Which is more efficient, a for-each loop, or an iterator?

后端 未结 7 1517
别那么骄傲
别那么骄傲 2020-11-22 16:00

Which is the most efficient way to traverse a collection?

List  a = new ArrayList();
for (Integer integer : a) {
  integer.toSt         


        
7条回答
  •  眼角桃花
    2020-11-22 16:18

    If you are just wandering over the collection to read all of the values, then there is no difference between using an iterator or the new for loop syntax, as the new syntax just uses the iterator underwater.

    If however, you mean by loop the old "c-style" loop:

    for(int i=0; i

    Then the new for loop, or iterator, can be a lot more efficient, depending on the underlying data structure. The reason for this is that for some data structures, get(i) is an O(n) operation, which makes the loop an O(n2) operation. A traditional linked list is an example of such a data structure. All iterators have as a fundamental requirement that next() should be an O(1) operation, making the loop O(n).

    To verify that the iterator is used underwater by the new for loop syntax, compare the generated bytecodes from the following two Java snippets. First the for loop:

    List  a = new ArrayList();
    for (Integer integer : a)
    {
      integer.toString();
    }
    // Byte code
     ALOAD 1
     INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
     ASTORE 3
     GOTO L2
    L3
     ALOAD 3
     INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
     CHECKCAST java/lang/Integer
     ASTORE 2 
     ALOAD 2
     INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
     POP
    L2
     ALOAD 3
     INVOKEINTERFACE java/util/Iterator.hasNext()Z
     IFNE L3
    

    And second, the iterator:

    List  a = new ArrayList();
    for (Iterator iterator = a.iterator(); iterator.hasNext();)
    {
      Integer integer = (Integer) iterator.next();
      integer.toString();
    }
    // Bytecode:
     ALOAD 1
     INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
     ASTORE 2
     GOTO L7
    L8
     ALOAD 2
     INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
     CHECKCAST java/lang/Integer
     ASTORE 3
     ALOAD 3
     INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
     POP
    L7
     ALOAD 2
     INVOKEINTERFACE java/util/Iterator.hasNext()Z
     IFNE L8
    

    As you can see, the generated byte code is effectively identical, so there is no performance penalty to using either form. Therefore, you should choose the form of loop that is most aesthetically appealing to you, for most people that will be the for-each loop, as that has less boilerplate code.

提交回复
热议问题