按值排序Hashmap,然后按字母顺序排序

时间:2015-10-23 23:56:08

标签: java sorting hashmap comparator

我正在创建一个单词频率程序,它可以很好地计算单词。我使用hashmap存储单词频率。我使用单词作为键,计数作为值。但是,我想首先用字频率对hashMap进行排序,然后按照字母顺序对键进行排序:

it - 2
of - 2
the - 2
times- 2 
was - 2  
best- 1 
worst - 1 

我猜我需要一个自定义Comparator,但我不知道如何构建它。请问有什么建议吗?

2 个答案:

答案 0 :(得分:2)

看到您只需要进行一次此类操作,我建议您创建一个Result对象,其中包含您的StringInteger值并实现{{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

  

......此课程不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

您必须将其置于不同的结构中,以保持您想要的顺序。

根据您提供的内容,您的订单似乎有一些标准:

  1. Map.Entry 排序,按降序排列
  2. Map.Entry 按升序排序
  3. 您可以使用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