这是java.util.stream.Collectors
类的toSet()
方法的实现:使用Java 8 Streams API时,可以在调用Collectors.toSet()时依赖于sort()吗?
public static <T>
Collector<T, ?, Set<T>> toSet() {
return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
(left, right) -> { left.addAll(right); return left; },
CH_UNORDERED_ID);
}
我们可以看到,它采用了HashSet
并调用add
。从HashSet
documentation,“它不保证为向集合的迭代顺序;特别是它不保证该顺序将随着时间保持不变。”
在下面的代码,的String
一个List
被流传输,分类收集到Set
:
public static void main(String[] args) {
Set<String> strings = Arrays.asList("c", "a", "b")
.stream()
.sorted()
.collect(Collectors.toSet());
System.out.println(strings.getClass());
System.out.println(strings);
}
这提供了输出:
class java.util.HashSet
[a, b, c]
的输出是排序的。我认为这里发生的事情是,尽管HashSet
文档提供的合同规定排序不是它提供的,但是实现恰巧按顺序添加。我想这可能会改变将来的版本/ JVM之间的差异,而更明智的做法是做类似Collectors.toCollection(TreeSet::new)
的事情。
能sorted()
调用Collectors.toSet()
时不能依赖?
此外,究竟是什么“它不保证该顺序将随着时间保持不变”呢? (我想add
,remove
,底层数组的大小调整?)
“调用Collectors.toSet()时可以依赖于排序吗()?”没有[例如](https://ideone.com/NPVQT8)。 –
如果需要在不同的JVM实例(和/或不同的JVM发布周期)内维护任何顺序,则必须使用'LinkedHashSet'或类似的类来确保**确定性的**顺序。原因已在答案中给出。 – Zabuza