为什么我们需要list来使用collection.sort()方法进行排序?

qv7cva1a  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(435)

我计划从hashmap中对密钥进行排序。我使用的是定制的排序方法。
下面的代码给出了compareto()方法的编译时错误,我使用set作为集合

Set<String> set = map.keySet();
Collections.sort(set, (a, b) -> map.get(a) == map.get(b) ?  a.compareTo(b) : map.get(b) - map.get(a));

如果我将set转换为list,然后排序,那么一切都正常。

List<String> words = new ArrayList<>(map.keySet());
Collections.sort(words, (a, b) -> map.get(a) == map.get(b) ?  a.compareTo(b) : map.get(b) - map.get(a));

我需要转换为列表以对集合排序的原因是什么?为什么我不能用set排序?

q3aa0525

q3aa05251#

根据java的定义, Set 不是有序集合。
我们无法对java进行排序 Set 通过调用收集 Collections.sort() 集合上的方法。
在java中没有对集合排序的直接支持。要对集合进行排序,请执行以下步骤:
将集合转换为列表。
排序列表使用 Collections.sort() 应用程序编程接口。
将列表转换回集合。

我们可以使用set的排序实现。
按下图 HashSet , LinkedHashSet ,和 TreeSet 是set的实现。 HashSet :无序 LinkedHashSet :插入顺序 TreeSet :有序(自然顺序,即字母、字母数字或时间顺序)
注: HashSet 是大多数情况下使用的默认实现。

图表参考:https://dzone.com/articles/an-introduction-to-the-java-collections-framework

eoigrqb6

eoigrqb62#

Set 没有api来更改顺序。你会注意到你自己,如果你尝试,例如,交换的第一和第二个元素的一个 Set .
此外,集合有他们自己的关于订单的合同,如果您可以从外部更改订单,则会违反这些合同 HashSet 以及一个 HashMap 完全不要维持秩序。如果没有规定其他合同,这是对集合的一般假设 LinkedHashSet 以及一个 LinkedHashMap 将反映插入顺序 TreeSet 以及一个 TreeMap 使用键的自然顺序或显式指定的比较器的顺序。的所有实现 SortedSet 一定会有 Comparator 或者钥匙的自然顺序。
为了对某些东西进行排序,您需要一个集合来维护顺序,并有一个支持更改顺序的api。
List 他是个天生的候选人。也可以对数组进行排序。自 LinkedHashMap 反映插入顺序,可以创建 LinkedHashMap 通过按所需顺序添加元素来指定顺序:

map = map.entrySet().stream()
    .sorted(Map.Entry.<String,Integer>comparingByValue().reversed()
                     .thenComparing(Map.Entry::getKey))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                              (a,b)->b, LinkedHashMap::new));

另外,你的比较仪看起来坏了。术语 map.get(b) - map.get(a) 表示值是数字的,在上面的示例中我假设 Integer ,但是 map.get(a) == map.get(b) 比较装箱对象的引用。
如果是 Integer ,区别 map.get(b) - map.get(a) 可能会溢出。你应该使用 Integer.compare(map.get(b), map.get(a) 相反。
或在适用时使用比较器的工厂方法

List<String> words = new ArrayList<>(map.keySet());
words.sort(Comparator.<String>comparingInt(map::get).reversed()
                     .thenComparing(Comparator.naturalOrder()));

相关问题