参考:https://blog.csdn.net/black_bird_cn/article/details/81591698
一、三种遍历方式
1.增强for循环
for(String str : list) {//其内部实质上还是调用了迭代器遍历方式,这种循环方式还有其他限制,不建议使用。
System.out.println(str);
}
2.普通for循环
for( int i = 0 ; i < list.size() ; i++) {//内部不锁定,效率最高,但在多线程要考虑并发操作的问题。
System.out.println(list.get(i));
}
3.迭代器遍历
Iterator iter = list.iterator();
while(iter.hasNext()){ //执行过程中会执行数据锁定,性能稍差,若在循环过程中要去掉某个元素只能调用iter.remove()方法。
System.out.println(iter.next());
二、增强for循环和迭代器遍历遇到的问题
问题1:foreach增强for循环中修改List中element的值操作无效;
示例代码:
public static void main(String[] args) {
int size = 1000;
String s[] = new String[]{“qwqwe”, “frsgdf”, “asd”, “dfsfuytrd”, “qwds”};
List asList = Arrays.asList(s);
for (String t : asList) {
if (t.length() <= 4) {
System.out.println(t);
t = “1122”;
}
}
for (String tt : asList){
System.out.println("==== :"+tt);
}
}
//程序运行结果
asd
qwds
==== :qwqwe
==== :frsgdf
==== :asd
==== :dfsfuytrd
==== :qwds
问题缘由:
foreach遍历JDK5.0增加的增强for循环,foreach在遍历过程中是通过一个临时变量,记录遍历到的当前List中的element,所以在foreach中操作的对象是指向临时变量的,而不是List中的element实例对象的地址,结果自然就只是修改临时变量的值并没修改List中的element,所以才会出现:foreach增强for循环中修改List中element的值是无效的问题;
**解决办法:**改用loop without size实行;
问题2:Iterator迭代时,调用List集合对象remove(Object o)时,抛出Exception;
示例代码:
public static void main(String[] args) {
List asList = new ArrayList<>();
asList.add(“qwqwe”);
asList.add(“frsgdf”);
asList.add(“asd”);
asList.add(“dfsfuytrd”);
asList.add(“qwds”);
Iterator iterator = asList.iterator();
String next;
while (iterator.hasNext()) {
next = iterator.next();
if(next.length()<=4){
asList.remove(next);
}
}
}
//运行结果
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList
I
t
r
.
c
h
e
c
k
F
o
r
C
o
m
o
d
i
f
i
c
a
t
i
o
n
(
A
r
r
a
y
L
i
s
t
.
j
a
v
a
:
901
)
a
t
j
a
v
a
.
u
t
i
l
.
A
r
r
a
y
L
i
s
t
Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList
Itr.checkForComodification(ArrayList.java:901)atjava.util.ArrayListItr.next(ArrayList.java:851)
at Main.main(Main.java:31)
问题缘由:
这个问题是和Iterator的实现方式有关系的,以ArrayList为例,在ArrayList中.iterator()其实是通过工厂模式在内部new出来一个Iterator对象,而且这个Iterator对象的size是按照它被创建时List的.size()大小创建的,如果在iterator()中调用List的remove方法,这就会导致Iterator的size大于List的size,进而发生IndexOutOfBoundsException越界异常(List中改为抛出ConcurrentModificationException,可参考ArrayList.Itr.next()函数);
解决办法:
法1:如果list中只需要删除一个element的话可以的话,删除完成直接break;这样也可以节约时间和减小性能开销;
法2:调用Iterator的remove()方法进行删除【在源码中可以看到在Iterator的remove()中同时也调用了List的remove(),这保持了List的size和Iterator的size一致,避免出现越界异常;】