我使用以下代码创建一个hashmap,然后使用树形图和比较器对hashmap中的值进行排序。但是,输出相当出乎意料。 因此,任何关于我做错事的想法都会有所帮助
代码
public static void main(String[] args) {
System.out.println("Most freq"+mostFreq(" i me hello hello hello me"));
}
public static String[] mostFreq(String str){
if ((str==null)||( str.trim().equalsIgnoreCase("")))
return null;
String[] arr = new String[10];
String[] words= str.split(" ");
Map <String,Integer> map = new HashMap<String,Integer>();
for (String word :words)
{
int count =0;
if (map.containsKey(word))
{
count= map.get(word);
map.put(word, count+1);
}
else
map.put(word, 1);
}
MyComparator comp= new MyComparator(map);
Map<String,Integer> newMap= new TreeMap(comp);
newMap.putAll(map);
Iterator it= newMap.entrySet().iterator();
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry) it.next();
System.out.println("Key "+pairs.getKey()+"-- value"+pairs.getValue());
}
return arr;
}
这是比较器
package samplecodes;
import java.util.Comparator;
import java.util.Map;
public class MyComparator implements Comparator {
Map map;
public MyComparator(Map map){
this.map=map;
}
@Override
public int compare(Object o1, Object o2) {
return ((Integer)map.get(o1) >(Integer)map.get(o2)? (Integer)map.get(o1):(Integer)map.get(o2));
}
}
输出的格式为
me-2
hello-3
i-3
答案 0 :(得分:3)
请检查compare
的JavaDoc:您没有返回更大的值,-1
表示o1
&lt; o2
0
,o1
为o2
= 1
,o1
为o2
&gt; @Override
public int compare(Object o1, Object o2) {
return ((Integer) map.get(o1)).compareTo((Integer) map.get(o2);
}
。所以你可以写:
{{1}}
答案 1 :(得分:1)
TreeMap
的{{3}}明确指出:
基于红黑树的NavigableMap实现。地图已排序 根据键
的自然顺序
我们不应该使用TreeMap
按值排序来违反此规则。
但是,要按值排序,我们可以执行以下操作:
LinkedList
map
条目
Collection.sort
对条目进行排序LinkedHashMap
:按照插入顺序保存密钥,当前按自然顺序排序。 将LinkedHashMap
作为已排序的map
返回。
public static <K extends Comparable,V extends Comparable> Map<K,V> sortByValues(Map<K,V> map){
List<Map.Entry<K,V>> entries = new LinkedList<Map.Entry<K,V>>(map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<K,V>>() {
@Override
public int compare(Entry<K, V> o1, Entry<K, V> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
Map<K,V> sortedMap = new LinkedHashMap<K,V>();
for(Map.Entry<K,V> entry: entries){
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
}
参考: Java Doc
答案 2 :(得分:0)
你所做的实际上是滥用工具。
我相信你需要做的是:
当然你仍然可以使用像TreeSet这样的东西并使用频率作为键,但是你应该将单词列表作为这个地图的值(又名Multi-Map),而不是编写一个有问题的比较器而不是遵循比较者的合同:http://docs.oracle.com/javase/6/docs/api/java/util/Comparator.html#compare%28T,%20T%29您的原始实施和其中一个答案的评论都不符合sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y
的规则(原来的更糟糕)。
一些代码片段只是为了给你提示:
List<String> words = ....;
Map<String, Integer> wordFrequencyMap = new HashMap<String, Integer>();
// iterate words and update wordFrequencyMap accordingly
List<String> uniqueWords = new ArrayList<String>(new HashSet<String>(words));
Collections.sort(uniqueWords, new WordFrequencyComparator<String>(wordFrequencyMap));
for (String w : uniqueWords) {
System.out.println("word : " + w + " frequency : " + wordFrequencyMap.get(w));
}
缺少的部分不应该是困难的。