bawa
bawa

Reputation: 93

Sorting a hash map first according to value, then key secondarily

I need to sort a hash map, first according to value then according to key.

TreeMap<String,Integer> dictionary = new TreeMap<String,Integer>();

For example, the desired output is something like:

it - 2
of - 2
the - 2
times - 2
was - 2
best - 1
worst - 1

I tried tree map, but that only sorts it according to key. So basically, I need to sort my first according to the Integer (Highest to Lowest) and then according to the String (First A then B till Z). I searched online and saw that I'm gonna have to use comparator but I'm not sure how to make it work? Any guidance will be appreciated.

This is for a Java assignment.

Upvotes: 1

Views: 924

Answers (2)

Bohemian
Bohemian

Reputation: 424983

The Map interface has no concept of "order", but you could sort the entries:

Map<String, Integer> map; // populated
List<Map.Entry<String, Integer>> entries = new ArrayList<> (map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
    public int compareTo(Map.Entry<String, Integer> a, Map.Entry<String, Integer> b) {
        return a.getValue().equals(b.getValue()) ? a.getKey().compareTo(b.getKey()) : Integer.compareTo(b.getValue(), a.getValue());
    }
});
for (Map.Entry<String, Integer> entry : entries)
    System.out.println(entry.getKey() + " - " + entry.getValue());

If java 8 is available, it becomes a lot neater:

Map<String, Integer> map; // populated
map.entrySet().stream()
    .sorted( (a, b) -> a.getValue().equals(b.getValue()) ? a.getKey().compareTo(b.getKey()) : Integer.compareTo(b.getValue(), a.getValue()))
    .map(e -> entry.getKey() + " - " + entry.getValue())
    .forEach(System.out::println);

If absolutely need a map, load them into aLinkedHashMap, which "preserves order" in that it iterates over its entries in the same order they were inserted.

Upvotes: 3

seand
seand

Reputation: 5286

(I'm assuming this is something like Java). Sorted maps only deal with keys, not values. You probably want to just load the map content into a new TreeMap where each key is the original key and value combined somehow. Or, you can load into an List and sort that, or use a Set.

Upvotes: 1

Related Questions