Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Collectors.toSet() always return a HashSet ? What is the contract?

Javadoc says

Returns a Collector that accumulates the input elements into a new Set. There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned; if more control over the returned Set is required, use toCollection(java.util.function.Supplier).

So Collectors.toCollection(HashSet::new) seems like a good idea to avoid problems here (SO question).

My problem is, as hard as I've tried, I can not get anything else returned from toSet() than a HashSet

Here is the code I used :

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");
        }
    }
}

Why then, does the Javadoc state that there is no guarantee when in fact, there is...

like image 304
Yassin Hajaj Avatar asked May 05 '16 16:05

Yassin Hajaj


2 Answers

The JavaDoc states there is no guarantee, but that doesn't prevent any specific implementation from always returning a specific type of set. This is just the designers saying they don't want to limit what a future implementation can do. It says nothing about what the current implementation actually does.

In other words, you have discovered implementation defined behavior (always return a HashSet), but if you count on that you may have problems in the future.

like image 192
Jim Garrison Avatar answered Oct 25 '22 23:10

Jim Garrison


The type of Set returned by Collectors::toSet is an implementation detail. You should not rely on implementation details to remain the same in future versions. Right now, they use a HashSet, but in the future they might want to use a different kind of set.

like image 27
Jeffrey Avatar answered Oct 26 '22 01:10

Jeffrey