Collectors.toSet()总是返回一个HashSet吗?合同是什么?

Yas*_*jaj 9 java java-8 collectors

Javadoc说

返回将输入元素累积到新Set中的Collector.返回的Set的类型,可变性,可序列化或线程安全性无法保证; 如果需要更多地控制返回的Set,请使用toCollection(java.util.function.Supplier).

所以Collectors.toCollection(HashSet::new)在这里避免问题似乎是一个好主意(问题).

我的问题是,很难,因为我已经试过,我不能得到任何来自其他返回toSet()HashSet

这是我使用的代码:

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

那么,为什么Javadoc说实际上没有保证,有......

Jim*_*son 14

JavaDoc表示无法保证,但这并不妨碍任何特定实现始终返回特定类型的集合.这只是设计师说他们不想限制未来的实现可以做什么.它没有说明当前的实现实际上做了什么.

换句话说,您已经发现了实现定义的行为(总是返回一个HashSet),但如果依靠它,您将来可能会遇到问题.


Mur*_*nik 5

当前的OpenJDK实现(以及AFAIK,Oracle也是如此)确实总是返回HashSet-,但不能保证这一点。JDK的未来发行版很可能会改变这种行为,并且如果您以某种方式假定Collectors.toSet()它将返回一个HashSet(例如,显式向下转换),则会破坏您的代码。