我知道LinkedHashMap
具有可预测的迭代顺序(插入顺序)。 Set
返回的LinkedHashMap.keySet()
和Collection
返回的LinkedHashMap.values()
是否也维持此顺序?
答案 0 :(得分:199)
Map接口提供三个 集合视图,它允许将地图的内容视为一个集合 键,值的集合或集合 键值映射。的订单 地图定义为其中的顺序 地图集合上的迭代器 视图返回其元素。一些地图 实现,如
TreeMap
上课,作出具体保证 他们的订单;其他人,比如HashMap
上课,不要。
- Map
此链接列表定义迭代 订购,通常是订单 其中键被插入 地图(插入订单)。
所以,是的,keySet()
,values()
和entrySet()
(提到的三个集合视图)按内部链接列表使用的顺序返回值。是的,Map
和LinkedHashMap
的JavaDoc保证了它。
毕竟,这就是本课程的重点。
答案 1 :(得分:11)
看看来源,看起来确实如此。 keySet()
,values()
和entrySet()
都在内部使用相同的条目迭代器。
答案 2 :(得分:7)
不要对LinkedHashMap.keySet()
和LinkedHashMap.entrySet()
返回Set感到困惑,因此不应该保证订购!
Set
是HashSet
,TreeSet
等与其实现相关的接口。 HashSet
接口的Set
实现不保证排序。但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
混淆。
此外,订单由元素插入存储桶的方式维护。查看addEntry(..)
的{{1}}方法,并将其与LinkedHashMap
的方法进行比较,突出显示HashMap
和HashMap
之间的主要区别。
答案 3 :(得分:5)
你可以这么认为。 Javadoc说'可预测的迭代顺序',Map 中唯一可用的迭代器是,用于keySet(),entrySet()和values()。
因此,在没有任何进一步限定的情况下,它显然适用于所有这些迭代器。
答案 4 :(得分:0)
AFAIK没有记录,所以你不能“正式”假设。但是,目前的实施不太可能发生变化。
如果您想确保订单,您可能希望迭代地图并将它们插入到具有您选择的订单功能的有序集合中,但您自然会支付性能成本。
答案 5 :(得分:-3)
查看界面,它返回普通Set
而不是SortedSet
。所以没有保证。
在通过查看实现(总是一个坏主意)假设隐式保证之前,还要查看所有其他Java实现中的实现:)
您最好使用构造函数中的keySet创建一个TreeSet实例。
答案 6 :(得分:-4)
我认为你不能假设keySet()和values()的顺序。
我可以轻松编写LinkedHashMap的实现,它返回无序的keySet()和values(),只要我坚持在Map中定义的这两个方法的契约,并在HashMap中重写。