Для каждого вопроса цикла - PullRequest
3 голосов
/ 15 марта 2011

У меня проблемы с пониманием цикла for-each.Я знаком с типичной структурой для каждого, где есть встроенный счетчик и оператор присваивания для каждого элемента.Тем не менее, в приведенном ниже коде, что подразумевается под ключевым словом "new"?Он выполняется только один раз?

for(Integer item : new ArrayList<Integer>(myCollection)){
    myCollection.add(first.intValue() + item.intValue());
}

Это эквивалентно следующему циклу for?

for(int ctr = 0; ctr < myCollection.size(); ctr++){
    Integer temp = myCollection.get(ctr);
    myCollection.add(first.intValue() + item.intValue());
}

Ответы [ 5 ]

4 голосов
/ 15 марта 2011

Ключевое слово new подразумевает, что оно создаст новый ArrayList, как если бы он был где-либо еще в коде.

Код в основном такой же, как и следующий.Нет ничего особенного в использовании new в цикле for-each.

List<Integer> list = new ArrayList<Integer>(myCollection);
for(Integer item : list){
    myCollection.add(first.intValue() + item.intValue());
}

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

for(int i = 0, size = myCollection.size(); i < size; i++){
    myCollection.add(first.intValue() + myCollection.get(i).intValue());
}

, которое, я думаю, совпадает с

for(int i = 0, size = myCollection.size(); i < size; i++)
    myCollection.add(first + myCollection.get(i));
2 голосов
/ 15 марта 2011

Первый блок кода создает новый ArrayList из Integers, копирует содержимое myCollection в него, а затем выполняет итерацию по полученному ArrayList.

Копия необходима, поскольку оригинал myCollection изменяется внутри цикла.

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

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

Ваш цикл

for(Integer item : new ArrayList<Integer>(myCollection)){
    myCollection.add(first.intValue() + item.intValue());
}

компилируется в тот же код (имена переменных по модулю), что и

for (Iterator<Integer> iterator = new ArrayList<Integer>(myCollection).iterator();
     it.hasNext(); ) {
    Integer item = iterator.next();
    myCollection.add(first.intValue() + item.intValue());
}

Если размер myCollection не изменится (а myCollection равен List), то это будет то же самое (только менее эффективно для создания временного списка), что и

for(int ctr = 0; ctr < myCollection.size(); ctr++){
    Integer temp = myCollection.get(i);
    myCollection.add(first.intValue() + temp.intValue());
}

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

Таким образом, ваш ArrayList помогает поддерживать ваш цикл в хорошем состоянии.

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

Выполняется ли он только один раз?

Да.

Это эквивалентно следующему для цикла?

Нет.Ваш цикл, следующий за

  1. , содержит три ошибки (first,intValue(), индекс цикла равен ctr, но myCollection.get(i), вы выбираете temp и оставляете item неопределенным),
  2. перебирает myCollection, добавляя к нему, постоянно проверяя растущий размер, и поэтому
  3. не завершается (size() растет), за исключением того, что
  4. будетв конечном итоге бросить OutOfMemoryError.

Это, однако, эквивалентно этому

for (int i = 0, n = myCollections.size(); i < n; i++) {
    Integer item = myCollection.get(i);
    myCollection.add(first.intValue() + item.intValue());
}
0 голосов
/ 15 марта 2011

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

Эквивалентный код с использованием for(;;) будет следующим:

List<Integer> auxList = new ArrayList<Integer>(myCollection);
for(int ctr = 0; ctr < auxList.size(); ctr++){
    myCollection.add(first.intValue() + auxList.get(ctr));
}

В качестве альтернативы вы можете просто пересчитать размер, чтобы избежать этой капчи:

int size = myCollection.size();
for(int ctr = 0; ctr < size; ctr++){
    myCollection.add(first.intValue() + myCollection.get(ctr));
}

Кроме этого, единственное отличие состоит в том, что подход foreach использует итераторы вместо доступа к элементам по индексам.

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

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