LinkedHashMap对象返回键和值的顺序是否有保证?

198

我知道LinkedHashMap具有可预测的迭代顺序(插入顺序)。通过LinkedHashMap.keySet()返回的SetLinkedHashMap.values()返回的Collection是否也保留此顺序?


1
由于所有答案都涉及到values()keySet()的问题,我已经扩展了问题的范围。这意味着更多的问题可以被关闭为此类重复问题。 - Duncan Jones
5个回答

273
Map接口提供了三个集合视图,可以将Map的内容视为一组键、一组值或一组键值映射。一个Map的顺序被定义为其集合视图上的迭代器返回元素的顺序。一些Map实现(如TreeMap类)对它们的顺序进行特定的保证;而其他Map实现(如HashMap类)则不会。
-- Map
这个链接列表定义了迭代顺序,通常是插入到Map中的键的顺序(插入顺序)。
-- LinkedHashMap
因此,是的,keySet()、values()和entrySet()(这三个集合视图)会按照内部链接列表使用的顺序返回值。是的,Map和LinkedHashMap的JavaDoc保证了它。这毕竟是这个类的重点。

10
使用LinkedHashMap迭代Map的速度比使用HashMap更快。 - Thierry
3
values() 方法返回一个集合,而不是列表。它是如何保持顺序的? - Dejell
8
Collectionvalues()返回值的基类。它返回的Collection的实现仍由LinkedHashMap控制。在LinkedHashMap的情况下,它返回一个LinkedValues实例,这是LinkedHashMap.java中的一个私有类。 - Powerlord
4
在我的情况下,LinkedHashMap的键集合不按地图中的顺序表示。 对此感到非常困惑。 - Alkanshel
3
感谢您在“Map”中提供了链接到文档的内容,明确将映射的顺序与映射集合视图上的迭代器联系起来(并清楚说明了这些集合视图是什么)。这对我来说是缺失的关键。 - LarsH
显示剩余5条评论

12

从源代码来看,似乎是这样的。keySet()values()entrySet()内部都使用相同的条目迭代器。


2
有一个指向存储库的链接会很酷,但我太懒了 :-) 当然,这并不保证向前兼容性。 - Ciro Santilli OurBigBook.com

8
不要混淆LinkedHashMap.keySet()和LinkedHashMap.entrySet()返回Set并且不应保证顺序!Set是一个接口,它的实现包括HashSet、TreeSet等。Set接口的HashSet实现不保证顺序,但是TreeSet和LinkedHashSet保证顺序。因此,取决于Set在LinkedHashMap中的实现方式,才能确定返回的Set引用是否保证排序。我查看了LinkedHashMap的源代码,它如下所示:
private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}

因此,LinkedHashMap/HashMap有其自己的Set实现,即KeySet。因此不要将其与HashSet混淆。
此外,元素插入到桶中的方式决定了顺序。查看LinkedHashMapaddEntry(..)方法,并将其与HashMap进行比较,这突显了HashMapLinkedHashMap之间的主要区别。

6
这个回答提供了有用的信息,但并没有真正回答问题。基本上它是在说它们可以有可预测的迭代顺序。 - Tuupertunut

5
你可以这么假设。Javadoc中写道“可预测的迭代顺序”,而在Map中唯一可用的迭代器是keySet()、entrySet()和values()。因此,在没有任何进一步限定的情况下,显然是打算应用于所有这些迭代器。

0

据我所知,这并没有被记录下来,因此您不能“正式”假设。然而,当前的实现不太可能改变。

如果您想确保顺序,可以遍历映射条目并将它们插入到一个排序集合中,该集合具有您选择的顺序函数,但自然会付出性能成本。


你的意思是entrySet()保证顺序,而keySet()不保证吗? - user256239
1
@kknight:我不确定。Javadoc指出:“这个链接列表定义了迭代顺序,通常是键被插入到映射中的顺序(插入顺序)。”然而,JDK的JavaDocs通常含糊不清。 - Uri
5
如果连 entrySet() 方法都不能保证遍历顺序,那么 LinkedHashMap 和 HashMap 有什么区别?我们如何利用 LinkedHashMap 实例中可预测的迭代顺序?注:LinkedHashMap 是一种特殊的 HashMap,它可以保持插入顺序或访问顺序。 - user256239
2
它肯定是有记录的。答案完全不正确。 - user207421

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