Вопрос: Разница между циклом for-loop и while-loop с использованием итератора


Итератор, использующий while-loop:

List<DataType> list = new ArrayList<DataType>();  
Iterator<YourDataType> it = yourList.iterator();  
while (it.hasNext())   
   // Do something

Итератор, использующий for-loop:

   List<DataType> list = new ArrayList<DataType>();
   for ( Iterator<DataType> it = list.iterator(); list.hasNext(); ) 
      // Do something

Я читал, что for-loop минимизирует область действия Iterator в самом цикле. Что именно это значит? Должен ли я использовать встроенный цикл while?


6


источник


Ответы:


Разница в основном

Для цикла:

for (Iterator<DataType> it = list.iterator(); list.hasNext(); ) 

В этом случае вы объявляете объект Iterator локально, и он будет eligible for GC(garbage collection) after the for loop,

В цикле while ,

while (it.hasNext()) так как вы объявили объект Iterator вне цикла. Так что это объем может быть   the entire program или method it is in, Или если он ссылается где угодно, не будет иметь право на GC ,

Надеюсь это поможет.


6



Поскольку вы объявляете итератор внутри цикла for, вы не сможете использовать его за его пределами. Его объем будет ограничен блоком for-loop.

Используйте то, что имеет больше смысла в вашем случае. Вам нужен итератор после того, как вы повторили все элементы в своей коллекции? Используйте цикл while. Если вам это не нравится, используйте for-loop.

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


1



for-loop минимизирует масштаб Iterator до самого цикла. Что именно это значит?

Использовать Iterator на while цикл, вы должны объявить и инициализировать его до  использования в while петля. Итак, вы можете сделать это:

List<DataType> list = new ArrayList<DataType>();  
Iterator<YourDataType> it = yourList.iterator();  
while (it.hasNext()) {
}
it.hasNext(); //this compiles and will return false

в for петля, Iterator объявляется внутри сферы действия for , поэтому его можно использовать только внутри тела этого цикла.

List<DataType> list = new ArrayList<DataType>();
for ( Iterator<DataType> it = list.iterator(); list.hasNext(); ) {
}
it.hasNext(); //this won't work and is a compiler error since the variable it's outside its scope

Должен ли я использовать встроенный цикл while?

Это полностью зависит от ваших потребностей. Обычно, если вы собираетесь использовать все элементы итератора в одном цикле, лучше использовать for и он будет лучше использовать расширенный for цикл, который уже использует Iterator за кулисами:

for(DataType data : list) {
    //...
}

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


1



Как сказал JNL, при ограниченном объеме сбор мусора может собирать его непосредственно после цикла, а не до следующего },

Обычно это малоинтересно - итератор на самом деле не занимает много памяти, и область действия обычно заканчивается довольно быстро после использования итератора. Например, если вы поместите оба образца кода в метод, они будут обладать одинаковой областью. Другой способ ограничить область цикла while - добавить в него фигурные скобки, как таковые:

{
   List<DataType> list = new ArrayList<DataType>();  
   Iterator<YourDataType> it = yourList.iterator();  
   while (it.hasNext())   
      // Do something
}

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


TL; DR

Не имеет значения.


1



Существуют два важных различия в синтаксисе и обслуживании.

Синтаксис

Область действия переменной различна. в forcase, переменная доступна только внутри заголовка и тела, а в while он доступен после цикла. Как правило, лучше иметь более жесткие области, меньше переменных в полете означает меньше контекста, чтобы беспокоиться о кодировании.

Обслуживание

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

Кроме того:

for петли более читабельны и универсальны для регулярных итерационных моделей, где while петли должны быть зарезервированы для нерегулярных схем итераций


1