hashSet 中元素的顺序
Order of element in hashSet
我在 java 1.7 文档中读到 "It makes no guarantees as to the iteration order of the set"。
这是什么意思?
我创建了一个 HashSet 打印它的元素 1000 次。但每次我得到一个固定的订单。
但是顺序与元素的插入顺序不同。
Set<String> hashSet = new HashSet<>();
for (int i = 0; i < 10; i++) {
hashSet.add("Item+" + i);
}
for (String s : hashSet) {
System.out.println(s);
}
您应该尝试向集合中添加更多元素(比如 10.000)。 HashSet 的默认容量为 16,但是一旦您向集合中添加更多元素,它就会在内部进行重构。在这种情况下,顺序可能会改变。
这意味着您不能确定顺序是否相同,例如,如果您 运行 在另一个 JVM 上使用相同的代码。
使用一个特定的 JVM,您的 机器上的顺序始终相同这一事实无关紧要。如果顺序很重要,请考虑使用 TreeSet
,TreeSet
将保证顺序 始终相同 ,无论您在哪里 运行代码。
当然:TreeSet
要求可以按某种方式(例如按字母顺序)对项目进行排序。如果要保留添加元素的顺序,您可能更喜欢 List
,例如 ArrayList
.
也许你可以看到相同的 "sorting" 但这不是真实的,这取决于 JVM 所以,如果你想要一个排序列表
如果您有逻辑排序,请使用 Collections.sort() 或实现您自己的 Comparator
如果您希望集合按插入顺序排序,请使用 List
和 Iterator
List iterators guarantee first and foremost that you get the list's elements in the internal order of the list (aka. insertion order). More specifically it is in the order you've inserted the elements or on how you've manipulated the list. Sorting can be seen as a manipulation of the data structure, and there are several ways to sort the list.
在哈希集合中,条目显示为按某些内部哈希函数的结果排序。
对于相同集合的条目以相同的顺序添加到相同的集合,返回顺序将始终相同,尽管散列函数值也保持不变,除非内部结构在调用之间重组(即通过扩大或缩小集合)——在重组时,内部哈希函数的值被重新计算并且条目在内部哈希 table 中占据另一个位置。
顺便说一句,哈希集合的条目迭代器仅保证您将收到您放置在那里但未被删除的所有条目。
HashMap 或 HashSet 中条目的顺序 在理论上是可以预测的 当前一代和更早的实现。
然而,预测至少取决于:
- 键的哈希值,
- set或map的初始容量,
- 在集合/映射中添加和删除键的精确顺序,
- 使用了
HashSet
或 HashMap
的具体实现(行为是 Java 版本相关的,并且可能取决于补丁级别),并且
- 对于 Java 8 及更高版本,键是否为
Comparable
.
如果您拥有所有这些信息(并且您准备好模拟插入/删除序列),您就可以准确地预测迭代顺序。然而,实施起来会很棘手,而且 运行 ...
在你的例子中,哈希值相同,初始HashSet
容量相同,插入顺序相同,HashSet
实现相同。在那些情况下(并且考虑到使用的精确算法)迭代顺序将是可重复的......即使很难预测。
在这种情况下,顺序不是 "random",因为在构建 HashSet
的过程中没有随机性。只是复杂和不透明的计算......但确定性。
I have read in java 1.7 docs that "It makes no guarantees as to the iteration order of the set". what is meaning of this?
意思是 javadoc 不承诺任何特定行为 vis-a-vis 排序。当然,没有对便携行为的承诺。
另请参阅:Order of values retrieved from a HashMap
我在 java 1.7 文档中读到 "It makes no guarantees as to the iteration order of the set"。 这是什么意思?
我创建了一个 HashSet 打印它的元素 1000 次。但每次我得到一个固定的订单。 但是顺序与元素的插入顺序不同。
Set<String> hashSet = new HashSet<>();
for (int i = 0; i < 10; i++) {
hashSet.add("Item+" + i);
}
for (String s : hashSet) {
System.out.println(s);
}
您应该尝试向集合中添加更多元素(比如 10.000)。 HashSet 的默认容量为 16,但是一旦您向集合中添加更多元素,它就会在内部进行重构。在这种情况下,顺序可能会改变。
这意味着您不能确定顺序是否相同,例如,如果您 运行 在另一个 JVM 上使用相同的代码。
使用一个特定的 JVM,您的 机器上的顺序始终相同这一事实无关紧要。如果顺序很重要,请考虑使用 TreeSet
,TreeSet
将保证顺序 始终相同 ,无论您在哪里 运行代码。
当然:TreeSet
要求可以按某种方式(例如按字母顺序)对项目进行排序。如果要保留添加元素的顺序,您可能更喜欢 List
,例如 ArrayList
.
也许你可以看到相同的 "sorting" 但这不是真实的,这取决于 JVM 所以,如果你想要一个排序列表
如果您有逻辑排序,请使用 Collections.sort() 或实现您自己的
Comparator
如果您希望集合按插入顺序排序,请使用
List
和Iterator
List iterators guarantee first and foremost that you get the list's elements in the internal order of the list (aka. insertion order). More specifically it is in the order you've inserted the elements or on how you've manipulated the list. Sorting can be seen as a manipulation of the data structure, and there are several ways to sort the list.
在哈希集合中,条目显示为按某些内部哈希函数的结果排序。
对于相同集合的条目以相同的顺序添加到相同的集合,返回顺序将始终相同,尽管散列函数值也保持不变,除非内部结构在调用之间重组(即通过扩大或缩小集合)——在重组时,内部哈希函数的值被重新计算并且条目在内部哈希 table 中占据另一个位置。
顺便说一句,哈希集合的条目迭代器仅保证您将收到您放置在那里但未被删除的所有条目。
HashMap 或 HashSet 中条目的顺序 在理论上是可以预测的 当前一代和更早的实现。
然而,预测至少取决于:
- 键的哈希值,
- set或map的初始容量,
- 在集合/映射中添加和删除键的精确顺序,
- 使用了
HashSet
或HashMap
的具体实现(行为是 Java 版本相关的,并且可能取决于补丁级别),并且 - 对于 Java 8 及更高版本,键是否为
Comparable
.
如果您拥有所有这些信息(并且您准备好模拟插入/删除序列),您就可以准确地预测迭代顺序。然而,实施起来会很棘手,而且 运行 ...
在你的例子中,哈希值相同,初始HashSet
容量相同,插入顺序相同,HashSet
实现相同。在那些情况下(并且考虑到使用的精确算法)迭代顺序将是可重复的......即使很难预测。
在这种情况下,顺序不是 "random",因为在构建 HashSet
的过程中没有随机性。只是复杂和不透明的计算......但确定性。
I have read in java 1.7 docs that "It makes no guarantees as to the iteration order of the set". what is meaning of this?
意思是 javadoc 不承诺任何特定行为 vis-a-vis 排序。当然,没有对便携行为的承诺。
另请参阅:Order of values retrieved from a HashMap