为什么这段代码会按顺序打印出[1,2,3]?

Why does this code print out [1,2,3] in order?

对于这个问题,为什么它以特定顺序打印出 [1,2,3] 因为我认为 HashSets 没有排序,我会认为它打印出 [1,2,3] in 任何订单。我知道它消除了重复项。是不是因为这道题是从list -> HashSet -> list转换过来的?

import java.util.*;

class Try
{
    public static void main(String args[]) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(3);
        list.add(3);
        list.add(3);
        list.add(2);
        list.add(2);
        list.add(1);
        Set<Integer> set = new HashSet<Integer>(list);
        List<Integer> list_1 = new ArrayList<Integer>(set);
        System.out.println(list_1);
    }
}

哈希集是无序的,这意味着当调用 new ArrayList<Integer>(set) 时,Java 编译器不保证结果列表是有序的。在您的情况下,碰巧它是按升序排列的,使用不同的 java 编译器编译,甚至在不同时间使用相同的 java 编译器可能会导致不同的排序。

例如,将您的代码稍微编辑为:

class Try {
  public static void main(final String args[]) {
    final List<Integer> list = new ArrayList<Integer>();
    for (int i = 10; i > -10; i--) {
      list.add(i);
    }
    final Set<Integer> set = new HashSet<Integer>(list);
    final List<Integer> list_1 = new ArrayList<Integer>(set);
    System.out.println(list_1);
  }
}

我的机器上的输出结果为:

[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, 8, -9, 9, 10]

显然这是不对的。

因此,当将哈希集转换为列表时,假设结果具有某种顺序是不安全的

数字按其自然顺序排列有点偶然,但 List 元素的顺序由 Set 迭代其元素的顺序决定。

HashSet 没有定义迭代其元素的顺序,但它受每个元素的哈希码的影响。在 Integer 个对象的情况下,hashCode() 方法 returns 它自己的值。哈希码决定元素存储在哪个桶中,由于 HashSets 开始有 16 个桶,因此对值 1、2 和 3 的操作 i % 16 的剩余部分只是 1、2 和 3,所以这就是桶他们会进去的。对元素的迭代是一次完成的。每个桶中只有一个元素 - 桶 1 中有元素 1,依此类推。这就是它们按顺序排列的原因。

对于较大数量的整数,纯巧合将不适用,元素将按伪随机顺序排列,但实际上由每个元素的哈希码、当前桶数、精确度用于选择桶的算法以及最后添加元素的顺序 - 每个桶中都有一个元素列表(如果列表变得太大,则为 TreeSet)。

哈希集是无序的,这意味着当调用 new ArrayList(num) 时,Java 编译器不保证结果列表是有序的。在您的情况下,碰巧它是按升序排列的,使用不同的 java 编译器编译,甚至在不同时间使用相同的 java 编译器可能会导致不同的排序。