【发布时间】:2021-08-31 16:36:31
【问题描述】:
我有以下代码
public static void main(String[] args) {
System.out.println("HashSet " + genSet());
System.out.println("Immutable Set " + genImmutableSet());
}
private static Set<String> genSet() {
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");
set.add("D");
return set;
}
private static Set<String> genImmutableSet() {
return Set.of("A", "B", "C", "D");
}
HashSet 的键总是 [A, B, C, D]
Set.of 键有时会被打乱。 我实际上已经多次运行我的代码并得到了我看到的结果。
这是 5 次运行的结果:
Run1:
HashSet [A, B, C, D]
Immutable Set [A, B, C, D]
Run2:
HashSet [A, B, C, D]
Immutable Set [C, D, A, B]
Run3:
HashSet [A, B, C, D]
Immutable Set [A, B, C, D]
Run4:
HashSet [A, B, C, D]
Immutable Set [D, C, B, A]
Run5:
HashSet [A, B, C, D]
Immutable Set [D, C, B, A]
此外,我检查了相关类的实际源代码。
HashSet 依赖于 HashMap 从而使用它的迭代器
Set.of 使用 ImmutableCollections 来实例化它的 Set 并且迭代器可以追溯到here
正如您所看到的,与其他迭代器不同,此迭代器选择基于基于 nano 计算的 SALT 的起始索引,方法如下。
long nt = System.nanoTime();
SALT = (int)((nt >>> 32) ^ nt);
我哪里错了?
【问题讨论】:
-
它实际上并没有保留插入顺序。尝试改变它,你会看到。
Set不保证订单。不过,有些实现确实有特定的顺序。 -
我知道 Set 不保证订单。我想知道为什么使用相同的输入会看到不同的输出。