[英]Does Collectors.toSet() always return a HashSet ? What is the contract?
Javadoc 说
返回一个将输入元素累积到新 Set 中的收集器。 返回的 Set 的类型、可变性、可序列化性或线程安全性没有任何保证; 如果需要对返回的 Set 进行更多控制,请使用 toCollection(java.util.function.Supplier)。
所以Collectors.toCollection(HashSet::new)
似乎是避免问题的好主意( SO question )。
我的问题是, toSet()
我所能,除了HashSet
之外,我无法从toSet()
返回任何其他内容
这是我使用的代码:
public static void main(String[] args) {
List<Integer> l = Arrays.asList(1,2,3);
for (int i = 0 ; i++<1_000_000;){
Class clazz = l.stream().collect(Collectors.toSet()).getClass();
if (!clazz.equals(HashSet.class)) {
System.out.println("Not a HashSet");
}
}
}
那么,为什么 Javadoc 声明不能保证,而实际上,有...
JavaDoc表示无法保证 ,但这并不妨碍任何特定实现始终返回特定类型的集合。 这只是设计师说他们不想限制未来的实现可以做什么。 它没有说明当前的实现实际上做了什么。
换句话说,您已经发现了实现定义的行为(总是返回一个HashSet
),但如果依靠它,您将来可能会遇到问题。
当前OpenJDK的实现(以及AFAIK,Oracle也是如此)确实总是返回一个HashSet
- 但是不能保证这一点。 如果你以某种方式假设Collectors.toSet()
将返回一个HashSet
(例如,明确地向下转换它),JDK的未来版本可能会很好地改变这种行为并打破你的代码。
Collectors::toSet
返回的Set
类型是一个实现细节。 您不应该依赖实现细节在将来的版本中保持不变。 现在,他们使用HashSet
,但将来他们可能想要使用不同类型的集合。
例如,未来的Java版本可能会返回专门的不可变集合实现,这些实现对于读取更有效,并且比当前的HashSet
实现消耗更少的内存,而HashSet
实际上只是HashMap
一个包装器。 瓦尔哈拉项目最终可能会导致这种优化。
他们甚至可能选择基于数据量返回不同的集合类型,例如,如果事先知道将返回零个或一个元素,则为空或单个集合。
因此,通过根据当前实施提供的保证数量少于可能,他们为未来的改进敞开大门。
我想你要找的是: Collectors.toCollection(LinkedHashSet::new)
怎么样
Set<String> tree =s.stream().collect(Collectors.toCollection(TreeSet::new));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.