调用之间的地图/集合顺序是否稳定?
如果我有一个哈希映射并重复迭代对象,那么我不能保证每次调用的顺序都相同,这是否正确?例如,以下内容是否可以打印彼此不同的两行:
Map<String,Integer> map = new HashMap<String,Integer>()
{{ put("a", 1); put("b", 2); put("c", 3); }};
System.out.println(map);
System.out.println(map);
一般情况下,集合和集合都是这种情况吗?如果是这样,如果您必须以相同的顺序对同一集合进行两次迭代(无论顺序是什么),最好的方法是什么?我想转换为列表。
If I have a hash map and iterate over the objects repeatedly, is it correct that I'm not guaranteed the same order for every call? For example, could the following print two lines that differ from each other:
Map<String,Integer> map = new HashMap<String,Integer>()
{{ put("a", 1); put("b", 2); put("c", 3); }};
System.out.println(map);
System.out.println(map);
And is this the case for sets and collections in general? If so, what's the best way in case you have to iterate twice over the same collection in the same order (regardless of what order that is)? I guess converting to a list.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Map
和Set
的约定不对迭代顺序做出任何保证,但SortedSet
和SortedMap
的约定(由TreeMap
和TreeSet
实现)。此外,即使是未排序的实现,只要不以任何方式修改,通常也会表现出确定性,并且对于每个特定实例都具有可重复的迭代顺序。然而,这是一个实现细节,不应依赖。
The contracts of
Map
andSet
do not make any guarantees about iteration order, but those ofSortedSet
andSortedMap
(implemented byTreeMap
andTreeSet
) do.Furthermore, even the non-sorted implementations generally behave deterministically and have a repeatable iteration order for each specific instance, as long as it's not modified in any way. However, that's an implementation detail and should not be relied upon.
你是对的,不能保证地图的顺序。您可能想查看类似 TreeMap< /a> 如果您需要在调用之间保持相同的顺序。
话虽如此,代码很可能会打印出相同的内容两次,但这并不能保证。
you're correct, the order of a map is not guaranteed. you might want to look at something like TreeMap if you need the order to stay the same between calls.
having said that, chances are that code will print out the same thing twice, it's just not guaranteed.
使用
HashMap
时,不能保证每次迭代的迭代顺序都相同。相反,请考虑
LinkedHashMap
,这是一个具有可预测迭代顺序的哈希表。When using a
HashMap
, there's no guarantee that the iteration order will be the same on each iteration.Instead, consider a
LinkedHashMap
, which is a hash table with a predictable iteration order.我认为现有的任何答案都不能完全满足您的要求。当然,具有某些内容的 HashMap 可能不会以与具有相同内容的不同 HashMap 相同的方式进行迭代,或者在不同的 VM 调用中,或者在不同的 JDK 版本上运行等。但是您只是想知道该确切的实例是否,如果未修改,将以与自身相同的方式进行迭代。
这是事实上规范的一个很好的示例。确实,规范的文字中并没有表明会出现这种情况。然而,每个 JDK 集合都以这种方式运行(前提是,在访问有序的 LinkedHashMap 的情况下,每次都进行迭代)。并且很难想象一个集合实现不具有此属性。我已经实现并审查了许多集合,只有一次我考虑过一个集合每次都会进行不同的迭代;这是一个非常奇怪的情况,我最终放弃了整个想法,因为每次都进行不同的迭代实在太奇怪了(也就是说,违反了我提到的事实上规范)。
所以我说继续吧,依靠它。这并不是一个依赖于您想要的任何旧的未指定行为的笼统建议。但在这种情况下,它不会伤害你。
I don't think any of the existing answers are quite speaking to exactly what you're asking about. Sure, a HashMap with certain contents may not iterate in the same way as a different one with equal contents, or in a different VM invocation, or running on different JDK versions, etc. But you're just asking whether that exact instance, if not modified, will iterate the same way as itself.
This is a good example of a de facto specification. It's true that it is not present in the letter of the spec that this will be the case. However, every single JDK collection behaves this way (provided, in the case of an access-ordered LinkedHashMap, that you iterate all the way through each time). And it is difficult to conceive of a collection implementation that would not have this property. I've implemented and reviewed many collections and there was just once that I considered a collection that would iterate differently each time; it was an extremely strange case and I ended up throwing out the whole idea because iterating differently each time was just too damn weird (that is, violated that de facto specification I mentioned).
So I say go ahead and depend on it. That's not a blanket recommendation to depend on any old unspecified behavior you want. But in this case, it's just not going to hurt you.
虽然库规范不保证顺序随着时间的推移保持不变,但只要底层数据结构(即实现哈希表的数组)不改变,它就可能是相同的。因此,只要您不向哈希表插入或删除项目,那么假设条目顺序不会改变也不是没有道理的。
查看
HashMap
的典型实现表明情况就是如此,例如:http://www.docjar.com/html/api/ java/util/HashMap.java.html
也就是说,它不是您的代码应该依赖的东西。
While the library spec does not guarantee that the order remains the same over time, it probably will be identical as long as the underlying data structure (i.e., the arrays that implement the hash table) are not altered. So as long as you don't insert or remove items from the hash table, it's not unreasonable to assume that the entry order will not change.
Looking at a typical implementation of
HashMap
shows this to be the case, such as the one at:http://www.docjar.com/html/api/java/util/HashMap.java.html
That being said, it's not something your code should rely on.