Повторять цикл for или цикл while?

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

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

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

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

так как

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

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

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

15 ответов

Решение

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

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

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

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

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

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

Почему бы не использовать конструкцию for-each? (Я давно не использовал Java, но он существует в C#, и я уверен, что в 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));

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

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

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

ИМХО, цикл for менее читабелен в этом сценарии, если вы посмотрите на этот код с точки зрения английского языка. Я работаю над кодом, где автор ругает за цикл, и это не красиво. Сравните следующее:

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

против

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

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

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

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

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

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

ибо (i=0;i n2;i+=2) сделайте что-нибудь.

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

int i=0;

в то время как (я меньше, чем предел) {сделать что-то..; я ++; }

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

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

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

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

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

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

И то, и другое хорошо, но помните, что иногда полезен прямой доступ к Итератору (например, если вы удаляете элементы, соответствующие определенному условию - вы получите исключение ConcurrentModificationException, если вы выполните collection.remove(o) внутри for(T o: коллекция) петля).

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

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

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

Другие вопросы по тегам