为什么设置插入有序的项目?

时间:2014-08-14 09:25:21

标签: java collections set

实际上Set不是有序的。我只是创建集合并插入数字5,2,10 Wen打印在控制台中,打印为2,5,10

为什么set没有订购?

5 个答案:

答案 0 :(得分:2)

这是因为这会加快查询某个元素是否属于集合的查询。

不同之处在于无法保证此行为。保持为快速查找排序的小集合可能是有益的,但是一旦达到一定数量的元素就切换到基于散列的实现,此时元素将突然按哈希值排序。

答案 1 :(得分:0)

Setinterface,但它有多个实现。 HashSet无法保证您的广告订单(未订购)。 LinkedHashSet保留了广告订单,TreeSet为您提供了排序set(排序集)。

然后您将5,2,10插入HashSet,无法保证订单相同。

答案 2 :(得分:0)

Set只是一个界面,假设您正在谈论HashSet(因为它发生了这种情况),它并没有对它们进行排序。例如:

HashSet<Integer> set = new HashSet<Integer>();
set.add(1);
set.add(16);
System.out.println(set);

输出

[16, 1]

这是因为HashSet使用hashcode函数来计算项目将以类似数组的结构存储的索引。这样,由于hashcode永远不会改变,它可以从正确的索引中提取元素,再次计算hashcode并检查该索引处的单元格。

hashcode函数将大多数类转换为整数:

System.out.println(new Integer(1).hashCode());      # 1
System.out.println(new Integer(1000).hashCode());   # 1000
System.out.println("Hello".hashCode());             # 69609650

每个类都可以定义自己的方式来计算哈希码Integer返回自己。 正如你所看到的那样,数字很快就会变大,我们不希望有一个带有 1000 单元的数组只是为了保存两个整数。 为了避免这个问题,我们可以创建一个包含n元素的数组,然后使用哈希码的剩余部分除以n作为索引。 / p>

例如,如果我们想在 16 元素的数组中找到1000的索引:

System.out.println(new Integer(1000).hashCode() % 16);   # 8

因此我们的字典会知道整数1000位于索引 8 。这就是HashSet的实施方式。

那么,为什么[16, 1]没有订购?这是因为HashSet是使用 16 元素创建的,因为它们在开始时的容量(当没有不同的指定时),并根据需要增长(更多关于此here)。

让我们计算索引,将key = 2key = 9的数据存储在n = 8的字典中:

System.out.println(new Integer(1).hashCode() % 16);   # 1
System.out.println(new Integer(16).hashCode() % 16);  # 0

这意味着包含字典数据的数组将是:

| index | value |
|-------|-------|
|   0   |  16   |
|   1   |   1   |
|   2   |       |
|   3   |       |
|   4   |       |
|   5   |       |
|   6   |       |
|   7   |       |
|   8   |       |
|   9   |       |
|  10   |       |
|  11   |       |
|  12   |       |
|  13   |       |
|  14   |       |
|  15   |       |

对其进行迭代后,订单将是此代表中显示的顺序,因此16将在1之前。

答案 3 :(得分:0)

Set是界面。它仅表示避免集合的重复实体。

HashSet内部使用Hashmap。通常hashmap使用hashcode。所以它不会以有序的方式返回。如果您需要广告订单,则会使用LinkedHashMap

答案 4 :(得分:-1)

Set只是一个界面。订购将取决于实施。例如,TreeSetSet的有序实现。