Java - Как я могу сослаться на предыдущий и следующий элемент во время итерации? - PullRequest
7 голосов
/ 19 декабря 2011

Когда у меня есть для цикла , я использую i для ссылки на элементы моего массива, объекты и т. Д.

Как:
Текущий пункт: myArray[i]
Следующий товар: myArray[i+1]
Предыдущий товар: myArray[i-1]

Но сейчас я использую цикл foreach (for (Object elem : col) {).
Как мне обратиться к предыдущему пункту?
(Мне нужно выполнить поиск по «массиву», который я делаю с for (Object object : getComponents()).

Но когда он возвращает true (поэтому он находит то, что я ищу), он должен выполнить код для элемента previous и next .

Уточнение: У меня есть java.awt.Component элементов!

Ответы [ 4 ]

9 голосов
/ 19 декабря 2011

Если структура данных является списком, то вы можете напрямую использовать ListIterator . ListIterator является особенным, потому что он содержит оба метода next() и previous ()

List list = ...;
ListIterator iter = list.listIterator(); //--only objects of type List has this
while(iter.hasNext()){
    next = iter.next();
    if (iter.hasPrevious()) //--note the usage of hasPrevious() method
       prev = iter.previous(); //--note the usage of previous() method
}
5 голосов
/ 19 декабря 2011

Цикл foreach не позволит вам сделать это. Я предлагаю вернуться к использованию старого доброго стиля Iterator. Например

final Iterator itr=getComponents().iterator();
Object previous=itr.next();
Object current=itr.next();
while(itr.hasNext()){
    Object next=itr.next();
    //Do something with previous, current, and next.
    previous=current;
    current=next;
}
1 голос
/ 19 декабря 2011
JButton prev, next, curr;
Component[] arr = getComponents();

for(int i=1;i<arr.length-1;i++) {
    if (yourcondition == true) {
        curr = (JButton) arr[i];
        prev = (JButton) arr[i-1];
        next = (JButton) arr[i+1];
    }
}
0 голосов
/ 16 января 2018

Индексирование массива

Если у вас есть массивоподобная структура данных (например, фактический массив или что-то вроде ArrayList), то ссылки на i, i-1, i+1 будут давать хорошую производительность так что тут ничего особенного. (Хотя необходимость превращать цикл For-Each в индекс, подсчитывающий цикл For, не очень забавная и является одним из немногих предостережений.)

Ответ, предложенный Сергеем, делает что-то вроде этого.

Универсальный ListIterator

Если вы можете взять в руки ListIterator (что на самом деле является довольно большим предположением), ответа, предложенного Сураджем, может быть достаточно. Но обратите внимание, что next() и previous() перемещают позицию итератора . Поэтому, если вы сделали что-то вроде следующего для каждой итерации цикла: prev = previous(); current = next(); next = next(); previous(), вы в конечном итоге будете выполнять примерно 4 итерационные операции за цикл. Это не составляет большой проблемы, если итерация дешевая , и, к счастью, это часто имеет место для структур данных, которые предлагают ListIterator.

Универсальный раствор

Общее решение для любого Iterable (или Iterator) не должно делать случайных поисков (как это возможно с массивом) или делать предположения относительно производительности next(), которую следует вызывать не более N раз, где N - количество доступных элементов.

Вот одна из таких реализаций:

final Iterator<E> it = iterable.iterator();

for (E next = (it.hasNext() ? it.next() : null), current = null; next != null;) {
    E previous = current;
    current = next;
    next = it.hasNext() ? it.next() : null;

    // Do something using 'current', 'previous' and 'next'.
    // NB: 'previous' and/or 'next' are null when 'current' is
    // the first and/or last element respectively
}

Имейте в виду, эта реализация имеет свои собственные предостережения:

  • Это сломается, если Iterable содержит null элементов.
  • Ни current, ни next не являются эффективно-окончательными , поэтому не могут быть использованы непосредственно в них с разбитыми лямбдами Java 8.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...