Apologies for the newbie question, but what's the proper way to get a Set
(say LinkedHashSet
) in reverse order? For Collection
s there's Collections.reverse(Collection c)
, but how does one do it for a Set
with ordered elements (like a LinkedHashSet
)?

- 31,231
- 29
- 115
- 197
-
5A `Set` doesn't have an order. Can you clarify? Also, `reverse` takes a `List`. – Sotirios Delimanolis Mar 06 '14 at 00:28
-
1Okay... I mean a `LinkedHashSet` (which is ordered). What's the best way to reverse it? Do I need to get the iterator and just iterate over it, or is there a smarter way? – carlspring Mar 06 '14 at 00:31
-
3@SotiriosDelimanolis In Java, `TreeSet`s keep their items in sorted order. To get at the elements in reverse order, you can use the `descendingSet()` method. For `LinkedHashSet`, see this answer: http://stackoverflow.com/questions/10741902/java-linkedhashset-backwards-iteration – dlev Mar 06 '14 at 00:31
-
4A `LinkedHashSet` is not _ordered_ it is `Linked`. If you want to loop over the items in reverse order of insertion use an `Iterator`. – Boris the Spider Mar 06 '14 at 00:32
-
2@BoristheSpider It's really dependent on what you mean by "ordered". `TreeSet` maintains a "sorted" order, whereas `LinkedHashSet` maintains the insertion order (and thus does have a predictable iteration order.) – dlev Mar 06 '14 at 00:33
-
1@dlev you're right - it's mainly semantics. – Boris the Spider Mar 06 '14 at 00:37
6 Answers
Sets are not ordered in general, so to preserve the sorting, after sorting the set as a list, you would need to use a known iteration order implementation of Set, such as LinkedHashSet
List list = new ArrayList(set);
Collections.sort(list, Collections.reverseOrder());
Set resultSet = new LinkedHashSet(list);
You could also use TreeSet with a comparator, but that is not as fast as the ArrayList method above.

- 972
- 7
- 13
-
Wouldn't this be inefficient (memory-wise) with larger sets of data (as you'll end up having the same data in memory twice)? My input is a `Set`, not a `List`. – carlspring Mar 06 '14 at 00:41
-
The Java Collections API doesn't seem to allow for a constant space sorting or an arbitrary Set. You may need to limit yourself to the SortedSet API to expect that from what I can tell. – Peter Apr 02 '14 at 00:44
public class LargestArray {
public static void main(String[] args) {
ArrayList<Integer> al = new ArrayList<>();
Set<Integer> set = new TreeSet<>();
set.add(10);
set.add(20);
set.add(7);
set.add(4);
set.add(1);
set.add(2);
set.add(3);
set.add(4);
System.out.println("after Sorting");
for(int i : set) {
System.out.print(" " + i);
}
al.addAll(set);
set.clear();
Collections.reverse(al);
System.out.println();
System.out.println("After Reverse");
for (int i : al) {
System.out.print(" " + i);
}
}
}
output = after Sorting 1 2 3 4 7 10 20 After Reverse 20 10 7 4 3 2 1

- 1,620
- 5
- 26
- 37
Check this out
http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#descendingSet()
If you use a TreeSet you can get reverse order by calling descendingSet.

- 8,673
- 4
- 36
- 47
-
Wouldn't the `TreeSet` re-order them after I have added them (and mix up the order)...? – carlspring Mar 06 '14 at 00:38
-
No that is why requires a comparator to maintain the order. If the comparator isn't correctly implemented then yes your order can be very strange. – Daniel Williams Mar 06 '14 at 00:42
-
1The OP is using a `LinkedHashSet` - this maintains insertion order. Putting the items into a `TreeSet` would obviously break this. Unless you supplied an explicit ordering comparator - which defeats the object somewhat. – Boris the Spider Mar 06 '14 at 01:01
-
1Ah that was added in an edit. I'm surprised LinkedHashSet doesn't have a reverse iterator since the docs say the implementation is backed by a doubly linked list. – Daniel Williams Mar 06 '14 at 01:07
-
That was indeed added a minute, or two after I added the post. Sorry about that. – carlspring Mar 06 '14 at 01:09
I will explain you with an example. Comments are added in mid of the code for better understanding.
public class ReverseLinkedHashSet {
public static void main(String[] args) {
// creating a LinkedHashSet object which is
// of type String or any. Will take a example of String.
HashSet<String> cars = new LinkedHashSet<String>();
// adding car elements to LinkedHashSet object as below
cars.add("Toyato");
cars.add("Hundai");
cars.add("Porshe");
cars.add("BMW");
// Iterating using enhanced for-loop to see the order.
System.out.println("Insertion Order: Iterating LinkedHashSet\n");
for(String car : cars) {
System.out.println(car);
// Output will be as below
//Toyato
//Hundai
//Porshe
//BMW
}
// Now convert to ArrayList to rearrange to reverse
// the linkedHashset
List<String> listOfCars = new ArrayList<String>(cars);
// to reverse LinkedHashSet contents
Collections.reverse(listOfCars);
// reverse order of LinkedHashSet contents
// can be done as below
System.out.println("\n\n\nReverse Order of LinkedHashSet\n");
for(String car : listOfCars) {
System.out.println(car);
// Output will be as below
//BMW
//Porshe
//Hundai
//Toyato
}
}
}
Also, I suggest not to use LinkedhashSet
without a strong reason. For a complex application, it will reduce the performance. Use HashSet
instead.

- 31,231
- 29
- 115
- 197

- 276
- 3
- 9
Java 8, I using solution below,
Set<String> setTest = new HashSet<>();
setTest.add("1");
setTest.add("2");
setTest.add("3");
List<String> list = new ArrayList<>(setTest);
list.sort(Collections.reverseOrder());
Set<String> result = new LinkedHashSet<>(list);
for (String item: result) {
System.out.println("---> " + item);
}
Result:
---> 3
---> 2
---> 1
Work for me.

- 3,676
- 1
- 29
- 28
Java 21 is introducing the SequencedSet
interface for reversible sets which have a well defined insertion order. LinkedHashSet
implements the interface and SortedSet
extends it. For such a set, the reversed()
method will return a reversed view of it.
SequencedSet<String> set = new LinkedHashSet<>(List.of("A", "B", "C"));
SequencedSet<String> reversedSet = set.reversed();
System.out.println(reversedSet); // [C, B, A]

- 14,487
- 7
- 91
- 130