This is an implementation of the java.util.stream.Collectors class toSet() method:
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); }
As we can see, it uses a HashSet and calls add . From the HashSet documentation : "It does not give any guarantees regarding the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time."
In the following code, a List of String is passed, sorted, and assembled in 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); }
This provides a conclusion:
class java.util.HashSet
[a, b, c]
The result is sorted. I think what is happening here is that although the contract provided by the HashSet documentation indicates that the order is not what it provides, the implementation takes place to add to the order. I believe that this may change in future versions / vary between the JVM and that a more reasonable approach would be to do something like Collectors.toCollection(TreeSet::new) .
Is it possible to use sorted() when calling Collectors.toSet() ?
In addition, what does it mean "does not guarantee that order will remain constant over time" does it mean? (I suppose add , remove , resizing the underlying array?)