概述
java中foreach
入门
今天闲来无事,师父让我看一下,迭代器在一个循环里面连续两次iterator.remove()的问题,因为今天看一个离职人员的代码,里面写了这个。
我们看一下测试代码:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for (Integer value:list){
logger.debug(value);
}
//输出
2020-08-07 09:58:12,323 DEBUG (com.huskyui.App:main) -1
2020-08-07 09:58:12,324 DEBUG (com.huskyui.App:main) -2
2020-08-07 09:58:12,325 DEBUG (com.huskyui.App:main) -3
2020-08-07 09:58:12,325 DEBUG (com.huskyui.App:main) -4
反编译文件
List<Integer> list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator var2 = list.iterator();
while(var2.hasNext()) {
Integer value = (Integer)var2.next();
logger.debug(value);
}
// 生成迭代器
iterator
迭代器里面的介绍是:_Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics._迭代器允许调用者在迭代期间使用定义良好的语义从基础集合中删除元素.
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator iterator = list.iterator();
logger.debug("Iterator 从前向后遍历:");
while (iterator.hasNext()){
Integer value = (Integer)iterator.next();
logger.debug(value);
}
// 增强版iterator listIterator
logger.debug("listIterator从前向后遍历");
ListIterator iterator1 = list.listIterator();
while (iterator1.hasNext()){
Integer value = (Integer)iterator1.next();
logger.debug(value);
}
logger.debug("listIterator从后向前遍历:");
while (iterator1.hasPrevious()){
logger.debug(iterator1.previous());
}
/**
2020-08-07 11:07:44,832 DEBUG (com.huskyui.App:main) -Iterator 从前向后遍历:
2020-08-07 11:07:44,834 DEBUG (com.huskyui.App:main) -1
2020-08-07 11:07:44,834 DEBUG (com.huskyui.App:main) -2
2020-08-07 11:07:44,834 DEBUG (com.huskyui.App:main) -3
2020-08-07 11:07:44,834 DEBUG (com.huskyui.App:main) -4
2020-08-07 11:07:44,835 DEBUG (com.huskyui.App:main) -listIterator从前向后遍历
2020-08-07 11:07:44,835 DEBUG (com.huskyui.App:main) -1
2020-08-07 11:07:44,835 DEBUG (com.huskyui.App:main) -2
2020-08-07 11:07:44,837 DEBUG (com.huskyui.App:main) -3
2020-08-07 11:07:44,838 DEBUG (com.huskyui.App:main) -4
2020-08-07 11:07:44,838 DEBUG (com.huskyui.App:main) -listIterator从后向前遍历:
2020-08-07 11:07:44,838 DEBUG (com.huskyui.App:main) -4
2020-08-07 11:07:44,838 DEBUG (com.huskyui.App:main) -3
2020-08-07 11:07:44,839 DEBUG (com.huskyui.App:main) -2
2020-08-07 11:07:44,839 DEBUG (com.huskyui.App:main) -1
*/
经典出错
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for (Integer value :list){
System.out.println(value);
if(value.equals(1)){
list.remove(value);
}
}
// 反编译
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Integer value = (Integer)iterator.next();
System.out.println(value);
if(value.equals(1)){
list.remove(value);
}
}
// 出错
// 1
// Exception in thread "main" java.util.ConcurrentModificationException
// at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
// at java.util.ArrayList$Itr.next(ArrayList.java:859)
// at com.huskyui.App.main(App.java:24)
// 我们来看iterator在ArrayList的实现
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
// cursor就是游标的大概意思,size是ArrayList的容量
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
// 报错是在这里
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
// 给lastRet负责,有点pre节点的味道了
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
// 指向前一个节点
cursor = lastRet;
// lastRet赋初始值,在后续执行next()方法是可以重新赋值
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
// 这个modCount是ArrAyList继承的AbstractList中的变量,记录这个arrayList的修改次数。譬如我们添加了4次,那么这个就是4
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
为什么我们不能在遍历时,删除,因为arrayList的remove时,并没有修改exceptedModCount,而iterator却可以。
关于foreach两种方式
foreach支持1.实现了Iterator接口的2.数组
第一种,Iterator反编译后,就是使用Iterator迭代器来实现的
第二种,数组形式的foreach
int[] array = new int[]{1,2,3,4,5};
for (int num:array){
System.out.println(num);
}
// 反编译后
int[] array = new int[]{1, 2, 3, 4, 5};
int[] var2 = array;
int var3 = array.length;
for(int var4 = 0; var4 < var3; ++var4) {
int num = var2[var4];
System.out.println(num);
}
参考
Java基础8:Iterator和foreach循环
最后
以上就是现代月饼为你收集整理的java中foreach和iteratorjava中foreach的全部内容,希望文章能够帮你解决java中foreach和iteratorjava中foreach所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复