foreach 是 Java 中的一种语法糖,几乎每一种语言都有一些这样的语法糖来方便程序员进行开发,编译期间以特定的字节码或特定的方式来对这些语法进行处理。能够提高性能,并减少代码出错的几率。在 Java 中还有比如 泛型、自动拆箱、自动装箱、内部类、枚举等等。
foreach 是用来对数组或者集合进行遍历的语法。具体语法如下:
1
2
3
|
for
(元素类型 ele : 数组名/Iterable 实例){
}
|
下面我们用 foreach 来对数组和一个集合进行遍历:
1
2
3
4
5
6
7
8
9
10
11
12
|
int
[] array = {
1
,
2
,
3
};
for
(
int
i : array){
System.out.println(i);
}
List list =
new
ArrayList();
list.add(
1
);
list.add(
2
);
list.add(
3
);
for
(Object obj : list){
System.out.println(obj);
}
|
然后我们可以通过反编译工具,查看 class 文件内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
int
array[] = {
1
,
2
,
3
};
int
[] array$ = array;
for
(
int
len$ = array$.length, i$ =
0
; i$<len$; ++i$ )
{
int
i = array$[i$];
{
System.out.println(i);
}
}
List list =
new
ArrayList();
list.add(
1
);
list.add(
2
);
list.add(
3
);
for
(java.util.Iterator i$ = list.iterator(); i$.hasNext();)
{
String s = (String) i$.next();
{
System.out.println(s);
}
}
|
很明显:
1、对于数组,foreach 循环实际上还是用的普通的 for 循环
2、对于集合,foreach 循环实际上是用的 iterator 迭代器迭代
注意:如果我们想一边迭代,一边删除集合中的元素,如下:
1
2
3
4
5
6
7
|
List list =
new
ArrayList();
list.add(
1
);<br> list.add(
2
);
list.add(
3
);
for
(Object obj : list){
System.out.println(obj);
list.remove(obj);
//一边迭代一边删除
}
|
这样写会报如下错误:这是一个并发修改异常报错
原因:迭代器内部的每次遍历都会记录List内部的modcount当做预期值,然后在每次循环中用预期值与List的成员变量modCount作比较,但是普通list.remove调用的是List的remove,这时modcount++,但是iterator内记录的预期值=并没有变化,所以会报错,但是如果在Iterator中调用remove,这时会同步List的modCount到Iterator中,故不再报错
解决办法:使用 iterator 迭代器中的remove()方法
1
2
3
4
5
6
|
Iterator it = list.iterator();
while
(it.hasNext()){
Object obj = it.next();
System.out.println(obj);
if
(obj.equals(
1
)){
it.remove();
//这里是用 迭代器的 remove() 方法<br><br> //list.remove(obj); <br> //如果你用 集合 方法,那么还是会报错<br> } <br> }
|