具有相同值的排序键--> LinkedHashMap

6

我已经用Java编写了一个单词程序,并且列出了单词和频率的列表。结果当前存储在LinkedHashMap中。结果看起来类似于下面这样:

garden-->2
road-->4
street-->5
park-->5
highway-->5

在上面的结果集中,存储在LinkedHashMap中,我应该如何对只有相同频率键进行排序。我们仍然希望保持给定频率的顺序。
结果将类似于:
garden-->2
road-->4
highway-->5
park-->5
street-->5

谢谢您。


data.entrySet().stream().sorted(Comparator.comparing(Entry::getValue).thenComparing(Comparator.comparing(Entry::getKey))).collect(Collectors.toMap(Entry::getKey, Entry::getValue, mergeFunction, LinkedHashMap::new)) - Boris the Spider
2个回答

2

我能够像Boris的建议答案一样完成这个任务。然而,我使用的任何IDE都拒绝推断泛型类型,因此我必须在第一次调用Comparator#comparing时明确指定它们,如下所示:

Map<String, Integer> map = new LinkedHashMap<>();

map.put("garden", 2);
map.put("road", 4);
map.put("street", 5);
map.put("park", 5);
map.put("highway", 5);

map = map.entrySet()
         .stream()
         .sorted(Comparator.<Entry<String, Integer>, Integer>comparing(Entry::getValue)
                           .thenComparing(Comparator.comparing(Entry::getKey)))
         .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (k, v) -> {
             throw new IllegalStateException(String.format("Duplicate Key: %s", k));
         }, LinkedHashMap::new));

System.out.println(map);

上面的代码产生以下输出:

{garden=2,road=4,highway=5,park=5,street=5}

我注意到您希望值按降序排列,但共享值的键按升序排列。以下是几乎相同的解决方案:

map = map.entrySet()
         .stream()
         .sorted(Comparator.<Entry<String, Integer>, Integer>comparing(Map.Entry::getValue).reversed()
                           .thenComparing(Comparator.comparing(Entry::getKey)))
         .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (k, v) -> {
                throw new IllegalStateException(String.format("Duplicate key %s", k));
         }, LinkedHashMap::new));

注意: Entry 是指 java.util.Map.EntryCollectors 是指 java.util.stream.Collectors


1
非常感谢,Collectors 指的是什么? - omi
1
很好的答案。我只能通过创建两个显式比较器(c1,c2)并使用sorted(c1.thenComparing(c2))来解决问题。当你包含泛型时它开始工作。仍然不确定为什么我不能在没有这个的情况下链接.thenComparing()。你有我的投票。 - Ian Mc
@AnujKumar Collectors 指的是 java.util.stream.Collectors - Jacob G.
@AnujKumar 你在使用IDE(Intellij,Eclipse等)吗? 我猜只是某个地方打错了,因为对我来说它完全正常工作。阅读此内容:https://dev59.com/Cl8e5IYBdhLWcg3wfaUy 你可能正在使用Java 7或更低版本进行编译吗? - Jacob G.
1
谢谢Jacob。我觉得现在应该可以了,我会进行一些测试。感谢你的帮助! - omi
显示剩余4条评论

1
如果您正在查找JAVA7或更低版本,以下简单代码可以完成您的工作。
Map<String, Integer> map = new LinkedHashMap<>();

map.put("garden", 2);
map.put("road", 4);
map.put("street", 5);
map.put("park", 5);
map.put("highway", 5);

List<Entry<String, Integer>> list = new ArrayList<>();
list.addAll(map.entrySet());

Collections.sort(list, new Comparator<Entry<String, Integer>>() {

    @Override
    public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
        return o1.getValue()-o2.getValue() != 0 ?  o1.getValue()-o2.getValue() : o1.getKey().compareTo(o2.getKey());
    }
});
System.out.println(list);

输出:-

[花园=2,道路=4,高速公路=5,公园=5,街道=5]

我猜,Jacob实现的代码在这里执行相同的工作。


谢谢大家的回复,这对我非常有帮助,上面提供的解决方案都起作用了!你们真是太棒了!!! - omi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接