[英]Sorting HashMap by value using a TreeMap and Comparator
我使用以下代碼創建一個哈希圖,然后使用樹圖和比較器對哈希圖中的值進行排序。 但是,輸出是相當意外的。 因此,任何關於我做錯事的想法都會有所幫助
碼
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
請檢查的JavaDoc的compare
:你不回更大的價值,但-1
為o1
< o2
, 0
為o1
= o2
和1
對o1
> o2
。 所以你可以這樣寫:
@Override
public int compare(Object o1, Object o2) {
return ((Integer) map.get(o1)).compareTo((Integer) map.get(o2);
}
TreeMap
的Java文檔明確指出:
基於紅黑樹的NavigableMap實現。 該地圖是根據其鍵的自然順序排序的
我們不應該通過使用TreeMap
按值排序來違反此規則。
但是,要按值排序,我們可以執行以下操作:
map
條目的LinkedList
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; } }
參考: 按值對地圖排序
您在做什么實際上是濫用工具。
我相信您需要做的是:
當然,您仍然可以使用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
答案均不符合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));
}
缺少的部分應該沒有什么困難。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.