嗨,我正在学习Java 9的新功能,并且正在阅读新的Collections API。我不确定为什么在从两个JDK实例创建不可变集时会得到随机迭代顺序。
JDK 1: jshell> Set.of("a","b","c")
$96 ==> [a, b, c]
JDK2 : jshell> Set.of("a","b","c")
$68 ==> [a, c, b]
我对List.of()重载没有看到相同的东西。我可以做一些自定义操作,例如更改某些系统属性以保证此处的顺序一致吗?
任意Set
实现没有排序,因此,当迭代由Set
返回的Set.of()
的元素时遇到的任何迭代顺序都是正确的,因此您不应该依赖它。这是一个实现细节,不同的JDK版本可以产生不同的迭代顺序。
如果需要一致的顺序,请不要使用Set
,或使用保证顺序的Set
,例如TreeSet
。
List.of()
具有不同的行为,因为List
具有排序。在List
返回的List.of("a","b","c")
中,“ a”将始终是第一个元素,“ b”将始终是第二个元素,而“ c”将始终是第三个元素。
如已经说明的Eran,未指定Set
的迭代顺序。
为了避免其他程序依赖于迭代顺序,JVM将在启动时创建一个盐,并使用它来随机化其内部Set
和Map
实现的迭代顺序:
/** * 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;
简而言之,他们做了额外的工作来使迭代顺序“随机”,因此,如果人们开始依赖该顺序,事情将会中断。
例如,某些程序确实依赖HashSet
的迭代顺序-这使得现在很难提高HashSet
而又不破坏依赖该顺序的程序。