Yassin Hajaj Yassin Hajaj - 6 months ago 53
Java Question

Collectors.toSet() returns always a HashSet ? Why 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...

Answer

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.

Comments