It's time to get your affairs in order.

Specifically, you need to sort that Java Map you're currently working with.

I know you need to do that right now because your favorite search engine brought you here so you could learn how to do that.

So let me show you a couple of ways to sort a Java Map.

By Key

Chances are pretty good that you need to sort the Map by key. So let's start there.

But first, let's get a hypothetical business requirement established. Suppose you're working on a CRM app and you use a Map that associates customer names with sales regions.

Set up some test data with code that looks like this:

Map<String, String> customerMap = new HashMap<String, String>();
customerMap.put("Joe Jones", "NorthEast");
customerMap.put("John Jackson", "Southwest");
customerMap.put("Lief Beauregard", "Southwest");
customerMap.put("Ashton Kendall", "South");
customerMap.put("Leila Prinz", "Pacific");

Now let's say you want to sort that Map alphabetically based on the customer's first name. 

Here's some code that will do that:

Map<String, String> sorted = customerMap
                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                                        (previousValue, newValue) -> previousValue, LinkedHashMap::new));

Lots of fun stuff happening there so let me break it down.

For starters, the code grabs the entry set (via the appropriately named entrySet() method) from the Map. That's going to return a List of Entry objects.

Then, the code creates a Stream object from that List with the also appropriately named stream() method.

After that, the code sorts the elements in the Stream with the sorted() method. Here, it's using comparingByKey() on the Entry class so the elements get sorted based on their natural order (i.e., alphabetically).

But that sorted() method just returns a Stream object, not a Map object. That's why the code uses the collect() method to create a Map.

Within that collect() method, the code invokes Collectors.toMap(). That's a static method that accepts four parameters.

The first parameter is the key of the entry in the new Map

The second parameter is the value of the entry in the new Map.

Those first two parameters, by the way, are functions. That's why the code gets away with using method references (::).

The third parameter is also a function. It's used to resolve collisions between values associated with the same key. It's not likely you'll have that problem, though.

The fourth parameter is a Supplier. It instantiates the Map object that will get populated with the new results.

By the way, the code instantiates a LinkedHashMap instead of HashMap for a very good reason: LinkedHashMap preserves insertion order. That's very important here since the name of the game is to keep things sorted.

Now if you run that code above and print out the resulting set to the console, you'll get this:

{Ashton Kendall=South, Joe Jones=NorthEast, John Jackson=Southwest, Leila Prinz=Pacific, Lief Beauregard=Southwest}

Perfect. It's sorted alphabetically by key.

By Value

But let's say you don't want to sort the Map by key. You want to sort it by value.

Well guess what? You can do that, too. 

But let's throw a little fly in the ointment here. Let's say you want to sort the Map by value in reverse alphabetical order.

Yep. You can do that, too:

Map<String, String> sorted = customerMap
                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                                        (previousValue, newValue) -> previousValue, LinkedHashMap::new));

The only difference between that block of code and the previous one is in the sorted() method.

Instead of using Map.Entry.comparingByKey() it's using Map.Entry.comparingByValue().

Unsurprisingly, that sorts the entries in the sequence by value instead of by key.

But it's also using a parameter in the comparingByValue() method: Comparator.reverseOrder(). That static method returns a Comparator that, you guessed it, sorts the entries in reverse order.

Now print that result out to the console and you'll get the following:

{John Jackson=Southwest, Lief Beauregard=Southwest, Ashton Kendall=South, Leila Prinz=Pacific, Joe Jones=NorthEast}

Bingo. All entries are sorted by value in reverse alphabetical order.

Wrapping It Up

You got this.

Take what you've learned here and start using it in your own code. Just adapt it to suit your business requirements.

Have fun!

Photo by Sarah Chai from Pexels