我知道LinkedHashMap
有一个可预测的迭代顺序(插入顺序)。Set
退货者LinkedHashMap.keySet()
和Collection
退货者是否LinkedHashMap.values()
也保持这个顺序?
7 回答
Map 接口提供了三个 集合视图,它们允许将映射的内容视为一组键、值集合或键值映射集。地图的顺序定义为地图集合视图上的迭代器返回其元素的顺序。一些地图实现,比如
TreeMap
类,对它们的顺序做出特定的保证;其他人,像HashMap
班级一样,没有。
--地图
这个链表定义了迭代顺序,通常是键插入映射的顺序(插入顺序)。
所以,是的,keySet()
、values()
和entrySet()
(提到的三个集合视图)按照内部链表使用的顺序返回值。是的,JavaDoc 用于Map
并LinkedHashMap
保证它。
毕竟,这就是这门课的重点。
看源码,好像是这样的。keySet()
, values()
, 和entrySet()
都在内部使用相同的条目迭代器。
不要混淆LinkedHashMap.keySet()
并LinkedHashMap.entrySet()
返回 Set ,因此它不应该保证订购!
Set
是一个接口HashSet
,TreeSet
等等是它的实现。接口的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 有自己的Set
ie实现KeySet
。因此,不要将此与HashSet
.
此外,顺序由元素插入存储桶的方式来维护。查看 的addEntry(..)
方法LinkedHashMap
并将其与突出和HashMap
的主要区别的方法进行比较。HashMap
LinkedHashMap
你可以这样假设。Javadoc 说“可预测的迭代顺序”,Map 中唯一可用的迭代器是那些用于 keySet()、entrySet() 和 values() 的迭代器。
因此,在没有任何进一步限定的情况下,它显然打算适用于所有这些迭代器。
AFAIK 它没有记录,所以你不能“正式”这样假设。但是,当前的实施方式不太可能发生变化。
如果您想确保顺序,您可能需要遍历整个地图并将它们插入到具有您选择的顺序功能的排序集中,尽管您自然会付出性能成本。
查看界面,它返回一个普通的Set
而不是SortedSet
. 所以没有任何保证。
在通过查看实现(总是一个坏主意)来假设隐式保证之前,还要查看所有其他 Java 实现中的实现:)
例如,您可以更好地使用构造函数中的 keySet 创建一个 TreeSet。
我认为您不能假定 keySet() 和 values() 的顺序。
只要我遵守在 Map 中定义并在 HashMap 中覆盖的这两个方法的约定,我就可以轻松编写返回无序 keySet() 和 values() 的 LinkedHashMap 实现。