Элегантный способ делать "нисходящие" итерации с помощью итераторов - PullRequest
1 голос
/ 28 февраля 2012

Например, для списка {1,2,3,4} я должен сравнить пары (1,2), (1,3), (1,4), (2,3), (2), 4), (3,4).Путь с обычным циклом for:

for(i=0 ; i<list.size() ; i++){
    for(j=i+1 ; j<list.size() ; j++){
    //do stuff with list[i] and list[j];
    }
}

Можно ли сделать что-то подобное с итераторами (см. Ниже)?

for (int i : list){
    for(int j : [list after index i]){
    //do stuff with list[i] and list[j];
    }
}

Ответы [ 4 ]

1 голос
/ 28 февраля 2012

При этом все еще используются вложенные циклы, но вместо этого используется ListIterator . ListIterator можно получить с помощью метода listIterator (idx) интерфейса List. Это на самом деле не более элегантно, чем цикл for, но может работать лучше, если список не доступен случайным образом, например, LinkedList.

for (ListIterator i=list.listIterator(); i.hasNext(); ) {
    Object a = i.next();
    for (Iterator j=list.listIterator(i.previousIndex()); j.hasNext(); ) {
        Object b = j.next();
    }
}
1 голос
/ 28 февраля 2012

Возможно, не , что элегантно, но возможно:

int lastIndex = list.size()-1;
for (Object i : list) {
  for (Object j : list.sublist(list.indexOf(i), list.size()-1)) {
    // do what has to be done
  }
}
1 голос
/ 28 февраля 2012

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

Если вы делаете это много, вы можете инкапсулировать код в метод и передать ему метод для вызова для каждой пары.

0 голосов
/ 28 февраля 2012

Вы можете реализовать свой собственный Итератор , чтобы сделать это.Вам также нужно будет создать простые объекты-обертки, чтобы позволить вам возвращать два элемента одновременно (очень досадно, что в Java нет встроенного типа кортежа!).

Просто путем реализации Iteratorоднако не позволит вам использовать его непосредственно в цикле for.Вместо этого вам придется сделать что-то вроде этого:

Iterator<MyPairObject> iterator = new MyIterator(list);
while (iterator.hasNext()) {
    ...
}

Однако, если вы подклассом используете класс list, который вы используете, вы можете переопределить метод iterator() и вернуть свой собственный итератор - тогда выВы сможете использовать свой собственный класс списка и его итератор непосредственно в цикле for.

...