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 its key length, if two keys length are equal (e.g go and c# both length 2), then sorted by alphba order. so the outcome 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 doesnt 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 appears as red (not be able to compile).... please someone help me with some code example...i am a bit confusing with how to use comparator class to customize compare object...
The compiler is complaining because you cannot call compareTo on an int. The correct way to sort the map is the following:
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 the two Strings and return a positive or a negative number accordingly. The third condition would compare the Strings lexicographically if their lengths are equal.
You call String#length(), which returns a primitive int. You need the static method Integer.compare(int,int). If you are on Java 8, you can save yourself a lot of typing:
Map<String,Integer> treeMap = new TreeMap<>(
Comparator.comparingInt(String::length)
.thenComparing(Function.identity()));
because length() doesn't define compareTo method thats why you see error. To correct it 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);
}
}
If using the TreeMap is not mandatory
Explantion: Define a Comaprator , and next step, define a list so we can add all map entries into a list. At the end, sort the list by defined Comaprator
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));
Output:
c#=2
go=2
java=4
objective-c=11
Note: get sorted by number
if there is need to do comparison based on key, the following line can be used.
Comparator<Map.Entry<String,Integer>> byMapKeys =
(Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) -> left.getKey().compareTo(right.getKey());
public int compare(String o1, String o2) {
return o1.length() == o2.length() ? o1.compareTo(o2) : o1.length() - o2.length();
}
The Comparator should be:
new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
}
来源:https://stackoverflow.com/questions/25899929/in-java-sort-hash-map-by-its-key-length