为什么 Map、Set集合存放是无序的,然而LinkedHashSet和LinkedHashMap等集合却有序?

(1)LinkedHashSet是一个哈希表和链表的结合,而且还是一个双向链表。
(双向链表是链表的一种,它的每个数据节点都有两个指针分别指向直接后继和直接前驱,所以从双向链表的任意一个节点开始都可以很方便的访问它的前驱节点和后继节点。)
下图为一个双向链表的节点:
在这里插入图片描述
LinkedHashSet集合也是根据元素hashCode值来决定元素存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。也就是说,当遍历LinkedHashSet集合里元素时,HashSet将会按元素的添加顺序来访问集合里的元素,因此LinkedHashSet可以保证元素按插入顺序输出。

而Set对每个对象只接受一次,里面的值不允许重复,是无序的数据结构;LinkeHashSet是set集合的一个实现,具有set集合不重复的特点,同时具有可预测的迭代顺序,即输入顺序。

(2)Map对每个元素保存一份,但是是基于“键”的,是成对的数据结构,键值必须具有唯一性(即键不能相同否则会被替换,不允许键重复但允许值重复)。
HashMap是基于哈希表的Map接口实现,以key-value的形式存在,是map的一个实现类,HashMap是无序的,因为HashMap内的元素在数组中的位置是由元素的hash值决定的,并不是先插入就在位置的前面。但
LinkedHashMap是有序的,默认按插入顺序排序。

LinkedHashMap中声明了两个成员变量:

private transient Entry<K,V> header;
private final boolean accessOrder;

而且LinkedHashMap对Entry也重写了,Entry类中添加了两个成员变量 before, after。

private static class Entry<K,V> extends HashMap.Entry<K,V> {
  Entry<K,V> before, after;
}

可以看出LinkedHashMap有序的原因是LinkedHashMap不但继承了父类使用数组存储元素,hash定位,自己内部还保存着一个双向链表,正是因为此双向链表的存在,LinkedHashMap才能有序。
LinkedHashMap是HashMap的一个直接子类,二者唯一的区别是LinkedHashMap在HashMap的基础上,采用双向链表(doubly-linked list)的形式将所有entry连接起来,这样是为保证元素的迭代顺序跟插入顺序相同。

猜你喜欢

转载自blog.csdn.net/weixin_44084434/article/details/91370587