0

Sort a Map<Key, Value> by values (Java)

My question is different from the above. I want to count the number of occurrences of values of key and sort both keys and values in descending order.

I have this hash map:

0=[1, 2], 1=[2, 3], 2=[4], 3=[4, 5], 4=[5], 5=[]
  • I want to have a list of keys and values sorted in descending order based on the count of values it has. The final list should be 0=[1, 2], 1=[3, 2], 3=[4,5], 2=[4], 4=[5], 5=[]

  • The keys and values should be arranged based on following : 0 has two values, 1 has two values, 3 has two values, 2 has one value, 4 has one value and 5 has nothing so on..

  • Note: both keys and values both are arranged based on the count.

I just sorted the keys based on the count of values

Map<Integer, Integer> map_degree = new HashMap<Integer, Integer>();

    for (Entry<Integer, ArrayList<Integer>> entry : list.entrySet()) {

        ArrayList<Integer> value=entry.getValue();
        int degree= value.size(); 
        int key=entry.getKey();
        map_degree.put(key,degree);

        }


       System.out.println("The mapping"+list);
       System.out.println("Before sorting" +   map_degree);
       System.out.println("After sorting descindeng order");
       Map<Integer, Integer> sortedVertex = sortByComparator(map_degree);
       System.out.println(sortedVertex); 





   }

   private static Map<Integer, Integer> sortByComparator(Map<Integer, Integer> map_degree)
   {

       LinkedList<Entry<Integer, Integer>> list_sorting = new LinkedList<Entry<Integer, Integer>>(map_degree.entrySet());

       // Sorting the list based on values
       Collections.sort(list_sorting, new Comparator<Entry<Integer, Integer>>()
       {
           public int compare(Entry<Integer, Integer> o1,
                   Entry<Integer, Integer> o2)
           {

               {    
                   // returns descending order
                   return o2.getValue().compareTo(o1.getValue());

               }
           }
       });



       // Maintaining insertion order with the help of LinkedList
       Map<Integer, Integer> sortedMap = new LinkedHashMap<Integer, Integer>();

       for (Entry<Integer, Integer> entry : list_sorting)
       {
           sortedMap.put(entry.getKey(), entry.getValue());
       }

       return sortedMap;

   }

The output is (key is sorted and mapped with count of values)

Before sorting{0=2, 1=2, 2=1, 3=2, 4=1, 5=0}
After sorting descindeng order
{0=2, 1=2, 3=2, 2=1, 4=1, 5=0}

How can i order the values of the key also such that finally i get 0=[1, 2], 1=[3, 2], 3=[4,5], 2=[4], 4=[5], 5=[] ?

Community
  • 1
  • 1
priya
  • 375
  • 5
  • 22
  • 2
    Possible duplicate of [How to sort a Map on the values in Java?](http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java) – mawalker Dec 24 '15 at 21:33
  • @mawalker It is different. I want to arrange keys and values according to the number of count of values. – priya Dec 24 '15 at 21:43
  • That is still a 'sort', you just want to sort on a different part of the key/pair set. – mawalker Dec 24 '15 at 21:46
  • @priya, no, it's not really different. It's the same problem, you're just sorting on a property of the values (the size of the list) rather than the values themselves. – Louis Wasserman Dec 25 '15 at 00:20

1 Answers1

1

Try this.

    Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>() {{
        put(0, Arrays.asList(1, 2));
        put(1, Arrays.asList(2, 3));
        put(2, Arrays.asList(4));
        put(3, Arrays.asList(4, 5));
        put(4, Arrays.asList(5));
        put(5, Arrays.asList());
    }};
    System.out.println("Before " + map);
    Map<Integer, List<Integer>> sorted = map.entrySet().stream()
        .peek(e -> e.getValue().sort((a, b) -> map.get(b).size() - map.get(a).size()))      // sort values descending
        .sorted((a, b) -> b.getValue().size() - a.getValue().size())    // sort keys descending
        .collect(LinkedHashMap::new, (m, e) -> m.put(e.getKey(), e.getValue()), (m0, m1) -> m0.putAll(m1));
    System.out.println("After  " + sorted);

result:

Before {0=[1, 2], 1=[2, 3], 2=[4], 3=[4, 5], 4=[5], 5=[]}
After  {0=[1, 2], 1=[3, 2], 3=[4, 5], 2=[4], 4=[5], 5=[]}
  • Thanks !!. The order of keys is correct but the values should be in the order 0=[1, 2], 1=[3, 2], 3=[4,5], 2=[4], 4=[5], 5=[] . For example : 3=[4,5] and not 3=[5, 4] because 4 has one value and 5 has nothing. 0=[1, 2] and not 0=[2, 1] because 1 has two values and two has just one value. (should be in descending order of countof values mapped ). – priya Dec 24 '15 at 22:44
  • I have a asked a related question . Could you please check this link too. [link](http://stackoverflow.com/questions/34575726/how-to-sort-hash-map-based-on-number-of-keys-for-a-value-using-flatmap-java8#comment56897375_34575726). Any idea? – priya Jan 03 '16 at 12:34