zoukankan      html  css  js  c++  java
  • Java集合(13)--LinkedHashMap源码分析

    HashMap使用哈希表来存储数据,并用拉链法来处理冲突。LinkedHashMap继承自HashMap,同时自身有一个链表,使用链表存储数据,不存在冲突。

    LinkedList和LinkedHashMap一样使用一个双向循环链表,但LinkedList存储的是简单的数据,并不是“键值对”。

    LinkedList和LinkedHashMap都可以维护内容的顺序,但HashMap不维护顺序。

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

    HashMap的init方法没有实现,但是LinkedHaqshMap已经对其实现:

    void init() {  
    //初始化一个Entry类型的header  
            header = new Entry<K,V>(-1, null, null, null);        
    header.before = header.after = header;  
        }

    LinkedHashMap中多了一个accessOrder变量,他表示迭代时候的一个顺序,若为true,则按照读取顺序排序(读得越多在链表的越后面读得越少在链表的越前面LRU,最近最少使用),若为false则按照插入顺序排序.LinkedHaqshMap的前4个构造方法可以看出,accessOrder默认为false,故按照插入顺序进行排序。

     void recordAccess(HashMap<K,V> m) {  
               LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;  
               if (lm.accessOrder) {  
                   lm.modCount++;  
                   remove();  
                   addBefore(lm.header);  
               }  
           }  

    LRU算法中,最少使用的页面被先换出最近使用的很可能以后还会使用

    他判断accessOrder属性,若为true,则执行一个叫做LRU的算法,将刚访问的entry移除,然后加到header前面,这样迭代的时候会优先迭代最近频繁访问的entry(不是链表头),从而就改变了迭代的顺序。

    void addEntry(int hash, K key, V value, int bucketIndex) {
          createEntry(hash, key, value, bucketIndex);
          Entry<K,V> eldest = header.after;
          if (removeEldestEntry(eldest)) {
              removeEntryForKey(eldest.key);
          } else {
              if (size >= threshold)
                  resize(2 * table.length);
          }
     }
    protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
       //始终返回的是false     
    return false; }

    启发:若希望将Map当做Cache来使用,并且限制大小,只需继承LinkedHashMap并重写removeEldestEntry(Entry<K,V> eldest)方法,像这样:

    private static final int MAX_ENTRIES = 100;
     protected boolean removeEldestEntry(Map.Entry eldest) {
          return size() > MAX_ENTRIES;
     }

    实现最近被使用(LRU)缓存:

    import java.util.LinkedHashMap;
    import java.util.Map;
     
    public LRUCache<K, V> extends LinkedHashMap<K, V> {
      private int cacheSize;
     
      public LRUCache(int cacheSize) {
        super(16, 0.75, true);//排序策略
        this.cacheSize = cacheSize;
      }
  • 相关阅读:
    调用google地图
    jQuery放大镜效果
    jQuery拖到效果
    jQuery制作相册
    jQuery ui插件用法
    jQuery写fadeTo方法
    jQuery实现动画效果
    jQuery的slideToggle方法
    控经纬度显示地图与卫星
    像百度那样的智能感知效果
  • 原文地址:https://www.cnblogs.com/pipi-style/p/4738060.html
Copyright © 2011-2022 走看看