哈希集的迭代顺序

2022-09-01 21:53:47

如果添加到 java.util.HashSet 中的每个对象都以确定性方式实现 Object.equals() 和 Object.hashCode(),那么对于添加的每个相同的元素集,HashSet 上的迭代顺序是否保证相同,无论它们以何种顺序添加?

奖励问题:如果广告订单也相同怎么办?

(假设 Sun JDK6 具有相同的 HashSet 初始化。

编辑:我原来的问题并不明确。这不是关于HashSet的总契约,而是Sun在JDK6中对HashSet的实现作为确定性的保证。它本质上是非确定性的吗?什么会影响其迭代器使用的顺序?


答案 1

绝对不行。

每当发生存储桶冲突时,广告订单都会直接影响迭代顺序:

当两个元素最终位于同一个存储桶中时,插入的第一个元素也将是在迭代期间返回的第一个元素,至少如果冲突处理和迭代的实现很简单(Sun中的那个是)java.util.HashMap


答案 2

对于这样的事情,没有“官方”保证。我想说的是,对于以相同方式初始化的相同HashSet实现的实例,这很可能是正确的。但是,例如,我看到Java 5和6之间的迭代顺序不同。

此外,由于重新哈希处理,对于同一哈希集实现的实例,它可能有所不同,这些实例以不同的大小初始化。即,如果您有100个元素和两个集合,一个初始化为大于100的大小,另一个具有更小的大小,则第二个元素将被重新分配,其元素在填充时会重新哈希多次。这可能会导致映射到同一存储桶的元素以不同的顺序添加(从而迭代)。

在Java4及更高版本中,您有LinkedHashSet,它保证迭代顺序将是其元素插入的顺序。