Debapriya Biswas
Debapriya Biswas

Reputation: 1339

Random Iteration order from Set.of(...)

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

Answers (2)

Johannes Kuhn
Johannes Kuhn

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;

Source

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

Eran
Eran

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 Sets, or use Sets that guarantee order, such as TreeSet.

List.of() has a different behavior, since Lists 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

Related Questions