我计划从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排序?
2条答案
按热度按时间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
eoigrqb62#
一
Set
没有api来更改顺序。你会注意到你自己,如果你尝试,例如,交换的第一和第二个元素的一个Set
.此外,集合有他们自己的关于订单的合同,如果您可以从外部更改订单,则会违反这些合同
HashSet
以及一个HashMap
完全不要维持秩序。如果没有规定其他合同,这是对集合的一般假设LinkedHashSet
以及一个LinkedHashMap
将反映插入顺序TreeSet
以及一个TreeMap
使用键的自然顺序或显式指定的比较器的顺序。的所有实现SortedSet
一定会有Comparator
或者钥匙的自然顺序。为了对某些东西进行排序,您需要一个集合来维护顺序,并有一个支持更改顺序的api。
一
List
他是个天生的候选人。也可以对数组进行排序。自LinkedHashMap
反映插入顺序,可以创建LinkedHashMap
通过按所需顺序添加元素来指定顺序:另外,你的比较仪看起来坏了。术语
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)
相反。或在适用时使用比较器的工厂方法