LinkedHashMap介绍(特点,优势,和其他比较)

LinkedHashMap的特点:
1.LinkedHashMap继承了HashMap ,实现了Clonable ,serialiable(可序列化) , map接口;

 public class LinkedHashMap<K,V> 
    extends HashMap<K,V>
    implements Map<K,V>
{
}

2.提供了AccessOrder参数,用来指定LinkedHashMap的排序方式,accessOrder =false -> 插入顺序进行排序 , accessOrder = true -> 访问顺序进行排序。

LinkedHashMap的优势:
相比于HashMap:迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序。而LinkedHashMap,它虽然增加了时间和空间上的开销,通过一个双向链表,LinkedHashMap保证了元素迭代的顺序。该迭代顺序有两种,可以是插入顺序或者是访问顺序。LinkedHashMap继承了HashMap类,有着HashMap的所有功能,还提供了记住元素添加顺序的方法。

LinkedHashMap和HashMap的异同点:

  • 相同点

1.linkedHashMap虽然继承HashMap, 但实现了双线链表 ,有固定的顺序,与插入entry的顺序一样; 而HashMap存储的方式是无序的。
2.LinkedHashMap包含removeEldestEntry()方法,而HashMap则没有;

 protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {  
        return false;  
 }
  • 相同点

key——value键值对:
1.Key和Value都允许空
2.Key重复会覆盖、Value允许重复

安全性:
非线程安全

继承关系:
都实现了Clonable ,serialiable(可序列化) , map接口;

LinkedHashMap底层数据结构:
数组加链表
LinkedHashMap可以认为是HashMap+LinkedList,它可以使用HashMap操作数据结构,又使用LinkedList维护插入元素的先后顺序。

LinkedHashMap成员变量:
// LinkedHashMap维护了一个双向链表,header是链表头,不存储数据。
private transient Entry<K, V> header;
// accessOrder(有序性的标志),accessOrder=true(访问有序),默认为false(插入有序)
private final boolean accessOrder;

Entry内部类:

//before:指向前一个entry元素。after:指向后一个entry元素

 Entry<K,V> before, after;

//使用的是父类HashMap的Entry构造

next是用于维护HashMap指定table位置上连接的Entry的顺序的,before、After是用于维护Entry插入的先后顺序的。

Entry(int hash, K key, V value, HashMap.Entry<K,V> next) { 
	super(hash, key, value, next); 
}

LinkedHashMap并没有重写父类的put()方法,说明调用put方法时实际上调用的是父类的put方法。按照顺序将entry插入到头结点为header的双向链表中;

linkedHashMap的get()方法:判断accessOlder的值 是需要按访问顺序还是遍历顺序来进行操作。

public V get(Object key) {
     //1.调用HashMap的getEntry方法得到e  
     Entry<K, V> e = (Entry<K, V>) getEntry(key); 
     if (e == null){
       	return null; 
     }
     //2.LinkedHashMap加入的操作 
     e.recordAccess(this);
     return e.value; 
}
void recordAccess(HashMap<K,V> m) { 
     LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
     if (lm.accessOrder) {
        lm.modCount++; 
     remove(); 
     //因为是双向循环链表,所以在头节点之前插入的节点也就是链表的尾节点 			                     	
     addBefore(lm.header); 
     }
}
private void addBefore(Entry<K,V> existingEntry) { 
     after = existingEntry; 
     before = existingEntry.before; 
     before.after = this; 
     after.before = this; 
}

LinkedHashMap的remove()方法,是将双线链表的某一个节点移除,而不移除数组加链表上的节点。

   private void remove() {       
        //this.before.after = this.after;       
        //this.after.before = this.before; 这样看可能会更好理解,this指的就是要删除的那个元素。 
        before.after = after; 
        after.before = before; 
    }

LinkedHashMap的containsValue方法:首先处理value为null的情况, 其次它不像HashMap一样遍历整个数组, 而是通过遍历双线链表header来查找value;

LinkedHashMap可以保存元素的插入顺序,顺序有两种方式一种是按照插入顺序排序,一种按照访问做排序。默认以插入顺序排序,性能比HashMap略低,线程也是不安全的。

一般情况下,我们用的最多的是HashMap,在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果要按顺序或自定义顺序遍历键,那么TreeMap会更好。如果需要输出的顺序和输入的相同,用LinkedHashMap 可以实现,它还可以按读取顺序来排列.

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值