每个 Java 文档都说 Set 是无序数据结构。 但是当我们尝试这样的实验时:
public class SetTest {
@Test
public void testIterationsOverSet() {
Set<Integer> s = new HashSet<>();
for (int i = 0; i < 10; i++) {
s.add(i);
System.out.println(Arrays.toString(s.toArray()));
}
Set<Integer> s2 = new LinkedHashSet<>(s);
Set<Integer> s3 = new TreeSet<>(s2);
printSet(s, "HashSet");
printSet(s2, "LinkedHashSet");
printSet(s3, "TreeSet");
}
private void printSet(Set<Integer> set, String msg) {
System.out.println("\n"+msg);
Iterator<Integer> itr = set.iterator();
while (itr.hasNext()) {
System.out.print(itr.next());
}
System.out.println();
}
}
我们将得到如下输出:
[0]
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
HashSet
0123456789
LinkedHashSet
0123456789
TreeSet
0123456789
各种集合的顺序是上面输出中的顺序。我有一个假设,每次我们通过添加新元素来更改 Set 时,我们都会崩溃,我们会更改顺序,但所有内容似乎都是在 Set 内部排序的,元素在添加时存储。
所以实际上,据说顺序是不能保证的,上面的例子是正确的,一切都按预期进行。
但问题是,在什么情况下我们可以打破 Set 内部的顺序?
最佳答案
哈希集不会对您插入的数字进行排序,但它恰好在这种特定情况下保留插入顺序,因为您要插入从 0 开始的一组连续数字。纯属偶然,这组数字最终没有被打乱。
原因是整数的哈希码是整数本身,哈希码直接映射到 HashMap 内部数组中的索引。 0 插入到索引 0 处,1 插入到索引 1 处,2 插入到索引 2 处,依此类推。当您插入连续的小整数时,您实际上是在测试最简单的可能场景,其中 HashMap 的行为实际上是可以预测的。
尝试更复杂的场景:代替0-9,插入100-109;或 100-200,步长为 10;或 200-100,步长为 -10;或一组具有不同大小间隙和顺序的不同数字,例如 {100, 2, 2222, -63, 72};等等
此外,看看 HashSet<String>
会发生什么与 HashSet<Integer>
相比。我预计,您会发现字符串的排序非常随意,而且很少按顺序排列。
关于java - Set 的内部顺序怎么会被破坏呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59552418/