为什么我们需要使用Collection.sort()方法对List进行排序? [英] Why do we need List to sort using Collection.sort() method?

查看:576
本文介绍了为什么我们需要使用Collection.sort()方法对List进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正计划从哈希图中对键进行排序.我正在使用自定义的排序方法.

I am planning to sort keys from a hashmap. I am using a customized sort method.

下面的代码给我 compareTo()方法的编译时错误,其中我正在使用 Set 作为Collection

Following code gives me compile-time error on compareTo() method where I am using Set as Collection

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));

如果我将设置为列表进行转换,然后进行排序,那么一切都可以正常运行.

If I convert Set to List and then sort then everything works fine.

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来对集合进行排序的原因是什么?为什么我不能使用Set排序?

What is the reason that I need to convert to List to sort the collection? Why can't I sort using Set?

推荐答案

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

A Set has no API to change the order. You will notice yourself if you try, e.g. to swap the first and second elements of a Set.

此外,集合具有自己的合同,关于合同的顺序,如果您可以从外部更改,则会被违反

Further, sets have their own contracts regarding the order which would be violated if you could change it from the outside

  • HashSetHashMap的键集根本不维持顺序.如果未指定其他合同,这是集合的一般假设
  • LinkedHashSetLinkedHashMap的键集将反映插入顺序
  • TreeSetTreeMap的键集使用键的自然顺序或显式指定的比较器的顺序. SortedSet的所有实现都绑定到Comparator或键的自然顺序.
  • HashSet and the key set of a HashMap do not maintain an order at all. This is the general assumption for sets if no other contract is specified
  • LinkedHashSet and the key set of a LinkedHashMap will reflect the insertion order
  • TreeSet and the key set of a TreeMap use the natural order of the keys or the order of an explicitly specified comparator. All implementations of SortedSet are bound to a Comparator or the natural order of the keys.

要对某物进行排序,您需要一个用于维护订单的集合,并具有支持更改订单的API.

In order to sort something you need a collection which maintains an order and has an API supporting to alter the order.

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

A List is a natural candidate. You can also sort arrays. Since LinkedHashMap reflects the insertion order, you can create a LinkedHashMap with a specific order by adding the elements in the desired order:

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)比较盒装对象的引用.

Besides, your comparator looks broken. The term map.get(b) - map.get(a) indicates that the values are numerical, in the examples above I assumed Integer, but map.get(a) == map.get(b) compares the references of the boxed objects.

Integer的情况下,差异map.get(b) - map.get(a)可能溢出.您应该改用Integer.compare(map.get(b), map.get(a).

And in case of Integer, the difference map.get(b) - map.get(a) can overflow. You should use Integer.compare(map.get(b), map.get(a) instead.

或在适用时将工厂方法用于比较器

Or use the factory methods for comparators whenever applicable

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

这篇关于为什么我们需要使用Collection.sort()方法对List进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆