如何遍历Java列表并隔一个删元素且不复制原列表?代码问题求解
问题分析与修复方案
嘿,我来帮你排查下为什么你的代码会把列表删空!
问题根源
你当前的代码里,用list.indexOf(e)来判断元素的索引,但这个方法有两个致命问题:
- 索引判断完全失效:当你删除列表中的元素后,后续元素的实际位置会前移,但
indexOf只会返回元素第一次出现的位置,完全没法反映当前迭代元素的真实索引。 - 重复元素会彻底混乱:如果列表里有重复元素,
indexOf会直接返回第一个匹配项的索引,根本不是当前元素的位置。
举个具体的执行流程:
- 初始列表:
[1,2,3,4] - 第一次迭代取到
1,indexOf(1)是0(偶数),删除后列表变成[2,3,4] - 第二次迭代取到
2,indexOf(2)是0(还是偶数),删除后列表变成[3,4] - 第三次迭代取到
3,indexOf(3)是0,删除后列表变成[4] - 第四次迭代取到
4,indexOf(4)是0,删除后列表为空
这就是为什么最后得到空列表的原因!
正确的实现方式
我们需要准确跟踪当前迭代元素的真实位置,而不是依赖indexOf。这里给你几种靠谱的实现:
方法1:迭代器+计数器(通用所有List类型)
这是最安全的方式,不管是ArrayList还是LinkedList都能用:
public static void supprimeElement(List<Integer> list) { Iterator<Integer> i = list.iterator(); int currentPosition = 0; while(i.hasNext()) { i.next(); // 先移动到下一个元素 // 删除偶数位置(0、2、4...)的元素 if (currentPosition % 2 == 0) { i.remove(); } currentPosition++; } }
用currentPosition来记录当前元素的真实索引,每迭代一个元素就加1,完全不受列表结构变化的影响。
方法2:倒序for循环(适合随机访问列表)
如果你的列表是ArrayList这类支持快速随机访问的类型,倒序遍历删除更高效:
public static void supprimeElement(List<Integer> list) { // 从最后一个偶数索引开始倒序删除,避免索引偏移 for (int i = list.size() - 1; i >= 0; i -= 2) { list.remove(i); } }
倒序遍历的好处是,删除后面的元素不会影响前面元素的索引,不会出现漏删或误删的情况。
方法3:ListIterator获取索引(更灵活)
如果需要更灵活的操作,可以用ListIterator的previousIndex()方法直接获取当前元素的索引:
public static void supprimeElement(List<Integer> list) { ListIterator<Integer> iterator = list.listIterator(); while (iterator.hasNext()) { iterator.next(); int currentIndex = iterator.previousIndex(); if (currentIndex % 2 == 0) { iterator.remove(); } } }
previousIndex()会返回上一次调用next()时元素的索引,能准确反映当前元素的真实位置。
测试效果
用你的测试代码跑一遍,初始列表[1,2,3,4],执行后会得到[2,4],完美符合“每隔一个删除一个”的需求!
内容的提问来源于stack exchange,提问作者rady
相关产品推荐
相关产品推荐

