LinkedHashMap中的entrySet()方法是否也保证顺序?

89

我正在使用LinkedHashMap来保证某人尝试访问它时的顺序。但是,当需要遍历它时,使用entrySet()返回键/值对是否也能保证顺序?在迭代时不会进行任何更改。

编辑:此外,通过遍历其键并调用get方法来迭代映射是否会有任何负面影响?


我本来也想问同样的问题,但如果已经有人问过并得到了好的答案,为什么还要再问呢?对于一个好问题点赞。 - uTubeFan
在LinkedHashMap中,您可以使用插入顺序和访问顺序。顺序始终保持不变。请参阅我的《LinkedHashMap的内部生活》教程(http://volodial.blogspot.com/2013/07/internal-life-of-linkedhashmap-in-java.html)。 - Volodymyr Levytskyi
3个回答

57
根据 Javadocs,LinkedHashMap是可以的。
HashMap 不同,LinkedHashMap 通过维护一个双向链表来遍历所有条目。这个链表定义了迭代顺序,通常是插入键的顺序 (插入顺序)。
至于编辑操作,则没有问题。但由于 entry set 避免在迭代期间查找映射中的每个键的开销,因此 entry set 稍微快一些。

15
但是entrySet返回的是一个无序的Set? - Jonathan.
6
是的,从技术上讲,entrySet 本身没有办法访问位置,但是 entrySet.iterator() 可以。迭代器可以让我们拥有一个有序列表。 - Jpatrick
3
我想知道这个答案是否正确,但是正如Jonathan指出的那样,entrySet()返回一个Set集合。Jpatrick说,该集合的迭代器让我们拥有一个有序列表,但是http://docs.oracle.com/javase/6/docs/api/java/util/Set.html#iterator()说:“元素没有特定的顺序返回(除非此集合是某个提供保证的类的实例)。”,而且这里引用的文档都没有说entrySet()返回的Set是一个保证顺序的类的实例。我有什么遗漏吗? - LarsH
1
迈克尔·迈尔斯指出的文档确实表明LinkedHashMap定义了迭代顺序,但是它并没有说明如何访问该排序。 entrySet().iterator()是一种合理的方式,但它能可靠地依赖吗? - LarsH
7
在这里找到了一个明确的答案:https://dev59.com/YXA85IYBdhLWcg3wJf8Z#2924143,“Map的顺序被定义为迭代器在映射集合视图返回其元素的顺序。” - Map的Javadoc。 - LarsH

2

如果您确定在迭代期间不会进行任何更改,则使用entrySet()进行适当排序是有保证的,正如API中所述。


3
你提供的entrySet()的API文档并未说明其能保证正确排序。该页面上唯一相关的声明是:“该类(即HashMap)不保证映射的顺序;特别是它不能保证顺序随时间保持不变。”你在提供这个链接时指的是什么? - LarsH

1
这个链表定义了迭代顺序,通常是键被插入到映射中的顺序(插入顺序)。请注意,如果将键重新插入到映射中,则不会影响插入顺序。(如果在调用之前m.containsKey(k)返回true,则在调用m.put(k, v)时将键k重新插入到映射m中。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接