【发布时间】:2017-10-20 21:31:53
【问题描述】:
这是java.util.stream.Collectors类的toSet()方法的实现:
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。来自HashSetdocumentation,“它不保证集合的迭代顺序;特别是,它不保证顺序会随着时间的推移保持不变。”
在以下代码中,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) 的操作。
调用Collectors.toSet()时可以依赖sorted()吗?
此外,“它不能保证订单会随着时间的推移保持不变”到底是什么意思? (我想add,remove,底层数组的大小调整?)
【问题讨论】:
-
"调用 Collectors.toSet() 时可以依赖 sorted() 吗?"编号For example.
-
如果需要在不同的 JVM 实例(和/或不同的 JVM 发布周期)中维护任何顺序,则必须使用
LinkedHashSet或类似的类来确保 确定性 顺序.原因已经在答案中给出。
标签: java collections java-8 java-stream