我知道 LinkedHashMap有一个可预测的迭代顺序(插入顺序)。LinkedHashMap.keySet()返回的 Set和 LinkedHashMap.values()返回的 Collection是否也维持这个订单?
LinkedHashMap
LinkedHashMap.keySet()
Set
LinkedHashMap.values()
Collection
看看源代码,似乎是这样的。 keySet()、 values()和 entrySet()都在内部使用相同的条目迭代器。
keySet()
values()
entrySet()
AFAIK 是没有文件的,所以你不能“正式”假设这样。然而,目前的执行情况不太可能发生变化。
如果希望确保顺序,那么可能需要迭代映射整体,并将它们插入到具有自己选择的顺序函数的排序集中,当然,这样做需要支付性能成本。
Map 接口提供了三个 集合视图 ,它允许将地图的内容视为一个集合 键的集合、值的集合或集合 键值映射的 秩序 地图被定义为 映射集合上的迭代器 视图返回它们的元素。一些映射 实现,如 TreeMap 类,作出具体保证 他们的顺序; 其他的,像 HashMap类,不要。
TreeMap
HashMap
—— 地图
这个链表定义了迭代 顺序,这通常是顺序 其中键被插入到 地图(插入顺序)。
—— LinkedHashMap
因此,是的,keySet()、 values()和 entrySet()(上面提到的三个集合视图)按照内部链表使用的顺序返回值。是的,用于 Map和 LinkedHashMap的 JavaDoc 保证了这一点。
Map
毕竟,这就是这门课的重点。
你可以这么认为。Javadoc 表示“可预测的迭代顺序”,而 Map 是中只有 keySet ()、 entrySet ()和 value ()可用的迭代器。
因此,在没有任何进一步限定的情况下,显然可以将它应用于所有这些迭代器。
不要混淆 LinkedHashMap.keySet()和 LinkedHashMap.entrySet()返回集,因此它不应该保证订购!
LinkedHashMap.entrySet()
Set是一个与 HashSet、 TreeSet等实现接口。Set接口的 HashSet实现不保证排序。但 TreeSet可以。LinkedHashSet也是。
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。
KeySet
另外,顺序是通过元素如何插入 bucket 来维护的。看看 LinkedHashMap的 addEntry(..)方法,并将其与 HashMap的方法进行比较,后者突出了 HashMap和 LinkedHashMap之间的主要区别。
addEntry(..)