提问:Java的“ for each”循环如何工作?

考虑:

List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList

for (String item : someList) {
System.out.println(item);
}
复制代码


如果for不对每种语法使用,等效循环将是什么样?

高分回答:

很多的知识点,真的需要写出来才会掌握!!! \color{purple}很多的知识点,真的需要写出来才会掌握!!!{~}很多的知识点,真的需要写出来才会掌握!!! 

在Java 5中添加的foreach循环(也称为“增强循环”)等效于在同一件事上使用--it的语法糖。因此,在逐个读取每个元素时,应始终在迭代器上选择java.util.Iteratorforeach,因为它更加方便和简洁。前言

for(int i : intList) {
System.out.println("An element in the list: " + i);
}
复制代码


迭代器

Iterator<Integer> intItr = intList.iterator();
while(intItr.hasNext()) {
System.out.println("An element in the list: " + intItr.next());
}
复制代码


在某些情况下,您必须Iterator直接使用。例如,尝试在使用foreachcan(会吗?)的同时删除元素会导致ConcurrentModificationException。foreach与for:基本差异

for和之间的唯一实际区别foreach是,对于可索引对象,您无权访问索引。for需要基本循环的示例:

for(int i = 0; i < array.length; i++) {
if(i < 5) {
// Do something special
} else {
// Do other stuff
}
}
复制代码


尽管您可以使用手动创建一个独立的int变量索引foreach,

int idx = -1;
for(int i : intArray) {
idx++;
...
}
复制代码


不建议这样做,因为可变范围不是理想的选择,并且基本for循环只是该用例的标准格式和预期格式。

当访问的集合,一个foreach是显著速度比基本for循环的数组访问。但是,当访问数组时(至少使用原始数组和包装器数组),通过索引进行访问的速度大大加快。计时原始整数数组的迭代器和索引访问之间的区别

当访问或数组时,索引比迭代器快23 %到40%。这是本文结尾处的测试类的输出,该输出求和一个100元素的primary-int数组中的数字(A是迭代器,B是索引):intInteger

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 358,597,622 nanoseconds
Test B: 269,167,681 nanoseconds
B faster by 89,429,941 nanoseconds (24.438799231635727% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 377,461,823 nanoseconds
Test B: 278,694,271 nanoseconds
B faster by 98,767,552 nanoseconds (25.666236154695838% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 288,953,495 nanoseconds
Test B: 207,050,523 nanoseconds
B faster by 81,902,972 nanoseconds (27.844689860906513% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,373,765 nanoseconds
Test B: 283,813,875 nanoseconds
B faster by 91,559,890 nanoseconds (23.891659337194227% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,790,818 nanoseconds
Test B: 220,770,915 nanoseconds
B faster by 155,019,903 nanoseconds (40.75164734599769% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 326,373,762 nanoseconds
Test B: 202,555,566 nanoseconds
B faster by 123,818,196 nanoseconds (37.437545972215744% faster)

我也为Integer数组运行了此操作,索引仍然是明显的赢家,但只快了18%到25%。
对于集合,迭代器比索引快

对于List的Integers,但是,迭代器是明显的赢家。只需将test-class中的int-array更改为:

List<Integer> intList = Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100});

并对测试功能进行必要的更改(int[]至List<Integer>,length至size(),等等):

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,429,929,976 nanoseconds
Test B: 5,262,782,488 nanoseconds
A faster by 1,832,852,512 nanoseconds (34.326681820485675% faster)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,907,391,427 nanoseconds
Test B: 3,957,718,459 nanoseconds
A faster by 1,050,327,032 nanoseconds (26.038700083921256% faster)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,566,004,688 nanoseconds
Test B: 4,221,746,521 nanoseconds
A faster by 1,655,741,833 nanoseconds (38.71935684115413% faster)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,770,945,276 nanoseconds
Test B: 3,829,077,158 nanoseconds
A faster by 1,058,131,882 nanoseconds (27.134122749113843% faster)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,467,474,055 nanoseconds
Test B: 5,183,149,104 nanoseconds
A faster by 1,715,675,049 nanoseconds (32.60101667104192% faster)

[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,439,983,933 nanoseconds
Test B: 3,509,530,312 nanoseconds
A faster by 69,546,379 nanoseconds (1.4816434912159906% faster)

[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,451,101,466 nanoseconds
Test B: 5,057,979,210 nanoseconds
A faster by 1,606,877,744 nanoseconds (31.269164666060377% faster)
复制代码


在一次测试中,它们几乎是等效的,但有了集合,迭代器就赢了。

高分回答:

for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
String item = i.next();
System.out.println(item);
}
复制代码


请注意,如果您需要i.remove();在循环中使用或以某种方式访问​​实际的迭代器,则不能使用该for ( : )习惯用语,因为实际的迭代器只是推断出来的。

正如Denis Bueno指出的那样,此代码适用于实现该Iterable接口的任何对象。

同样,如果for (:)习惯用法的右侧是一个array而不是一个Iterable对象,则内部代码将使用一个int索引计数器并进行检查array.length。请参阅Java语言规范。

文章翻译自 ​​kgs4h5t57thfb6iyuz6dqtun5y-ac4c6men2g7xr2a-stackoverflow-com.translate.goog/questions/8…​

作者建议:用迭代器就对了,索引和for对数组来说,出现remove方式,会抛出异常,建议使用java 8 流处理 - 过滤、比配、比较、转换等

欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!! \color{red}欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!!{~}欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!! 

有最新、优雅的实现方式,我也会在文末写出我对本问答的见解 \color{red}有最新、优雅的实现方式,我也会在文末写出我对本问答的见解{~}有最新、优雅的实现方式,我也会在文末写出我对本问答的见解 

真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话

求点赞???? 求关注❤️ 求分享???? 对8块腹肌的我来说真的 非常有用!!!

如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️