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

LinkedHashMap的特点:
1.LinkedHashMap继承了HashMap ,实现了Clonable ,serialiable(可序列化) , map接口;
public class LinkedHashMap
extends HashMap
implements Map
{
}
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 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 header;
// accessOrder(有序性的标志),accessOrder=true(访问有序),默认为false(插入有序)
private final boolean accessOrder;

Entry内部类:

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

 Entry before, after;

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

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

Entry(int hash, K key, V value, HashMap.Entry 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 e = (Entry) getEntry(key); 
     if (e == null){
       	return null; 
     }
     //2.LinkedHashMap加入的操作 
     e.recordAccess(this);
     return e.value; 
}
void recordAccess(HashMap m) { 
     LinkedHashMap lm = (LinkedHashMap)m;
     if (lm.accessOrder) {
        lm.modCount++; 
     remove(); 
     //因为是双向循环链表,所以在头节点之前插入的节点也就是链表的尾节点 			                     	
     addBefore(lm.header); 
     }
}
private void addBefore(Entry 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 可以实现,它还可以按读取顺序来排列.

你可能感兴趣的:(LinkedHashMap介绍(特点,优势,和其他比较))