java基础提升之LinkedHashMap

        进入高产模式java

。这一篇呢,咱们来学一哈儿LinkedHashMap,这个LinkedHashMap。在缓存算法中有一个LRU(Least Recently Used的缩写,最近最少使用)算法,咱们即可以经过这个LinkedHashMap去完成这个算法,具体实现咱们会在后面贴出来。如今咱们进入咱们探讨的正常流程。在看这一篇以前建议先去了解 HashMap

简介

  1. Map接口的哈希表与链表实现,这个跟HashMap不同的地方有这么一个,就是有可预测的顺序,咱们会在下面说到。这个实现不一样于HashMap的地方是它内部维护了一个关联全部键值对的双相链表,这个链表定义了迭代的顺序是按照插入时的顺序仍是访问时的顺序。算法

  2. LinkedHashMap提供了一个构造函数,能使原有的Map转变为LinkedHashMap,而且这个LinkedHashMap中元素的顺序与源中元素顺序相同。缓存

  3. LinkedHashMap提供了一个构造函数LinkedHashMap(int,float,boolean) ,咱们能经过这个构造函数指定排序顺序。当为ture时,LinkedHashMap会将按照访问的顺序进行排序。安全

  4. removeEldestEntry这个方法即是LinkedHashMap判断是否删除元素的依据,当为true时,删除第一个元素。若是要使用通常须要重写。ide

  5. 这个类提供全部map的可选操做,而且容许null元素。想HashMap同样,对基本操做如add、contains、remove他提供恒定时间的性能表现。而且性能比HashMap只低一点点,由于要维护一个双向链表。对全部元素进行迭代,在LinkedHashMap中这个所须要的时间与其size成正比。可是HashMap花费更多,须要与其容量成正比的时间。函数

  6. 有两个参数影响其性能,initial capacity与load factor 他们的定义与在HashMap中的彻底相同。性能

  7. 这个实现不是同步的,若是有多个线程访问,而且至少有一个线程对其进行告终构修改,必需要进行额外的操做保证其线程安全性,好比使用Map m = Collections.synchronizedMap(new LinkedHashMap(...));this

  8. 这里的结构改变与其余的集合类有些不一样,在这个LinkedHashMap是以访问顺序进行排序时,get也算结构改变。spa

  9. 这个类返回的全部迭代器Iterator都是基于快速失败机制fail-fast的。线程

  10. 这个类返回的分裂迭代器Spliterator是后期绑定以及快速失败的,而且被标记为ORDERED。

存储结构

LinkedHashMap继承于HashMap,因此LinkedHashMap除了双向链表外,其余的都与HashMap大同小异。在这一篇,咱们将关注点放到LinkedHashMap的实际使用上,因此存储结构咱们用图来解释。

展现的有些乱,可是大题存储结构画出来了,与HashMap相比其实就是多了一个双向链表。

实际应用

咱们如今利用LinkedHashMap来作一个简单的LRU。

import java.util.LinkedHashMap;
import java.util.Map;

/** * @author lichaobao * @date 2019/5/30 * @QQ 1527563274 */
public class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V> {
    private int capacity;
    public LRULinkedHashMap(int capacity){
        super(4,0.75f,true);
        this.capacity = capacity;
    }
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        boolean ifRemove = size() > capacity;
        if(ifRemove){
            System.out.println("内存不够即将删除:"+eldest.getKey()+"="+eldest.getValue());
        }
        return ifRemove;
    }
    public static void main(String[] args){
        Map<Integer,String> map = new LRULinkedHashMap<Integer, String>(4);
        map.put(1,"one");
        map.put(2,"two");
        map.put(3,"three");
        map.put(4,"four");
        System.out.println("==========访问前数据顺序==============");
        map.forEach((key,value)->{
            System.out.print(key+"="+value+" ");
        });
        System.out.println("\n============如今开始get(1)=============");
        System.out.println(map.get(1));
        System.out.println("==========访问1后数据顺序==============");
        map.forEach((key,value)->{
            System.out.print(key+"="+value+" ");
        });
        System.out.println("\n==============如今开始增长第五个数据 put(5,\"five\")==========");
        map.put(5,"five");
        System.out.println("================最后map中的元素以及顺序为================");
        map.forEach((key,value)->{
            System.out.print(key+"="+value+" ");
        });
    }
}
复制代码

最后运行结果以下:

总结

  1. LinkedHashMap除了多了一个双向链表外与HashMap大体相同,好比扩容、存储机制等。
  2. 支持两种自动排序,一种是按照插入时的顺序排序,一种是按照访问时的顺序排序,能够经过构造函数LinkedHashMap(int,float,boolean) 来选择。
  3. 比较适合用来作LRU
  4. 非同步容器
相关文章
相关标签/搜索