0

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);
April_Nara
  • 1,024
  • 2
  • 15
  • 39

3 Answers3

2

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}
developer_hatch
  • 15,898
  • 3
  • 42
  • 75
1

You can compare in this way, if you are aiming to sort with length.

Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {

    @Override
    public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
        // TODO Auto-generated method stub

        if (o1.getKey().length() == o2.getKey().length()) {
            return 0;
        }

        if (o1.getKey().length() > o2.getKey().length()) {
            return 1;
        } else {
            return -1;
        }

    }

});
Simmant
  • 1,477
  • 25
  • 39
  • That's a good answer, and a plus one ;), you can do it shorter, take a look at my answer if you want – developer_hatch Nov 13 '17 at 19:18
  • Thank you :), I checked and I really like that way, but reason why I use multiple if statement because it make code bit debug friendly :P in general. – Simmant Nov 13 '17 at 19:25
  • Thanks but this doesn't solve the problem of sorting them by value as well. – April_Nara Nov 13 '17 at 20:24
  • Sorry for delay in response, but now I have one question to @April_Nara, and its basis how much I understand your question and please correct me if I m wrong. You wanted to sort it with key and sorting is based on sum of individual key. If this the case then why you are using String as key?? It can easily be done with Integer as sum of key. – Simmant Nov 14 '17 at 10:24
0

You haven't said why it doesn't work. What happens when you try?

In Java, a Map is not meant to be sorted, it is meant for fast access. However, implementations like TreeMap maintain a deterministic ordering, and can be sorted. Your code suggests you are trying to sort the Map's EntrySet. A Java Set also has no order, and cannot be sorted.

I suggest you either utilise a NavigableMap like a TreeMap, or work with a List rather than a Set. A Java List has an order, and can be sorted using Collections.sort(...).

There are a number of reasons why your existing code may not be working. For one thing, you are attempting to call compareToon an int (at o1.getKey().length().compareTo(...)). This is not possible. You could instead use:

Ints.compare(o1.getKey().length(), o2.getKey().length());
alexvinall
  • 417
  • 4
  • 14