为什么我们需要使用Collection.sort()方法对List进行排序? [英] Why do we need List to sort using Collection.sort() method?
问题描述
我正计划从哈希图中对键进行排序.我正在使用自定义的排序方法.
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
-
HashSet
和HashMap
的键集根本不维持顺序.如果未指定其他合同,这是集合的一般假设 -
LinkedHashSet
和LinkedHashMap
的键集将反映插入顺序 -
TreeSet
和TreeMap
的键集使用键的自然顺序或显式指定的比较器的顺序.SortedSet
的所有实现都绑定到Comparator
或键的自然顺序.
HashSet
and the key set of aHashMap
do not maintain an order at all. This is the general assumption for sets if no other contract is specifiedLinkedHashSet
and the key set of aLinkedHashMap
will reflect the insertion orderTreeSet
and the key set of aTreeMap
use the natural order of the keys or the order of an explicitly specified comparator. All implementations ofSortedSet
are bound to aComparator
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屋!