Search code examples
javasortingcollectionscomparatorcompareto

Sort Entry Set of String, Integer by more than one field


Have a Map<String, Integer> and trying to sort on value and length of String. I am trying to compare two different things in the statement so don't know if I need two different statements. This is being used to compare digit root so the String length and then the digit root is the value and the value.

For example:

("103",4); (1+0+3 == 4)
("4",4); (4 ==4)
("11101",4); (1+1+1+0+1 == 4)
("5",5); (5 == 5 )
("1003",4); (1+0+0+3 == 4)

But ("103",4) > ("4",4) because the length of "103" > "4", and ("11101",4) > ("103",4);, length "11101" > "103"

Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { int length = o1.getKey().length().compareTo(o2.getKey().length());
if(length != 0) {
 return length;
}
return (o1.getValue()).compareTo(o2.getValue());
}
});

Edit Answered to the above Question(Also, response given)

 Map<String,Integer> unsortMap = new.
                        TreeMap<String,Integer>();

unsortMap.put("103",4);
unsortMap.put("4",4);
unsortMap.put("11101",4);   
unsortMap.put("5",5);
unsortMap.put("1003",4); Map<String,

 Integer> result =unsortMap.entrySet().stream() .sorted(Map.Entry.comparingByKey(Comparator.comparingInt(String::length)) )
   .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap
     (Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); 

 System.println(result);

Solution

  • If you already have a map, and you want to order it, by lenght key, and by value then:

    Map<String,Integer> unsortMap = new TreeMap<String,Integer>();
    
    unsortMap.put("103",4);
    unsortMap.put("4",4);
    unsortMap.put("11101",4);
    unsortMap.put("5",5);
    unsortMap.put("1003",4);
    
    Map<String, Integer> result = unsortMap.entrySet().stream()
            .sorted(Map.Entry.comparingByKey(Comparator.comparingInt(String::length))
    
            ).sorted(Map.Entry.comparingByValue())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (oldValue, newValue) -> oldValue, LinkedHashMap::new));
    
    
    System.out.println(result);
    
    out => {4=4, 103=4, 1003=4, 11101=4, 5=5}