Итерация с циклом цикла или while?

Я часто вижу код вроде:

Iterator i = list.iterator();
while(i.hasNext()) {
    ...
}

но я пишу, что (когда Java 1.5 недоступен или для каждого не может использоваться):

for(Iterator i = list.iterator(); i.hasNext(); ) {
    ...
}

потому что

  • Короче
  • Он сохраняет i в меньшей области
  • Это уменьшает вероятность путаницы. (Is i используется вне в то время как? Где объявлено i?)

Я думаю, что код должен быть как можно более понятным, так что мне нужно сделать сложный код, чтобы делать сложные вещи. Как вы думаете? Что лучше?

От: http://jamesjava.blogspot.com/2006/04/iterating.html

Ответы

Ответ 1

Я предпочитаю цикл for, потому что он также задает область итератора только для цикла for.

Ответ 2

Почему бы не использовать конструкцию for-each? (Я не использовал Java некоторое время, но это существует в С#, и я уверен, что Java 1.5 тоже имеет это):

List<String> names = new ArrayList<String>();
names.add("a");
names.add("b");
names.add("c");

for (String name : names)
    System.out.println(name.charAt(0));

Ответ 3

Существуют соответствующие применения для while, for и foreach конструкций:

  • while - Используйте это, если вы выполняете итерацию, и решающий фактор для цикла или нет основан только на условии. В этой конструкции цикла сохранение индекса является лишь вторичной проблемой; все должно основываться на условии

  • for - Используйте это, если вы зацикливаете, и ваша главная проблема - это индекс массива/коллекции/списка. Полезнее использовать for для, если вы, скорее всего, пройдете все элементы и в определенном порядке (например, перейдя через отсортированный список, например).

  • foreach - Используйте это, если вам просто нужно пройти свою коллекцию независимо от порядка.

Очевидно, что есть исключения из вышеизложенного, но что общее правило, которое я использую при принятии решения об использовании, которое. При этом я чаще использую foreach.

Ответ 4

Я думаю, что область является самой большой проблемой здесь, как вы указали.

В примере "while" итератор объявляется вне цикла, поэтому он будет продолжать существовать после завершения цикла. Это может вызвать проблемы, если этот же итератор снова используется в какой-то более поздний момент. E. g. вы можете забыть инициализировать его, прежде чем использовать его в другом цикле.

В примере "for" итератор объявляется внутри цикла, поэтому его область ограничена циклом. Если вы попытаетесь использовать его после цикла, вы получите ошибку компилятора.

Ответ 5

если вы только собираетесь использовать итератор один раз и выбросить его, предпочтительна вторая форма; иначе вы должны использовать первую форму

Ответ 6

IMHO, цикл для менее читабельен в этом сценарии, если вы посмотрите на этот код с точки зрения английского языка. Я работаю над кодом, в котором автор злоупотребляет циклом для, и это не очень хорошо. Сравните следующие:

for (; (currUserObjectIndex < _domainObjectReferences.Length) && (_domainObjectReferences[currUserObjectIndex].VisualIndex == index); ++currUserObjectIndex)
    ++currNumUserObjects;

vs

while (currUserObjectIndex < _domainObjectReferences.Length && _domainObjectReferences[currUserObjectIndex].VisualIndex == index)
{
    ++currNumUserObjects;
    ++currUserObjectIndex;
}

Ответ 7

Я бы согласился, что цикл "for" более ясен и более уместен при повторении.

Цикл "while" подходит для опроса или где количество циклов, удовлетворяющих условию выхода, будет изменяться в зависимости от активности внутри цикла.

Ответ 8

Не то, чтобы в этом случае это имело значение, но у компиляторов, виртуальных машин и процессора обычно есть специальные методы оптимизации, которые они используют под капотом, которые улучшат производительность петель (и в ближайшем будущем параллельны), в общем случае они не делайте это с циклом while (потому что его сложнее определить, как он на самом деле будет работать). Но в большинстве случаев четкость кода должна превзойти оптимизацию.

Ответ 9

Используя цикл for, вы можете работать с одной переменной, поскольку она устанавливает область действия переменной для текущей работы только для цикла. Однако это невозможно в цикле while. Например:
int i; for (i = 0; in1; я ++) что-то делать..

для (i = 0; я n2; я + = 2) что-то делать.

Итак, после 1-го цикла я = n1-1 в конце. Но при использовании второго цикла вы можете снова установить я на 0.   Однако

int я = 0;

while (i меньше предела) {сделайте что-то..; я ++; }

Следовательно, я в конце устанавливается в limit-1. Таким образом, вы не можете использовать один и тот же я в другом цикле while.

Ответ 10

Либо все нормально. Я сам использую for(), и я не знаю, есть ли проблемы с компиляцией. Я подозреваю, что они оба оптимизированы до почти той же самой вещи.

Ответ 11

Хотя оба варианта действительно прекрасны, я использую первый пример, потому что его легче читать.

В каждой строке происходит меньше операций с циклом while(), что делает код более легким для кого-то нового для кода, чтобы понять, что происходит.

Этот тип конструкции также позволяет мне группировать инициализации в общем месте (вверху метода), что также упрощает комментирование для меня и концептуализацию для кого-то, читающего его в первый раз.

Ответ 12

Я согласен, что цикл for должен использоваться по возможности, но иногда есть более сложная логика, которая управляет итератором в теле цикла. В этом случае вам нужно идти вместе.

Ответ 13

Я был для цикла for для ясности. Хотя я использую цикл while, когда сталкиваюсь с каким-то неопределенным условием.

Ответ 14

Оба хороши, но помните, что иногда доступ к Iterator напрямую полезен (например, если вы удаляете элементы, которые соответствуют определенному условию), вы получите исключение ConcurrentModificationException, если вы делаете collection.remove(o) внутри a for ( T o: collection).

Я предпочитаю писать синтаксис for (blah: blah) [foreach] почти все время, потому что мне кажется более понятным для меня. Понятие итераторов вообще не имеет параллелей вне программирования

Ответ 15

Академия обычно предпочитает цикл while, поскольку это приводит к менее сложным рассуждениям о программах. Я предпочитаю структуры for-or-loop-loop, поскольку они упрощают чтение кода.