Java LinkedHashSet backwards iteration
Asked Answered
S

6

30

How can I iterate through items of a LinkedHashSet from the last item to the first one?

Shuttle answered 24/5, 2012 at 16:51 Comment(3)
Why in Java Collection Framework it is not included. LinkedHashSet maintains FIFO order so an utility to convert the order into LIFO should be there which seems to be vary handy when requirement is to maintain insertion order at the same time we may need to iterate in reverse order. In my project there were couple time I needed this already. Unfortunately, I have to use List as intermediary to take advantage of Collections.reverse() utility. This is dirty isn't it!Principate
This has been a problem since forever. There are proposals floating around to address it.Hyla
@Principate They finally addressed this in Java 21: https://mcmap.net/q/475166/-java-linkedhashset-backwards-iterationGeer
N
29

If you want to continue to use collections, you could use the following:

LinkedHashSet<T> set = ...

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

If you're fine with using an array instead, you could take a look at hvgotcodes' answer.

Nicknack answered 24/5, 2012 at 16:58 Comment(2)
The new LinkedList<>(set) will copy all items, won't it?Plank
@Plank Yes, it will.Nicknack
C
7

I would use toArray and just use a reverse for loop.

There might be a better way to do it, but that should work. toArray guarantees any order is preserved

If this set makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order.

Something like

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

for (int i = asArray.length - 1; i>=0; i--){
..
}
Chrestomathy answered 24/5, 2012 at 16:53 Comment(3)
your code seems cann't compile: MyType[] asArray = mySet.toArray();Peeling
Object array cannot be converted to MyType array. This code won't compile.Hirst
I just fixed that.Weisbart
B
7

This is another way:

LinkedHashSet<T> set = ...

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

for( T item : list ){
   ...
}
Brilliancy answered 24/5, 2012 at 17:1 Comment(0)
C
2

You could put the elements into an ArrayList and then use the ArrayList's ListIterator.

ListIterator<T> l = new ArrayList<T>(yourLinkedHashList).listIterator();
// ListIterator can iterate in reverse
while(l.hasPrevious()) {
    T obj = l.previous();
}
Coarse answered 24/5, 2012 at 17:7 Comment(0)
G
2

As of Java 21, the reversed() method on LinkedHashSet can be used. This reversed view of the set can be used to iterate in reverse order.

for (Object o : myLinkedHashSet.reversed()) {
  System.out.println(o);
}
Geer answered 30/4, 2023 at 8:30 Comment(0)
V
0

Now from java 21 onwards you can use reversed() method of SequancedSet to reverse a collection element.

LinkedHashSet lhs=....
....
.....
SequencedSet sequencedSet=lhs.reversed();
Visibility answered 5/1, 2024 at 4:23 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.