Есть ли способ в цикле Java для каждого
for(String s : stringArray) {
doSomethingWith(s);
}
узнать, как часто цикл уже обрабатывается?
Помимо использования старого и известного for(int i=0; i < boundary; i++)
цикла - это конструкция
int i = 0;
for(String s : stringArray) {
doSomethingWith(s);
i++;
}
единственный способ иметь такой счетчик в цикле for-each?
Type var = null; for (var : set) dosomething; if (var != null) then ...
Ответы:
Нет, но вы можете предоставить свой счетчик.
Причина этого заключается в том, что цикл for-each внутри не имеет счетчика; он основан на интерфейсе Iterable , то есть он использует
Iterator
цикл для «коллекции», которая может вообще не быть коллекцией, а может фактически быть чем-то совсем не основанным на индексах (таких как связанный список).источник
for(int idx=0, String s; s : stringArray; ++idx) doSomethingWith(s, idx);
each_with_index
метод петли дляEnumerable
в Ruby. См. Apidock.com/ruby/Enumerable/each_with_indexfor
цикла», что-то вродеfor (int i = 0; String s: stringArray; ++i)
Есть другой способ.
Учитывая, что вы пишете свой собственный
Index
класс и статический метод, который возвращаетIterable
более экземпляров этого класса, вы можетеГде реализация
With.index
что-то вродеисточник
Самое простое решение - запустить собственный счетчик так:
Причина этого заключается в том, что нет реальной гарантии того, что элементы в коллекции (которые этот вариант
for
повторяет) даже имеют индекс или даже имеют определенный порядок (некоторые коллекции могут изменить порядок при добавлении или удалении элементов).Смотрите, например, следующий код:
Когда вы запускаете это, вы можете увидеть что-то вроде:
это указывает на то, что порядок не считается характерной особенностью набора.
Есть и другие способы сделать это без ручного счетчика, но это немалый труд для сомнительной выгоды.
источник
Использование лямбд и функциональных интерфейсов в Java 8 делает возможным создание новых абстракций цикла. Я могу перебрать коллекцию с индексом и размером коллекции:
Какие выводы:
Который я реализовал как:
Возможности безграничны. Например, я создаю абстракцию, которая использует специальную функцию только для первого элемента:
Который печатает список через запятую правильно:
Который я реализовал как:
Библиотеки начнут появляться, чтобы делать подобные вещи, или вы можете свернуть свои собственные.
источник
Java 8 представила метод
Iterable#forEach()
/Map#forEach()
, который более эффективен для многих реализацийCollection
/Map
по сравнению с «классическим» циклом for-each. Однако и в этом случае индекс не предоставляется. Хитрость здесь в том, чтобы использоватьAtomicInteger
вне лямбда-выражения. Примечание: переменные, используемые в лямбда-выражении, должны быть окончательными, поэтому мы не можем использовать обычныеint
.источник
Боюсь, это невозможно
foreach
. Но я могу предложить вам простой цикл в старом стиле :Обратите внимание, что интерфейс List предоставляет вам доступ к
it.nextIndex()
.(редактировать)
К вашему измененному примеру:
источник
Одним из рассматриваемых изменений
Sun
являетсяJava7
предоставление доступа к внутреннемуIterator
в циклах foreach. синтаксис будет примерно таким (если это будет принято):Это синтаксический сахар, но, очевидно, было сделано много запросов на эту функцию. Но до тех пор, пока он не будет одобрен, вам придется самостоятельно считать итерации или использовать регулярный цикл for с символом
Iterator
.источник
Идиоматическое решение:
источник
Хотя для достижения того же самого было упомянуто много других способов, я поделюсь своим путем для некоторых неудовлетворенных пользователей. Я использую функцию Java 8 IntStream.
1. Массивы
2. Список
источник
Если вам нужен счетчик в цикле for-each, вы должны считать себя. Там нет встроенного счетчика, насколько я знаю.
источник
Есть вариант ответа pax ... ;-)
источник
i=0; i++;
подходом?В ситуациях, когда мне нужен только индекс, например, в предложении catch, я иногда буду использовать indexOf.
источник
Лучшее и оптимизированное решение - сделать следующее:
Где Тип может быть любым типом данных, а тип - это переменная, к которой вы применяете цикл.
источник
Я немного удивлен, что никто не предложил следующее (я признаю, что это ленивый подход ...); Если stringArray является каким-либо списком List, вы можете использовать что-то вроде stringArray.indexOf (S), чтобы вернуть значение для текущего счетчика.
Примечание: это предполагает, что элементы списка уникальны или что не имеет значения, не являются ли они неуникальными (потому что в этом случае будет возвращен индекс первой найденной копии).
Есть ситуации, в которых этого было бы достаточно ...
источник
Вот пример того, как я это сделал. Это получает индекс для каждого цикла. Надеюсь это поможет.
источник