面试题答案
一键面试- 问题:
- 当使用普通的
for
循环遍历ArrayList
等Collection
接口实现类并删除元素时,会导致索引混乱。因为删除元素后,后面元素的索引会向前移动,如果继续按照原索引遍历,会跳过一些元素。 - 使用增强
for
循环(foreach
)遍历并删除元素,会抛出ConcurrentModificationException
。这是因为增强for
循环依赖迭代器(Iterator
),在遍历过程中集合结构发生变化(删除元素),而迭代器没有感知到这种变化,违反了迭代器的一致性原则。
- 当使用普通的
- 正确删除方法:
- 使用迭代器的
remove
方法:
原理:迭代器的import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class CollectionRemoveExample { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { Integer num = iterator.next(); if (num % 2 == 0) { iterator.remove(); } } System.out.println(list); } }
remove
方法会正确更新集合的结构,同时也更新迭代器内部的状态,保证迭代过程的一致性。当调用iterator.remove()
时,它知道当前操作是在迭代过程中的删除,能够正确调整内部状态以适应集合的变化。 - 使用Java 8的
removeIf
方法:
原理:import java.util.ArrayList; import java.util.List; public class CollectionRemoveExample2 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.removeIf(num -> num % 2 == 0); System.out.println(list); } }
removeIf
方法接受一个Predicate
(断言),它会遍历集合元素,对于满足断言条件的元素进行删除。这种方式内部实现也是基于迭代器,并且能够正确处理删除操作,保证集合结构的一致性。它避免了手动管理迭代器的过程,代码更加简洁。
- 使用迭代器的