1

I'm trying to sort nested hashMaps , where both HashMaps need to be sorted.

The first hashMap should be sorted by key. Second one should be sorted by value. So far I manage to sort the keys of the first hashMap by making an array of the keys and sort it .

My hashmap looks like this

 HashMap<String,HashMap<String,Integer>> carOwners = new 
                                    HashMap<String,HashMap<String, Integer>>();

an Example is let say we have first String is Name , car brand, qnty.

Example: David:

Audi>5

Bmw>4

Izabel:

VW>10

MB>4

So Basicly first we sort the names, and then we sort the nested hash by value. How can this be done ... cant find any useful information :(>

DavidsAmause
  • 57
  • 1
  • 9
  • 1
    You can not sort an `HashMap`, please consider using `LinkedHashMap` instead – TuyenNTA Jun 28 '17 at 22:37
  • By nature of `HashMap` they have no ordering. What do you mean by sorting them? – Chris Jun 28 '17 at 22:38
  • 1
    @TuyenNguyen `LinkedHashMap` is a `HashMap`. And technically you can't sort a `LinkedHashMap` either. – shmosel Jun 28 '17 at 22:39
  • @DavidsAmause Do you need to *maintain* the sort? That is, are you adding items to the map(s)? – shmosel Jun 28 '17 at 22:41
  • @shmosel you're right. `LinkedHashMap` only maintain the sorted order. [An example of sort map](https://www.mkyong.com/java/how-to-sort-a-map-in-java/) – TuyenNTA Jun 28 '17 at 22:44
  • Seriosly can't sort HashMap? It is the only way I figured out to solve my problem and it is that I read for example from a document David > audi David > adui David > bmw david > bmw And so on , so I put them in nested hashMap and increment only the value of the seonc hash to count the cars. However I need to print after that alphabetic the names + from most cars? ... no way to solve this with hash? What is the other way then? – DavidsAmause Jun 28 '17 at 22:47
  • 1
    @DavidsAmause Seriously. Why would you need to? – shmosel Jun 28 '17 at 22:47
  • 1
    *"Seriossly can't sort HashMap?"* - Yes. Seriously. *"It is the only way I figured out to solve my problem ..."* - well you need need to rethink your problem. There are always alternatives. For example, don't use `HashMap` as your only data structure. – Stephen C Jun 28 '17 at 22:52
  • Such as ? I'm seriosly stuck with this one ... The whole point of the hashMap is to link key>value ... I can easy sort hashMap , but with nested i jsut cant figure it out... – DavidsAmause Jun 28 '17 at 22:57
  • Stuck why? Have you considered `TreeMap`. It *is* sorted. – user207421 Jun 28 '17 at 23:05
  • As others mentioned already, `HashSet`s have no ordering by concept. However there are many implementations of `Map` that offer management of `key-value`-pairs. For example everything that implements `SortedMap`. That is, for example, `TreeMap`. But there are many other possible sorted map data-structures, also different tree variants. They all have advantages and disadvantages. `HashMap` provides a fast direct get-access where TreeMap maintains its content sorted but therefore only having `Theta(log(n))` get-access and so on. – Zabuzard Jun 29 '17 at 04:06

2 Answers2

3

For sorting a Map you can use the following class: TreeMap. As the official documentation says,

The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.

If you want to sort the elements in insertion order, please use LinkedHashMap.

This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).

For sorting a Map by value, please see this post. It's also for Java7 and Java8.

Hope it helps.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
3

Make the first map as TreeMap and for the second Map, sort it by values. Refer this post

Below is the code snippet for your problem.

public static void main(String[] args) {
    Map<String, HashMap<String, Integer>> carOwners = new TreeMap<String, HashMap<String, Integer>>();
    HashMap<String, Integer> nameQuantity = new HashMap<String, Integer>();
    nameQuantity.put("Audi", 5);
    nameQuantity.put("BMW", 4);
    carOwners.put("David", sortByValue(nameQuantity)); 
    nameQuantity = new HashMap<String, Integer>();
    nameQuantity.put("VW", 10);
    nameQuantity.put("MB", 4);
    carOwners.put("Izabel", sortByValue(nameQuantity)); 
    for (Map.Entry<String, HashMap<String, Integer>> carOwnerEntry : carOwners.entrySet()) {
        System.out.println(carOwnerEntry.getKey());
        HashMap<String, Integer> nameQty = carOwnerEntry.getValue();
        for (Map.Entry<String, Integer> nameQtyEntry : nameQty.entrySet()) {
            System.out.println(nameQtyEntry.getKey() + " " + nameQtyEntry.getValue());
        }
    }

public static <K, V extends Comparable<? super V>> HashMap<K, V> sortByValue(Map<K, V> map) {
    List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
        public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
            return (o1.getValue()).compareTo(o2.getValue());
        });
    HashMap<K, V> result = new LinkedHashMap<K, V>();
    for (Map.Entry<K, V> entry : list) {
        result.put(entry.getKey(), entry.getValue());
    }
    return result;
}
Zabuzard
  • 25,064
  • 8
  • 58
  • 82