In Java, sort the hash map by its key.length ()

I have a hashmap like this:

HashMap<String,Integer> map = new HashMap<String,Integer>(); map.put("java",4); map.put("go",2); map.put("objective-c",11); map.put("c#",2); 

Now I want to sort this map by key length if the two lengths of the keys are equal (e.g. go and C # as length 2) and then sorted in alphba order. so the result that I expect to get is something like:

printed result: objective-c, 11 java, 4 C #, 2 go, 2

here is my own attamp, but it doesn't work at all ...

  HashMap<String,Integer> map = new HashMap<String,Integer>(); map.put("java",4); map.put("go",2); map.put("objective-c",11); map.put("c#",2); Map<String,Integer> treeMap = new TreeMap<String, Integer>( new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.length().compareTo(s2.length()); } } ); 

actually the compareTo method looks like red (cannot compile) .... please help me with some sample code ... I'm a little confused about how to use the comparator class to configure the comparison object ...

+5
source share
6 answers

The compiler complains because you cannot call compareTo on an int . The correct way to sort the map is as follows:

 Map<String, Integer> treeMap = new TreeMap<String, Integer>( new Comparator<String>() { @Override public int compare(String s1, String s2) { if (s1.length() > s2.length()) { return -1; } else if (s1.length() < s2.length()) { return 1; } else { return s1.compareTo(s2); } } }); 

The first two conditions compare the lengths of two String and respectively return a positive or negative number. The third condition would compare String lexicographically if their lengths are equal.

+12
source

You call String#length() , which returns an int primitive. You need the static method Integer.compare(int,int) . If you are on Java 8, you can save a lot by typing:

 Map<String,Integer> treeMap = new TreeMap<>( Comparator.comparingInt(String::length) .thenComparing(Function.identity())); 
+4
source

because length() does not define the compareTo method, so you see an error. To fix this, use Integer.compare(s1.length(), s2.length()); updated code below

 import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; public class Test { public static void main(String[] args) { HashMap<String,Integer> map = new HashMap<String,Integer>(); map.put("java",4); map.put("go",2); map.put("objective-c",11); map.put("c#",2); Map<String,Integer> treeMap = new TreeMap<String, Integer>( new Comparator<String>() { @Override public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } } ); treeMap.putAll(map); System.out.println(treeMap); } } 
+2
source

If using TreeMap is optional

Explantion Define a Comaprator and the next step, define a list so that we can add all the entries to the list. At the end, sort the list by a specific Comaprator

The code

  Comparator<Map.Entry<String,Integer>> byMapValues = (Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) ->left.getValue().compareTo(right.getValue()); List<Map.Entry<String,Integer>> list = new ArrayList<>(); list.addAll(map.entrySet()); Collections.sort(list, byMapValues); list.forEach( i -> System.out.println(i)); 

Exit

 c#=2 go=2 java=4 objective-c=11 

Note: sort by number

if you need to perform a key-based comparison, you can use the following line.

 Comparator<Map.Entry<String,Integer>> byMapKeys = (Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) -> left.getKey().compareTo(right.getKey()); 
+1
source
  public int compare(String o1, String o2) { return o1.length() == o2.length() ? o1.compareTo(o2) : o1.length() - o2.length(); } 
+1
source

The comparator must be:

 new Comparator<String>() { @Override public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } } 
-1
source

Source: https://habr.com/ru/post/1202814/


All Articles