Sag*_*udi 6 java collections map treemap
我试图根据词频(即基于值)对地图进行排序.为此,我已经覆盖了比较器并传递给了TreeMap
,但我得到了这个奇怪的输出.
public class WordFrequency {
public static String sentence = "one three two two three three four four four";
public static Map<String, Integer> map;
public static void main(String[] args) {
map = new HashMap<>();
String[] words = sentence.split("\\s");
for (String word : words) {
Integer count = map.get(word);
if (count == null) {
count = 1;
} else {
++count;
}
map.put(word, count);
}
Comparator<String> myComparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
if (map.get(s1) < map.get(s2)) {
return -1;
} else if (map.get(s1) > map.get(s2)) {
return 1;
} else {
return 0;
}
}
};
SortedMap<String, Integer> sortedMap = new TreeMap<String, Integer>(myComparator);
System.out.println("Before sorting: " + map);
sortedMap.putAll(map);
System.out.println("After Sorting based on value:" + sortedMap);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Before sorting: {two=2, one=1, three=3, four=3}
After sorting based on value:{one=1, two=2, three=3}
Run Code Online (Sandbox Code Playgroud)
预期产出:
{one=1, two=2, four=3,three=3}
Run Code Online (Sandbox Code Playgroud)
您的compare
方法无法遵守Map接口的约定,因为它比较值而不是键.您的实现会导致具有相同值的两个键被视为相同的键.因此,您sortedMap
不包含"四"键,其值与"三"键相同.
请注意,如果此有序映射要正确实现Map接口,则树映射维护的顺序(如任何有序映射)以及是否提供显式比较器必须与equals一致.(见相当或比较为一致的精确定义与equals).这是因为Map接口是按照equals操作定义的,但有序映射使用它的compareTo执行所有的键比较(或比较)方法,因此2从排序映射的角度来看,通过此方法被视为相等的键是相等的.即使排序与equals不一致,也可以很好地定义有序映射的行为.它只是不遵守Map接口的一般合同.
您可以通过在值相等时比较键来解决此问题:
Comparator<String> myComparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
if (map.get(s1) < map.get(s2)) {
return -1;
} else if (map.get(s1) > map.get(s2)) {
return 1;
} else {
return s1.compareTo(s2);
}
}
};
Run Code Online (Sandbox Code Playgroud)
这应该给你一个输出:
After sorting based on value:{one=1, two=2, four=3, three=3}
Run Code Online (Sandbox Code Playgroud)
因为four<three
基于字符串的自然顺序.
归档时间: |
|
查看次数: |
714 次 |
最近记录: |