Java: альтернатива iterator.hasNext() при использовании for-each для циклического перемещения по коллекции
Я пытаюсь заменить петлю на основе итератора над списком Java с помощью оператора for-each
, но код использует в некоторой точке iterator.hasNext()
, чтобы проверить, достиг ли он последнего элемента в списке.
Есть ли что-то подобное для альтернативы for-each
?
for (Object current : objectList) {
if (last-element)
do-something-special
}
Ответы
Ответ 1
для каждого - это просто синтаксический сахар для версии итератора, и если вы проверяете скомпилированный байт-код, то вы заметите, что компилятор действительно изменил его на версию итератора.
С каждой формой вы не можете проверить, будет ли у вас больше элементов или нет.
Просто оставайтесь с явным использованием итератора, если вам нужна эта функция.
Ответ 2
В дополнение к Luno ответ:
Iterator<MyClass> it = myCollection.iterator();
while(it.hasNext()) {
MyClass myClass = it.next():
// do something with myClass
}
переводит на:
for (MyClass myClass:myCollection) {
// do something with myClass
}
Ответ 3
Как говорили другие - это невозможно.
Просто помните, что конструкция foreach не является be-all и end-all. Было введено для того, чтобы сделать очень общую задачу выполнения одних и тех же операций над каждым элементом коллекции, более простой для обозначения.
В вашем случае вы не хотите делать то же самое для каждого элемента, и, таким образом, цикл foreach не является правильным инструментом для задания. Попытка "взломать" его в этом глупо, просто используйте явный итератор в классическом для цикла.
Ответ 4
Цикл foreach
(или расширенный цикл for
) не имеет средств для отслеживания того, какой элемент выполняется в данный момент. Невозможно определить, какой индекс Collection
обрабатывается, или есть ли больше элементов для обработки в Iterable
.
Тем не менее, одним из способов решения проблемы является сохранение ссылки на объект, который в данный момент повторяется в цикле foreach
.
Сохраняя ссылку на то, на что она обрабатывается на текущей итерации, можно было бы сохранить ссылку после завершения цикла foreach
, а оставшееся в переменной будет последним элементом.
Это обходное решение будет работать только если и только если последний элемент является единственным элементом, который необходим.
Например:
String lastString = null;
for (String s : new String[] {"a", "b", "c"}) {
// Do something.
// Keep the reference to the current object being iterated on.
lastString = s;
}
System.out.println(lastString);
Вывод:
c
Ответ 5
К сожалению, для каждой идиомы не разрешается проверять, является ли элемент первым или последним в списке. Это известное ограничение для каждого цикла.
Я предлагаю вам просто продолжать использовать итератор.
Если вы также можете проверить первый элемент вместо последнего, например, если вы выполняете конкатенацию строк, вы можете изменить на что-то вроде:
boolean first = true;
for (Element e : list) {
if (!first) {
//do optional operation
}
//do other stuff
first = false;
}
но я бы предпочел использовать итератор.
Ответ 6
Если вы хотите остановиться с каждым из них, возможно, что-то вроде этого:
if (objectList.indexOf(current)==objectList.size()-1) break;
Ответ 7
int nElts = objectList.size();
int n = 0;
for (...) {
if (++n == nElts) ...
- лучшее, что я могу придумать.
Ответ 8
Есть два возможных случая, когда вы хотели бы сделать это.
- Вам нужно что-то сделать после достижения последнего элемента: в этом случае вам просто нужно поместить свой код за пределы цикла.
for(Object item:theLinkedList){
}
System.out.println("something special")
вам нужно каким-то образом изменить последний элемент или использовать информацию, связанную с последним элементом. В этом случае вы должны использовать ** LinkedList ** для доступа к последнему элементу
for(Object item:theLinkedList){
}
Object last=theLinkedList.getLast();
System.out.println("last");
Ответ 9
да, вы можете здесь, как бы я это сделал, если вы не хотите использовать явный синтаксис итератора:
for (Object current : objectList) {
if (objectList.getLast().equals(current))
do-something-special
}
Ответ 10
В дополнение к bayer вам нужно сделать это немного иначе, потому что нет метода getLast()
. Но вместо этого вы можете использовать этот objectList.size() - 1
.
for (Object current : objectList) {
if (objectList.get(objectList.size() - 1).equals(current))
do-something-special
}
Ответ 11
Просто сохраните подсчет повторения цикла, образец:
int loop = 0;
for(Item item : items) {
if(loop == 0) {
//Is First Item
}
if(loop != items.size()-1) {
//Has Next Item
}
if(loop == items.size()-1) {
//Is Last Item
}
//Must Be Last Statement
loop++;
}
Он похож на цикл for(int i = 0; i < items.size(); i++)
;
items.size()
используется для списков и items.length
для массивов;