我正计划从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));如果我将设置为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));我需要转换为List来对集合排序的原因是什么?为什么我不能用集合来分类呢?
发布于 2020-01-27 17:00:42
Set没有更改顺序的API。如果您尝试,您会注意到自己,例如,交换Set的第一个和第二个元素。
此外,如果您可以从外部更改订单,则sets也有自己的合同。
HashSet和HashMap的键集根本不维护订单。这是集合的一般假设,如果没有其他契约是specifiedLinkedHashSet,并且LinkedHashMap的键集将反映插入orderTreeSet,而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()));发布于 2020-01-29 09:44:57
根据定义,Set 不是一个有序的集合.
我们不能通过调用集合上的Set方法来对Collections.sort()集合进行排序。
在Java中没有对集合排序的直接支持。若要对集合进行排序,请执行以下步骤:
Collections.sort() API.或
我们可以使用set的排序实现。
根据下面的图表,HashSet,LinkedHashSet,和TreeSet是Set的实现。
HashSet:UnorderedLinkedHashSet:插入orderTreeSet:有序(自然顺序即字母、字母数字或chronological))
注意:HashSet是大多数情况下使用的默认实现。

图表参考:https://dzone.com/articles/an-introduction-to-the-java-collections-framework
https://stackoverflow.com/questions/59903608
复制相似问题