我应该使用迭代器还是循环迭代器?

我不喜欢不得不调用hasNext()next()的想法,并且看到我需要一个循环来调用这些循环,但我并没有真正看到使用List中给出的迭代器和地图。

只有当你需要从列表中拉出一个呢? 或者,如果您从列表中选取一个项目,并且必须这样做的时间不可测量? 我无法在Google或Stack上找到此信息,请帮助我。

我不是专门针对增强型for-loop(for-each循环)。

我也明白,foreach循环在性能上表现出色,但这更多的是“为什么它存在”的问题

编辑:意识到我只是谈论集合而不是阵列aswel。 在这种情况下, 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变量,但从变量作用域的角度来看,它并不理想。

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

访问集合时, foreach比基本for循环数组访问要快得多。 但是,在访问数组时,至少在使用基元和包装数组时,通过索引访问会更快。 见下文。


当访问索引比迭代更快23- 40% intInteger阵列。 下面是来自下面测试类的输出,它将100个元素的primitive-int数组中的数字相加(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;
/**
   <P>{@code java TimeIteratorVsIndexIntArray 1000000}</P>

   @see  <CODE><A HREF="https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java">https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java</A></CODE>
 **/
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<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>lengthsize()等进行必要的修改)

[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中添加,以便更轻松地对集合进行迭代。 但是,它不会将迭代器替换为迭代器,您可以在迭代器上迭代(通过迭代器接口)。 尝试从a中的集合中添加 remove对象将导致ConcurrentModificationException。

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


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

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

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

所以,编译器是一样的。 此标准的早期版本包含与'foreach'声明相同的描述

链接地址: http://www.djcxy.com/p/52987.html

上一篇: Should I use an Iterator or a forloop to iterate?

下一篇: Performance of traditional for loop vs Iterator/foreach in Java