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

我知道 LinkedHashMap有一个可预测的迭代顺序(插入顺序)。LinkedHashMap.keySet()返回的 SetLinkedHashMap.values()返回的 Collection是否也维持这个订单?

56117 次浏览

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

AFAIK 是没有文件的,所以你不能“正式”假设这样。然而,目前的执行情况不太可能发生变化。

如果希望确保顺序,那么可能需要迭代映射整体,并将它们插入到具有自己选择的顺序函数的排序集中,当然,这样做需要支付性能成本。

Map 接口提供了三个 集合视图 ,它允许将地图的内容视为一个集合 键的集合、值的集合或集合 键值映射的 秩序 地图被定义为 映射集合上的迭代器 视图返回它们的元素。一些映射 实现,如 TreeMap 类,作出具体保证 他们的顺序; 其他的,像 HashMap类,不要。

—— 地图

这个链表定义了迭代 顺序,这通常是顺序 其中键被插入到 地图(插入顺序)。

—— LinkedHashMap

因此,是的,keySet()values()entrySet()(上面提到的三个集合视图)按照内部链表使用的顺序返回值。是的,用于 MapLinkedHashMap的 JavaDoc 保证了这一点。

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

你可以这么认为。Javadoc 表示“可预测的迭代顺序”,而 Map 中只有 keySet ()、 entrySet ()和 value ()可用的迭代器。

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

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

Set是一个与 HashSetTreeSet等实现接口。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

另外,顺序是通过元素如何插入 bucket 来维护的。看看 LinkedHashMapaddEntry(..)方法,并将其与 HashMap的方法进行比较,后者突出了 HashMapLinkedHashMap之间的主要区别。