Итерировать с помощью цикла for или цикла while?

StackOverflow https://stackoverflow.com/questions/99164

  •  01-07-2019
  •  | 
  •  

Вопрос

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

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/itering.html

Это было полезно?

Решение

Я предпочитаю цикл 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 (; (currUserObjectIndex < _domainObjectReferences.Length) && (_domainObjectReferences[currUserObjectIndex].VisualIndex == index); ++currUserObjectIndex)
    ++currNumUserObjects;

против

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

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

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

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

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

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

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

интервал я = 0;

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top