Java HashMap LinkedHashMap

HashMap


HashMap的扩容机制?


如果Entry的数量达到或者超过阈值即(size >= threshold,并且将要插入的数组位置不为空,即null != table[bucketIndex],将table数组的长度增加为原来的2倍即resize(2 * table.length),并且计算新的位置bucketIndex = indexFor(hash, table.length)。


Entry节点插入机制?


通过扩容处理之后,调用createEntry(),将节点采用头插法插入到table数组指定位置中。


源代码:

   void addEntry(int hash, K key, V value, int bucketIndex) {
        if ((size >= threshold) && (null != table[bucketIndex])) {
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }


        createEntry(hash, key, value, bucketIndex);
    }


    void createEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<>(hash, key, value, e);
        size++;
    }

数据结构:





LinkedHashMap的扩容和插入机制与HashMap的实现机制相同,super.addEntry(hash, key, value, bucketIndex);


以下内容部分来源:http://zhangshixi.iteye.com/blog/673789


源代码:

    void addEntry(int hash, K key, V value, int bucketIndex) {
        super.addEntry(hash, key, value, bucketIndex);


        // Remove eldest entry if instructed
        Entry<K,V> eldest = header.after;
        if (removeEldestEntry(eldest)) {
            removeEntryForKey(eldest.key);
        }
    }


数据结构


上图显示了LinkedHashMap的链表部分数据结构,数组部分的数据结构和hashMap相同,仍然是一个table[bucketIndex];


总而言之,其实LinkedHashMap几乎和HashMap一样,不同的是它定义了一个Entry<K,V> header,这个header不是放在Table里,它是额外独立出来的,如图所示。LinkedHashMap通过继承hashMap中的Entry<K,V>,并添加两个属性Entry<K,V>  before,after,和header结合起来组成一个双向链表,来实现按插入顺序或访问顺序排序。


排序模式:


LinkedHashMap定义了排序模式accessOrder,该属性为boolean型变量。

  1. 对于访问顺序,为accessOrder=true,即采用LRU策略:按从近期访问最少到近期访问最多的顺序重排序。
  2. 对于插入顺序,则为accessOrder=false。

一般情况下,不必指定排序模式,其迭代顺序即为默认为插入顺序。看LinkedHashMap的构造方法,如:

    public LinkedHashMap(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);
        accessOrder = false;
    }

如果你想按照访问顺序构造一个LinkedHashMap,调用重构的构造函数:

   public LinkedHashMap(int initialCapacity,
                         float loadFactor,
                         boolean accessOrder) {
        super(initialCapacity, loadFactor);
        this.accessOrder = accessOrder;
    }

缓存模式:


接下来的代码用来更新缓存调用removeEldestEntry方法,这里就是实现LRU元素过期机制的地方,默认的情况下removeEldestEntry方法只返回false表示元素永远不过期


重写removeEldestEntry方法,维持此映射只保存100个条目的稳定状态,在每次添加新条目时删除最旧的条目。

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

基于LinkedHashMap实现LRU缓存调度算法原理 http://blog.csdn.net/langjian2012/article/details/45184303


修改部分内容参考自:http://www.cnblogs.com/children/archive/2012/10/02/2710624.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值