文章目录
1. 集合遍历
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);
arr.add(3);
arr.add(5);
arr.add(7);
arr.add(9);
arr.add(10);
for(int i=0;i<arr.size();i++) {
System.out.print(arr.get(i)+" ");
}
System.out.println();
for(int i:arr) {
System.out.print(i+" ");
//arr.remove(i);可编译通过,但是运行时报异常java.util.ConcurrentModificationException 并发修改异常
}
System.out.println();
Iterator<Integer> lt= arr.iterator();
while(lt.hasNext()) {
System.out.print(lt.next()+" ");
//从集合中删除上一次next()方法返回的元素
lt.remove();
}
}
1.1 普通for循环遍历
优点:效率最高,遍历快,可以根据计数器(下标)操作元素
缺点:不适用所有集合,适用范围小,不适用于Map、Set
1.2 foreach循环(增强for循环)遍历
可以看出,使用foreach循环遍历元素时无须获得数组长度,也无须根据索引来访问数据。foreach循环和普通for循环不同的是,它无须循环条件,无须循环迭代语句。
注:使用foreach循环遍历数组元素时,并不能改变数组元素的值,会报异常java.util.ConcurrentModificationException
(并发修改异常)
优点:代码简洁,不易出错。
缺点:只能做简单的遍历,不能在遍历过程中删除、替换数据。
1.3 Iterator迭代器遍历
Inerator接口只能用于遍历Collection集合中的元素,Iterator对象也被称为迭代器。Iterator接口里提供的方法:
boolean hasNext()
:如果被迭代的集合元素还没有遍历完,则返回trueObject next()
:返回集合里的下一个元素void remove()
:删除集合中上一次next()方法返回的元素void forEachRemaining(Consumer action)
:Java 8为Iterator新增的默认方法,此方法可使用Lambda表达式遍历集合元素
Iterator<Integer> lt= arr.iterator();
while(lt.hasNext()) {
int temp = lt.next();
System.out.print(temp+" ");
}
- Iterator依赖于Collection对象,Iterator对象提供了
hasNext()
和next()
两个方法来迭代访问Collection集合里的对象。 - 只有通过
Iterator的remove()
方法才能删除上一次next()方法返回的集合元素,使用list的remove()方法将会引发java.util.ConcurrentModificationException
(并发修改异常)
2. 集合删除
集合的删除只有两种方式:
2.1 使用普通for循环删除
此处省略代码。。。
2.2 Iterator遍历时调用Iterator的remove()方法,而不是list的remove()方法进行删除
Iterator<Integer> lt= arr.iterator();
while(lt.hasNext()) {
int temp = lt.next();
System.out.print(temp+" ");
//arr.remove(temp);报异常java.util.ConcurrentModificationException 并发修改异常
lt.remove();//从集合中删除上一次next()方法返回的元素,删除成功
}
- Iterator迭代器采用的是快速失败(fail-fast)机制,一旦在迭代过程中检测到该集合已被修改,程序会立刻报出
ConcurrentModificationException
(并发修改异常),而不是显示修改后的结果,这样可以避免共享资源而引发的线程非安全问题。 - 只有通过
Iterator的remove()
方法才能删除上一次next()方法返回的集合元素,使用list的remove()方法将会引发java.util.ConcurrentModificationException
(并发修改异常)
2.3 为什么不能用foreach遍历删除List中的元素呢?
foreach底层实现还是调用的Iterator迭代器,但是在进行remove操作时,使用的是list的remove方法,而非Iterator的remove方法,那么,在我们调用list的remove方法删除元素之后,迭代器并不知道我们删除了这个元素,所以遍历时报错。
具体原因看源码:Java中的 fail-fast
3. List去重
- 使用HashSet删除重复元素,HashSet中不允许重复元素,可利用这一点解决List中存在重复元素的问题,代码如下:
public static void removeDuplicate(List list) {
HashSet h = new HashSet(list);
list.clear();
list.addAll(h);
}
- 使用双层for循环遍历删除
public static void removeDuplicate2(List list) {
for ( int i = 0 ; i < list.size() - 1 ; i ++ ) {
for ( int j = list.size() - 1 ; j > i; j -- ) {
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
}