Различия Java For Loop - PullRequest
       8

Различия Java For Loop

2 голосов
/ 20 марта 2011

Являются ли эти утверждения полностью одинаковыми с точки зрения использования памяти и эффективности в Java?

Первый

Object[] array = new Object[100];
int i = 0;
for (; i < array.length; i++){
   Object o = array[i];
   //do something
}

Второй

Object[] array = new Object[100];
for (int i = 0; i < array.length; i++){
   Object o = array[i];
   //do something
}

Третий

Object[] array = new Object[100];
for (Object o : array){
   //do something
}

Ответы [ 4 ]

6 голосов
/ 20 марта 2011

С точки зрения использования памяти и эффективности, да.Тем не менее, есть различия.В первом случае i существует (имеет область действия) за пределами цикла;в то время как во втором это не так.В третьем случае нет (прямого) способа доступа к индексу или изменения содержимого массива в позиции текущего объекта.

1 голос
/ 20 марта 2011

Первый не является общей идиомой; Я бы так не написал.

Нет разницы в памяти или эффективности. Третий - синтаксический сахар, который был добавлен в более поздней JVM (я думаю, что это был JDK 6).

Ваш код будет узким местом в памяти и эффективности, а не в конструкциях цикла.

0 голосов
/ 20 марта 2011

Нет, это не совсем то же самое. И это легко проверить, и я даже не удивлюсь.

Просто декомпилируйте следующие две функции:

public static void test1(Object[] arr) {
    for (int i = 0; i < arr.length; i++) {
        System.out.println(arr[i]);
    }
}

public void test2(Object[] arr) {
    for(Object o : arr) {
        System.out.println(o);
    }
}

и посмотрите на вывод:

public static void test1(java.lang.Object[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   aload_0
   4:   arraylength
   5:   if_icmpge       23
   8:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   11:  aload_0
   12:  iload_1
   13:  aaload
   14:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
   17:  iinc    1, 1
   20:  goto    2
   23:  return

public void test2(java.lang.Object[]);
  Code:
   0:   aload_1
   1:   astore_2
   2:   aload_2
   3:   arraylength
   4:   istore_3
   5:   iconst_0
   6:   istore  4
   8:   iload   4
   10:  iload_3
   11:  if_icmpge       34
   14:  aload_2
   15:  iload   4
   17:  aaload
   18:  astore  5
   20:  getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   23:  aload   5
   25:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
   28:  iinc    4, 1
   31:  goto    8
   34:  return
}

Я просто включил println (), чтобы мы увидели, что с переменной что-то сделано, и чтобы javac не оптимизировал ее. Очевидно, что на более широкой картине разница не будет иметь значения, и их вряд ли можно измерить, но, тем не менее, это не тот же код;)

Хотя я не уверен, что именно происходит во 2-й функции, поэтому, если кто-то хочет потратить время и проанализировать код, продолжайте; -)

0 голосов
/ 20 марта 2011

Третья версия была представлена ​​в Java 5 и предназначена для упрощения вашей работы с генериками.Это улучшено, потому что вам не нужно определять, сколько элементов в массиве перед циклом.Также нет необходимости указывать, как увеличивать текущую позицию, обеспечивая более чистую реализацию без необходимости создания переменной счетчика или итератора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...