180

我知道LinkedHashMap有一个可预测的迭代顺序(插入顺序)。Set退货者LinkedHashMap.keySet()Collection退货者是否LinkedHashMap.values()也保持这个顺序?

4

7 回答 7

245

Map 接口提供了三个 集合视图,它们允许将映射的内容视为一组键、值集合或键值映射集。地图的顺序定义为地图集合视图上的迭代器返回其元素的顺序。一些地图实现,比如TreeMap 类,对它们的顺序做出特定的保证;其他人,像 HashMap班级一样,没有。

--地图

这个链表定义了迭代顺序,通常是键插入映射的顺序(插入顺序)。

-- LinkedHashMap

所以,是的,keySet()values()entrySet()(提到的三个集合视图)按照内部链表使用的顺序返回值。是的,JavaDoc 用于MapLinkedHashMap保证它。

毕竟,这就是这门课的重点。

于 2010-05-27T19:15:21.823 回答
12

看源码,好像是这样的。keySet(), values(), 和entrySet()都在内部使用相同的条目迭代器。

于 2010-05-27T18:39:51.393 回答
7

不要混淆LinkedHashMap.keySet()LinkedHashMap.entrySet()返回 Set ,因此它不应该保证订购!

Set是一个接口HashSetTreeSet等等是它的实现。接口的HashSet实现Set不保证顺序。但TreeSet确实如此。也LinkedHashSet可以。

因此,要知道返回的 Set 引用是否保证排序取决于如何Set实现。LinkedHashMap我浏览了 的源代码LinkedHashMap,它看起来像这样:

private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}

因此 LinkedHashMap/HashMap 有自己的Setie实现KeySet。因此,不要将此与HashSet.

此外,顺序由元素插入存储桶的方式来维护。查看 的addEntry(..)方法LinkedHashMap并将其与突出和HashMap的主要区别的方法进行比较。HashMapLinkedHashMap

于 2015-10-01T14:03:32.960 回答
5

你可以这样假设。Javadoc 说“可预测的迭代顺序”,Map 中唯一可用的迭代器那些用于 keySet()、entrySet() 和 values() 的迭代器。

因此,在没有任何进一步限定的情况下,它显然打算适用于所有这些迭代器。

于 2010-05-28T05:51:45.103 回答
0

AFAIK 它没有记录,所以你不能“正式”这样假设。但是,当前的实施方式不太可能发生变化。

如果您想确保顺序,您可能需要遍历整个地图并将它们插入到具有您选择的顺序功能的排序集中,尽管您自然会付出性能成本。

于 2010-05-27T18:40:28.960 回答
-3

查看界面,它返回一个普通的Set而不是SortedSet. 所以没有任何保证。

在通过查看实现(总是一个坏主意)来假设隐式保证之前,还要查看所有其他 Java 实现中的实现:)

例如,您可以更好地使用构造函数中的 keySet 创建一个 TreeSet。

于 2010-05-27T18:39:16.747 回答
-4

我认为您不能假定 keySet() 和 values() 的顺序。

只要我遵守在 Map 中定义并在 HashMap 中覆盖的这两个方法的约定,我就可以轻松编写返回无序 keySet() 和 values() 的 LinkedHashMap 实现。

于 2014-11-14T20:10:26.737 回答