我正在创建一个单词频率程序,它可以很好地计算单词。我使用hashmap存储单词频率。我使用单词作为键,计数作为值。但是,我想首先用字频率对hashMap进行排序,然后按照字母顺序对键进行排序:
it - 2
of - 2
the - 2
times- 2
was - 2
best- 1
worst - 1
我猜我需要一个自定义Comparator,但我不知道如何构建它。请问有什么建议吗?
答案 0 :(得分:2)
看到您只需要进行一次此类操作,我建议您创建一个Result
对象,其中包含您的String
和Integer
值并实现{{1 (保持密钥相同)。当您需要对结果进行排序时,只需在Comparable
上调用values()
,然后对其进行排序。
Main.java
HashMap
Result.java
import java.util.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
HashMap<String, Result> hm = new HashMap<String, Result>();
addTo(hm, "to");
addTo(hm, "be");
addTo(hm, "or");
addTo(hm, "not");
addTo(hm, "to");
addTo(hm, "be");
List<Result> results = new ArrayList(hm.values());
Collections.sort(results);
for(Result result : results)
{
System.out.println(result.getValue() + " - " +result.getCount());
}
}
public static void addTo(HashMap<String, Result> hm, String entry)
{
if(! hm.containsKey(entry))
{
Result result = new Result(entry);
hm.put(entry, new Result(entry));
}
hm.get(entry).increment();
}
}
答案 1 :(得分:2)
您无法按Javadoc中所述的那样排序HashMap
:
......此课程不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。
您必须将其置于不同的结构中,以保持您想要的顺序。
根据您提供的内容,您的订单似乎有一些标准:
Map.Entry
值排序,按降序排列Map.Entry
键按升序排序您可以使用Stream
API以及Comparator
中有用的Map.Entry
。
final HashMap<String, Integer> map = new HashMap<>();
map.put("it", 2);
map.put("of", 2);
map.put("the", 2);
map.put("times", 2);
map.put("was", 2);
map.put("best", 1);
map.put("worst", 1);
System.out.println("No Guaranteed Order:");
map.entrySet().stream()
.forEach(System.out::println);
System.out.println();
System.out.println("With Ordering:");
map.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue()
.reversed()
.thenComparing(Map.Entry.comparingByKey()))
.forEach(System.out::println);
输出:
No Guaranteed Order:
the=2
times=2
of=2
was=2
best=1
worst=1
it=2
With Ordering:
it=2
of=2
the=2
times=2
was=2
best=1
worst=1