Java 集合中排序是如何工作的

问题描述 投票:0回答:2

使用我创建的这个方法,我不明白为什么它会返回一个已经按顺序排列的整数列表,而在java文档上,集合不应该在没有我告诉它的情况下对元素进行排序。

此方法的作用:该方法给出一个字符串列表作为输入,返回列表中字符串的长度集合

public static Set<Integer> test(List<String> inputList){
    return inputList.stream()
        .map(String::length)
        .collect(Collectors.toSet());
}

主要是这样做

List<String> p2 = List.of("aaaa", "aa", "aaa", "a");
Set<Integer> r2 = test(p2);
System.out.println(r2);

它返回此列表:

[1, 2, 3, 4]
,当我预期时
[4, 2, 3, 1]

java sorting stream set
2个回答
1
投票

Set
一般没有任何可以信赖的订单。

Set
的目的是拥有一个不允许重复的元素集合,而不考虑元素的顺序。您基本上可以添加、删除元素并检查元素是否存在。

如果您想要一个带索引的数据结构,您可能应该使用

List
。 列表已编入索引并有顺序。

public static List<Integer> test(List<String> inputList){
    return inputList.stream()
        .map(String::length)
        .collect(Collectors.toList());
}

但是,有特定的

Set
实现可以保证特定的顺序。

例如,如果您想要一个仅保留顺序的

Set
,您可能需要考虑使用
LinkedHashSet
,它本质上是一个保持插入顺序的
HashSet

public static Set<Integer> test(List<String> inputList){
    return inputList.stream()
        .map(String::length)
        .collect(Collectors.toCollection(LinkedHashSet::new));
}

如果您希望以某种方式对集合进行排序,您还可以使用排序集实现,例如

TreeSet

public static Set<Integer> test(List<String> inputList){
    return inputList.stream()
        .map(String::length)
        .collect(Collectors.toCollection(()->new TreeSet<>(Comparator.naturalOrder().reversed())));
}

在上面的代码中,

Comparator.naturalOrder().reversed()
创建了一个
Comparator
,用于配置
Set
应排序的元素顺序。
Comparator.naturalOrder()
指的是按“自然顺序”进行比较的
Comparator
升序为
Integer
s 的元素。然后,
reversed()
用于反转顺序(降序
Integer
)。


0
投票

您的集合按排序顺序纯属巧合,并且基于

hash values
、集合的
capacity
以及
load factor
。所有这些都在 HashSet 的 JavaDoc 中提到,但更详细地解释了 HashMap

考虑以下因素:

List<Integer> list = List.of(13,12,11,10,9,8,7,6,5,4,3,2,1);
Set<Integer> set = new HashSet<>();
set.addAll(list);
System.out.println(set);

打印

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

现在调整尺寸和负载能力。

set = new HashSet<>(1,10f);
set.addAll(list);
System.out.println(set);

打印

[12, 10, 8, 6, 4, 2, 13, 11, 9, 7, 5, 3, 1]

如果你想保留插入顺序,请使用 LinkedHashSet

set = new LinkedHashSet<>();
set.addAll(list);
System.out.println(set);

打印

[13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

最重要的是,除了一些特殊的实现,包括上面没有讨论的TreeSet

Sets
本质上是无序的,它们的任何外观纯粹是巧合。

© www.soinside.com 2019 - 2024. All rights reserved.