Обратная итерация Java LinkedHashSet

Как я могу перебирать элементы LinkedHashSet от последнего элемента к первому?


person David Weng    schedule 24.05.2012    source источник
comment
Почему в Java Collection Framework его нет. LinkedHashSet поддерживает порядок FIFO, поэтому должна быть утилита для преобразования порядка в LIFO, которая кажется удобной, когда требуется поддерживать порядок вставки в то же время, когда нам может потребоваться выполнить итерацию в обратном порядке. В моем проекте было пару раз, когда мне это уже было нужно. К сожалению, мне приходится использовать List в качестве посредника, чтобы воспользоваться утилитой Collections.reverse(). Это грязно, не так ли!   -  person Bhavesh    schedule 03.04.2014
comment
Это была проблема с незапамятных времен. Есть предложения по обратиться к нему.   -  person Hollis Waite    schedule 17.04.2021


Ответы (5)


Если вы хотите продолжать использовать коллекции, вы можете использовать следующее:

LinkedHashSet<T> set = ...

LinkedList<T> list = new LinkedList<>(set);
Iterator<T> itr = list.descendingIterator();
while(itr.hasNext()) {
    T item = itr.next();
    // do something
}

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

person Jeffrey    schedule 24.05.2012
comment
new LinkedList<>(set) скопирует все элементы, не так ли? - person Sasha; 07.07.2016
comment
@Саша Да, будет. - person Jeffrey; 07.07.2016

э, если вы имеете в виду LinkedHashSet...

Я бы использовал toArray и просто используйте обратный цикл for.

Возможно, есть лучший способ сделать это, но это должно сработать. toArray гарантирует сохранение любого порядка

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

Что-то типа

Set<MyType> mySet = new LinkedHashSet();
...
MyType[] asArray = mySet.toArray();

for (int i = asArray.length - 1; i>=0; i--){
..
}
person hvgotcodes    schedule 24.05.2012
comment
ваш код кажется не может скомпилироваться: MyType[] asArray = mySet.toArray(); - person ZhaoGang; 28.06.2020
comment
Массив объектов не может быть преобразован в массив MyType. Этот код не будет компилироваться. - person Soham De; 29.11.2020

Это еще один способ:

LinkedHashSet<T> set = ...

List<T> list = new ArrayList<>(set);
Collections.reverse(list);

for( T item : list ){
   ...
}
person trutheality    schedule 24.05.2012

Если вы действительно имели в виду LinkedHashSet, вы можете поместить элементы в ArrayList, а затем использовать ListIterator ArrayList.

ListIterator<T> l = new ArrayList<T>(yourLinkedHashList).listIterator();
// ListIterator can iterate in reverse
while(l.hasPrevious()) {
    T obj = l.previous();
}
person Jeshurun    schedule 24.05.2012

Из javadoc: «Этот связанный список определяет порядок итерации, то есть порядок, в котором элементы были вставлены в набор (порядок вставки)».

Итак, вы можете просто:

LinkedHashSet<Integer> numbers = new LinkedHashSet<Integer>();
numbers.add(1);
numbers.add(2);
numbers.add(33);
numbers.add(44);
numbers.add(108);

for (Integer i : numbers) {
    System.out.println(i);
}
person sysoutnull    schedule 24.05.2012
comment
от последнего к первому. - person hvgotcodes; 24.05.2012