Reputation: 1339
Hi I am learning the new features of Java 9 and was reading new Collections API's . I am not sure why I am getting random iteration order while creating an immutable set from two instances of JDK .
JDK 1: jshell> Set.of("a","b","c")
$96 ==> [a, b, c]
JDK2 : jshell> Set.of("a","b","c")
$68 ==> [a, c, b]
I don't see the same for List.of() overloads.Can I do some customisation like changing some system properties to guarantee a consistent ordering here ?
Upvotes: 1
Views: 402
Reputation: 15163
As Eran already explained, the iteration order of a Set
is not specified.
To avoid that other programs rely on the iteration order, the JVM will create a salt at startup and use that to randomize the iteration order of their internal Set
and Map
implementations:
/** * A "salt" value used for randomizing iteration order. This is initialized once * and stays constant for the lifetime of the JVM. It need not be truly random, but * it needs to vary sufficiently from one run to the next so that iteration order * will vary between JVM runs. */ private static final long SALT32L;
In short: They did additional work to make the iteration order "random", so things will break if people start to rely on the order.
And some programs do rely on the iteration order of HashSet
for example - which makes it hard to improve HashSet
now without breaking programs that rely on the order.
Upvotes: 4
Reputation: 393781
Arbitrary Set
implementations have no ordering, so any iteration order encountered when iterating over the elements of a Set
returned by Set.of()
is correct, and you shouldn't rely on it. It's an implementation detail, and different JDK versions can produce different iteration orders.
If you require a consistent ordering, either don't use Set
s, or use Set
s that guarantee order, such as TreeSet
.
List.of()
has a different behavior, since List
s have ordering. In the List
returned by List.of("a","b","c")
, "a" will always be the first element, "b" the second element and "c" the third.
Upvotes: 4