Java 中的集合到底什么时候发生变异?

When exactly do sets in Java mutate?

我们都知道未排序的 Set 不能保证顺序,它们可以变异和改变。

我的问题是,这种情况多久发生一次,是什么原因造成的?

如果我偶尔从 Set 中获取第一个元素,它会可靠地伪随机吗?

例如,在 HashSet 中添加新元素可以重新排序之前添加的所有元素。当你达到容量时可能会发生(看看 java 来源中的这个地方:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/HashMap.java#772

在 TreeSet 中,您可能希望使用 compareTo 添加新元素,将此元素放在集合的中间并更改顺序。

要记住的最重要的事情是 Set 不是 Java 中的实现。它只是一个界面。 its documentation 中唯一提到的订购只是说明它不做任何保证。

The elements are returned in no particular order (unless this set is an instance of some class that provides a guarantee).

这意味着您不能假设 Set 的顺序,除非您知道实现是什么。实施者可以自由地做任何事情,从保持排序到拥有后台线程 运行 每隔几秒随机化一次顺序。

如果您查看各种 Set 的 Java 文档,您会发现保证各不相同,从 LinkedHashSet

[The iteration order] is the order in which elements were inserted into the set

TreeSet

The elements are ordered using their natural ordering

HashSet

makes no guarantees as to the iteration order of the set

在这些描述的范围内,Sets 可以根据自己的需要自由订购。这意味着定义明确的那些只需要在某些事情(例如插入或删除)导致他们需要新的订单来履行他们的合同时重新排序。没有保证的那些不会承诺任何东西,但大概有某种形式的内部结构允许快速查找,这将 a) 可能保持相当稳定,并且 b) 很可能优先考虑某些项目而不是其他项目。他们也可能不会,但你不能以任何一种方式做出假设。

My question is, how often does this happen, and what causes it?

只要应用程序调用变异操作,变异就会发生;例如添加、删除等。它不会自发发生。

(多久一次?当然是你调用变异方法的频率。)

If I were to occasionally grab the first element from a Set, would it be reliably pseudo-random?

没有。它很可能是 "randomness".

的不良来源

虽然这取决于您使用的 Set class,但对 Set 的突变通常不会显着改变元素的迭代顺序......或者在许多情况下,根本。在绝大多数情况下,"random" 对集合的小改动不会改变作为第一个元素返回的内容。