为何移除ArrayList中奇数或大于100的元素的代码无法正常工作?
问题分析与修复
你的代码无法得到正确结果,主要是以下几个逻辑错误导致的:
1. 正向遍历+元素移除引发索引错位
用for(int i = 0; i < list1.size(); i++)正向遍历并移除元素时,一旦删除i位置的元素,列表中i之后的所有元素都会向前移动一位。但循环的i会继续递增,这就跳过了原本在i+1位置(现在移到i位置)的元素,导致该元素无法被检查是否需要移除。
比如你的初始列表是[1,899,5,647,4,804,103],当i=0时移除1,列表变成[899,5,647,4,804,103],随后i递增到1,此时检查的是5,直接跳过了现在在0位置的899,导致它没被移除。
2. while循环逻辑冗余且存在隐患
你的while循环会持续检查当前i位置的元素,但元素被移除后i没有调整,结合for循环的递增逻辑会彻底混乱,甚至可能触发索引越界(比如列表最后一个元素被移除后,i可能等于列表长度,此时list1.get(i)会报错)。另外if(i != list1.size())这个判断完全多余,因为for循环的条件已经保证i < list1.size()。
3. 直接修改原列表(非必要但不符合常见预期)
函数直接修改传入的list1并返回,会导致原本的list也被修改——如果你的需求是保留原列表,这显然不符合预期。
修复方案
方案1:使用迭代器(最安全的传统写法)
迭代器专门适配遍历中修改集合的场景,不会出现索引错位问题:
public static ArrayList<Integer> removeEntries(ArrayList<Integer> list1) { // 创建原列表的副本,避免修改原数据 ArrayList<Integer> result = new ArrayList<>(list1); Iterator<Integer> iterator = result.iterator(); while (iterator.hasNext()) { Integer num = iterator.next(); if (num % 2 != 0 || num > 100) { iterator.remove(); } } return result; }
方案2:倒序遍历
从列表末尾向前遍历,移除元素不会影响前面未遍历的元素索引:
public static ArrayList<Integer> removeEntries(ArrayList<Integer> list1) { ArrayList<Integer> result = new ArrayList<>(list1); for (int i = result.size() - 1; i >= 0; i--) { Integer num = result.get(i); if (num % 2 != 0 || num > 100) { result.remove(i); } } return result; }
方案3:Java 8+ Stream API(简洁高效)
用Stream过滤符合要求的元素,代码更简洁,且天然不修改原列表:
import java.util.stream.Collectors; public static ArrayList<Integer> removeEntries(ArrayList<Integer> list1) { return list1.stream() .filter(num -> num % 2 == 0 && num <= 100) .collect(Collectors.toCollection(ArrayList::new)); }
测试你的初始列表,以上三种方案都会得到正确结果[4],同时原列表不会被修改。
内容的提问来源于stack exchange,提问作者FishyK
相关产品推荐
相关产品推荐

