首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我们需要List来使用Collection.sort()方法进行排序?

问为什么我们需要List来使用Collection.sort()方法进行排序?
EN

Stack Overflow用户
提问于 2020-01-24 20:58:46
回答 2查看 282关注 0票数 1

我正计划从hashmap中分类密钥。我正在使用自定义的排序方法。

下面的代码给出了编译时错误在compareTo()方法中使用Set作为集合

代码语言:javascript
复制
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));

如果我将设置为List,然后进行排序,那么可以很好地运行。

代码语言:javascript
复制
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));

我需要转换为List来对集合排序的原因是什么?为什么我不能用集合来分类呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-27 17:00:42

Set没有更改顺序的API。如果您尝试,您会注意到自己,例如,交换Set的第一个和第二个元素。

此外,如果您可以从外部更改订单,则sets也有自己的合同。

  • HashSet和HashMap的键集根本不维护订单。这是集合的一般假设,如果没有其他契约是specified
  • LinkedHashSet,并且LinkedHashMap的键集将反映插入order
  • TreeSet,而TreeMap的键集使用键的自然顺序或显式指定的比较器的顺序。SortedSet的所有实现都绑定到Comparator或密钥的自然顺序。

为了对某些内容进行排序,您需要一个集合,该集合维护订单,并具有支持更改订单的API。

List是一种自然的候选。还可以对数组进行排序。由于LinkedHashMap反映插入顺序,所以可以通过按所需顺序添加元素来创建具有特定顺序的LinkedHashMap:

代码语言:javascript
复制
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)代替。

或在适用的情况下为比较器使用工厂方法。

代码语言:javascript
复制
List<String> words = new ArrayList<>(map.keySet());
words.sort(Comparator.<String>comparingInt(map::get).reversed()
                     .thenComparing(Comparator.naturalOrder()));
票数 2
EN

Stack Overflow用户

发布于 2020-01-29 09:44:57

根据定义,Set 不是一个有序的集合.

我们不能通过调用集合上的Set方法来对Collections.sort()集合进行排序。

在Java中没有对集合排序的直接支持。若要对集合进行排序,请执行以下步骤:

  • 转换为list .
  • 排序列表使用Collections.sort() API.
  • 转换列表返回到set.

或

我们可以使用set的排序实现。

根据下面的图表,HashSet,LinkedHashSet,和TreeSet是Set的实现。

  • HashSet:Unordered
  • LinkedHashSet:插入order
  • TreeSet:有序(自然顺序即字母、字母数字或chronological)

)

注意:HashSet是大多数情况下使用的默认实现。

​

​

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59903608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档