我应该使用迭代器还是forloop来迭代? [英] Should I use an Iterator or a forloop to iterate?

查看:130
本文介绍了我应该使用迭代器还是forloop来迭代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不喜欢调用 hasNext() next()的想法,看到我需要一个循环才能调用这些,但是在使用列表和地图中给我们的迭代器时,我并没有太多意见。



只有在你需要从列表中拉一个?或者,如果您从列表中获取一个项目,并且不得不在未测量的时间内执行此操作?我不能在Google或Stack上找到这个,请帮助我。



我不是特别提到一个增强型for循环(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 不是 循环的正常。当需要访问索引时,需要循环的正常。虽然您可以手动创建一个单独的索引int-variable与 foreach 它不是理想的,从一个可变范围的观点。



以下是一些更多信息:一个href =https://stackoverflow.com/questions/2113216/which-is-more-efficient-a-for-each-loop-or-an-iterator>哪个更有效率,一个for-each循环,或迭代器?



访问集合时, foreach 比基本的 循环的数组访问。然而,当访问数组时,至少使用原始和包装数组 - 通过索引进行访问的速度更快。






索引是23- 40 比访问 int 整数数组时的迭代器。以下是下列测试类的输出,它将100个元素的primitive-int数组中的数字(A为迭代器,B为索引)相加:

  [C:\java_code\] java TimeIteratorVsIndexIntArray 1000000 
测试A:358,597,622纳秒
测试B:269,167,681纳秒
B更快89,429,941纳秒(24.438799231635727%更快)

[C:\java_code\] java TimeIteratorVsIndexIntArray 1000000
测试A:377,461,823纳秒
测试B:278,694,271纳秒
B更快98,767,552纳秒(25.666236154695838 %更快)

[C:\java_code\] java TimeIteratorVsIndexIntArray 1000000
测试A:288,953,495纳秒
测试B:207,050,523纳秒
B更快81,902,972纳秒(27.844689860906513%)

[C:\java_code\] java TimeIteratorVsIndexIntArray 1000000
测试A:375,373,765纳秒
测试B:283,813,875纳秒
B更快91,559,890纳秒onc(23.891659337194227%更快)

[C:\java_code\] java TimeIteratorVsIndexIntArray 1000000
测试A:375,790,818纳秒
测试B:220,770,915纳秒
B更快$ 155.00
[C:\java_code\] java TimeIteratorVsIndexIntArray 1000000
测试A:326,373,762纳秒
测试B:202,555,566纳秒
B快达123,818,196纳秒(37.437545972215744%更快)

完整的测试类:

  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;
//从命令行参数
尝试{
testCount = Integer.parseInt(tryCount_inParamIdx0 [0]))获取try-count;
} catch(ArrayIndexOutOfBoundsException | NumberFormatException x){
throw new IllegalArgumentException(缺少或无效的命令行参数:每个测试的testCount数+ x);
}

//测试正确... 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(); (int i = 0; i< testCount; i ++){
testIterator(intArray);

}
long lADuration = outputGetNanoDuration(A,lStart);

lStart = System.nanoTime(); (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; (int i = 0; i< int_array.length; i ++){
total + = int_array [i];

}
}
private static final void testFor(int [] int_array){
int total = 0; (int i:int_array)
{
total + = i;
}
}
//测试正确... END

//定时器测试实用程序... 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 +由+ nf.format(lDiff)+纳秒(+ dPct +%更快));
return lDiff;
}
//定时器测试实用程序... END
}

我还运行了一个整数数组,索引仍然是明显的赢家,但只有18%到25%之间。



对于列表 整数,迭代器更快。只需将上述代码中的int数组更改为

 列表<整数> 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,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 [] to List< Integer> length to size() / code>等)

  [C:\java_code\] java TimeIteratorVsIndexIntegerList 1000000 
测试A:3,429,929,976纳秒
测试B:5,262,782,488纳秒
A更快1,832,852,512纳秒(34.326681820485675%更快)

[C:\java_code\] java TimeIteratorVsIndexIntegerList 1000000
测试A:2,907,391,427纳秒
测试B:3,957,718,459纳秒
更快1,050,327,032纳秒(26.038700083921256%更快)

[C:\java_code\] java TimeIteratorVsIndexIntegerList 1000000
测试A:2,566,004,688纳秒
测试B:4,221,746,521纳秒
更快1,655,741,833纳秒(38.71935684115413%更快)

[C:\java_code\] java TimeIteratorVsIndexIntegerList 1000000
测试A:2,770,945,2 76纳秒
测试B:3,829,077,158纳秒
更快1,058,131,882纳秒(27.134122749113843%更快)

[C:\java_code\] java TimeIteratorVsIndexIntegerList 1000000
测试A:3,467,474,055纳秒
测试B:5,183,149,104纳秒
更快1,715,675,049纳秒(32.60101667104192%更快)

[C:\java_code\] java TimeIteratorVsIndexIntList 1000000
测试A:3,439,983,933纳秒
测试B:3,509,530,312纳秒
更快69,546,379纳秒(1.4816434912159906%更快)

[C:\java_code\] java TimeIteratorVsIndexIntList 1000000
测试A:3,451,101,466纳秒
测试B:5,057,979,210纳秒
A更快1,606,877,744纳秒(31.269164666060377%更快)

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


I don't like the idea of having to call hasNext() and next(), and seeing how I would need a loop to call those anyways, I don't really see much point in using the iterators given to us in Lists and Maps.

Is it only if you need to pull one this from the list? Or, if you're taking one item from the list, and having to do that for an unmeasured amount of time? I couldn't find this on Google or Stack, please help me out.

I'm not talking about an enhanced for-loop specifically (for-each loop).

I also understand that foreach loops excel in performance, but this is more of a 'why does it exist' question

EDIT: Realized I was talking about collections alone and not arrays aswel. Foreach loops don't have limitations in this situation.

解决方案

A foreach is equivalent to an iterator--it's syntactic sugar for the same thing. So you should always choose foreach over iterator whenever you can, simply because it's convenient and results in more concise code.

I've written about this in another answer: https://stackoverflow.com/questions/22110482/uses-and-syntax-for-for-each-loop-in-java/22110517#22110517

As stated by @RonnyShapiro, there are situations where you need to use an iterator, but in many cases a foreach should suffice. Note that a foreach is not a normal for loop. The normal for loop is needed when access to the index is required. Although you could manually create a separate index int-variable with foreach it is not ideal, from a variable-scope point of view.

Here's some more information: Which is more efficient, a for-each loop, or an iterator?

When accessing collections, a foreach is significantly faster than the basic for loop's array access. When accessing arrays, however--at least with primitive and wrapper-arrays--access via indexes is way faster. See below.


Indexes are 23-40 percent faster than iterators when accessing int or Integer arrays. Here is the output from the below testing class, which sums the numbers in a 100-element primitive-int array (A is iterator, B is index):

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

The full testing class:

   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
}

I also ran this for an Integer array, and indexes are still the clear winner, but only between 18 and 25 percent faster.

For a List of Integers, however, iterators are faster. Just change the int-array in the above code to

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

and make the necssary changes to the test-function (int[] to List<Integer>, length to size(), etc)

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

In one test they're almost equivalent, but still, iterator wins.

这篇关于我应该使用迭代器还是forloop来迭代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆