Explain Codes LogoExplain Codes Logo

Java Set retain order?

java
performance
best-practices
collections
Alex KataevbyAlex Kataev·Oct 14, 2024
TLDR
Set<Integer> orderedSet = new LinkedHashSet<>(Arrays.asList(4, 3, 2, 1)); System.out.println(orderedSet); // It prints [4, 3, 2, 1] not [1, 2, 3, 4] because 4 wanted to be first!

A LinkedHashSet in Java retains the insertion order. It's like a party where guests leave in the same order they arrived. Meanwhile, a HashSet is like a wild party where guests leave in any order, and a TreeSet is a posh, organized party where guests leave sorted by their names.

The Right Set for your Application

When selecting a Set implementation, juggle performance and ordering needs. HashSet performs very well but doesn't care about order. TreeSet maintains a neat, sorted arrangement, which could differ from the insertion order.

Let's call LinkedHashSet the "nicest of all parties". It keeps the order of arrival (insertion order). However, remember that it uses more memory than HashSet because, besides the party guest, it also needs space for the guy who checks the order of arrivals.

If you require your method to return sorted data, a SortedSet disguised as a TreeSet could be your best candidate. ConcurrentSkipListSet is a sorted set, and it's also thread-safe, the perfect fit for multithreaded environments.

If you're stuck with an unordered Set, we've got a trick up our sleeve: Wrap it up using LinkedHashSet to make it remember the order again.

Crucial insights into Set order

Handling performance and order

Selecting a Set implementation is like choosing your vehicle. A HashSet is like a sports car - fast but leaves your luggage jumbled up. A LinkedHashSet is like a minivan - slower, spacious, keeping everything just as you left it. A TreeSet is like a luxurious limo - everything is sorted and in place, but it's somewhat slower due to the 'sorting' it does.

Spotting method inconsistencies

In methods that need to return an ordered set, be very explicit about the Set type. It's like declaring a party "first come, first served" or "strictly by invitation" or "free for all".

public LinkedHashSet<Integer> getOrderedSet() { return new LinkedHashSet<>(Arrays.asList(4, 3, 2, 1)); }

This guarantees the calling code knows the order it will get, just like knowing the type of party to dress appropriately.

Bonus: How to Brace For Unordered Sets

Documenting the journey

Official Java documentation Set (Java Platform SE 8 ) has all the intricate details. For LinkedHashSet, the operational behavior advancement is over here: LinkedHashSet (Java Platform SE 8 ).

Handling unordered sets elegantly

Imagine getting an unordered Set. Retrofit it by wrapping it in a LinkedHashSet, like making an unruly kid follow the rules by adding some structure:

Set<Integer> unorderedSet = new HashSet<>(Arrays.asList(4, 3, 2, 1)); Set<Integer> orderedSet = new LinkedHashSet<>(unorderedSet); // Now be good and follow the order!

It's a minimal change path to retain the order of elements with no need for drastic rewrites.

Overriding default ordering

Overwrite the default TreeSet ordering by throwing in a Comparator. Now that's some power move!

Set<String> orderedByLength = new TreeSet<>(Comparator.comparingInt(String::length));