我应该使用Iterator还是forloop进行迭代?

我不喜欢不得不调用hasNext()next()的想法,并且看到我如何需要一个循环来调用它们,我真的没有看到使用在列表中给我们的迭代器和地图。

是否只需要从列表中提取一个? 或者,如果您从列表中选择一个项目,并且必须在不可测量的时间内执行此操作? 我在Google或Stack上找不到这个,请帮帮我。

我不是专门讨论增强的for循环(for-each循环)。

我也理解foreach循环在性能方面表现优异,但这更像是“为什么存在”的问题

编辑:已经实现我只谈论集合而不是arraysaswel。 Foreach循环在这种情况下没有限制。

foreach相当于一个迭代器 – 它是同一个东西的语法糖。 所以你应该随时选择foreach不是迭代器,只是因为它很方便并且会产生更简洁的代码。

我在另一个答案中写到了这个: https//stackoverflow.com/questions/22110482/uses-and-syntax-for-for-each-loop-in-java/22110517#22110517

正如@RonnyShapiro所述,在某些情况下您需要使用迭代器,但在许多情况下, foreach应该足够了。 请注意, foreach 不是正常for循环。 当需要访问索引时,需要正常的for循环。 虽然您可以使用foreach手动创建单独的索引int-variable,但从变量范围的角度来看,它并不理想。

这里有一些更多信息: 哪个更有效,for-each循环还是迭代器?

访问集合时, foreach 明显快于循环数组访问的基本速度 。 但是,当访问数组时 – 至少使用原始数据包和包装数组 – 通过索引访问速度更快。 见下文。


访问intInteger数组时,索引比迭代器快23-40%。 下面是测试类的输出,它将100个元素的原始数组中的数字相加(A是迭代器,B是索引):

 [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) 

完整的测试类:

  import java.text.NumberFormat; import java.util.Locale; /** 

{@code java TimeIteratorVsIndexIntArray 1000000}

@see
https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java **/ public class TimeIteratorVsIndexIntArray { public static final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US); public static final void main(String[] tryCount_inParamIdx0) { int testCount; //Get try-count from command-line parameter try { testCount = Integer.parseInt(tryCount_inParamIdx0[0]); } catch(ArrayIndexOutOfBoundsException | NumberFormatException x) { throw new IllegalArgumentException("Missing or invalid command line parameter: The number of testCount for each test. " + x); } //Test proper...START int[] intArray = new int[] {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}; long lStart = System.nanoTime(); for(int i = 0; i < testCount; i++) { testIterator(intArray); } long lADuration = outputGetNanoDuration("A", lStart); lStart = System.nanoTime(); for(int i = 0; i < testCount; i++) { testFor(intArray); } long lBDuration = outputGetNanoDuration("B", lStart); outputGetABTestNanoDifference(lADuration, lBDuration, "A", "B"); } private static final void testIterator(int[] int_array) { int total = 0; for(int i = 0; i < int_array.length; i++) { total += int_array[i]; } } private static final void testFor(int[] int_array) { int total = 0; for(int i : int_array) { total += i; } } //Test proper...END //Timer testing utilities...START public static final long outputGetNanoDuration(String s_testName, long l_nanoStart) { long lDuration = System.nanoTime() - l_nanoStart; System.out.println("Test " + s_testName + ": " + nf.format(lDuration) + " nanoseconds"); return lDuration; } public static final long outputGetABTestNanoDifference(long l_aDuration, long l_bDuration, String s_aTestName, String s_bTestName) { long lDiff = -1; double dPct = -1.0; String sFaster = null; if(l_aDuration > l_bDuration) { lDiff = l_aDuration - l_bDuration; dPct = 100.00 - (l_bDuration * 100.0 / l_aDuration + 0.5); sFaster = "B"; } else { lDiff = l_bDuration - l_aDuration; dPct = 100.00 - (l_aDuration * 100.0 / l_bDuration + 0.5); sFaster = "A"; } System.out.println(sFaster + " faster by " + nf.format(lDiff) + " nanoseconds (" + dPct + "% faster)"); return lDiff; } //Timer testing utilities...END }

我还为Integer数组运行了这个,索引仍然是明显的赢家,但速度只有18%到25%。

但是,对于Integers List ,迭代器更快。 只需将上面代码中的int数组更改为

 List 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}); 

并对test-function( int[] to Listlength to 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) 

在一次测试中,它们几乎相同,但迭代器仍然获胜。

对于每个都添加在Java 5中,以便更容易地迭代集合。 但是,它不会替换迭代器,因为只有迭代器可以在迭代时修改集合(通过迭代器接口)。 尝试从for中的集合中添加\ remove对象将导致ConcurrentModificationException。

如果你只是阅读价值观,那么foreach可能会更好。

好吧,Java语言规范8( http://docs.oracle.com/javase/specs/jls/se8/jls8.pdf ),14.14.2:

增强的for语句相当于表单的基本for语句:

 for (I #i = Expression.iterator(); #i.hasNext(); ) { {VariableModifier} TargetType Identifier = (TargetType) #i.next(); Statement } 

所以,对于相同的编译器。 该标准的早期版本包含“foreach”语句的相同描述

部分原因与java随时间发展的历史有关。 自Java 1.2以来,迭代器是一种语言特性,作为处理对象集合的一种方式。 Java 1.5添加了可迭代接口和for-each循环。

除非你需要在循环期间使用迭代器做一些特定的事情,否则我总是使用for-each块(在实现中使用迭代器)

通常Iterator比使用objects.get(i)进行for循环更有效,但差异对你的代码没有实际影响。 Iterator的主要优点是,您可以通过在迭代器上调用remove方法在过渡期间从列表中删除对象。