HashMap与LinkedHashMap的区别

#HashMap与LinkedHashMap的区别 ##LinkedHashMap类代码 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> 从类的声明来看LinkedHashMap继承自HashMap。那么两者有什么区别呢?

  • linkedHashMap是有序的。

  • private transient Entry<K,V> header; 这个是整个链表的头。

    void init() { header = new Entry<>(-1, null, null, null); header.before = header.after = header; } 在初始化时候对双向链表进行维护。

    //这个entity就是每个key-value对应的实体类, 因为继承自HashMap.Entity,所以自带HashMap.Entity的next,get等属性 private static class Entry<K,V> extends HashMap.Entry<K,V> { // These fields comprise the doubly linked list used for iteration. Entry<K,V> before, after;

      Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
          super(hash, key, value, next);
      }
    
      //删除当前节点, 将当前链表的收尾重新拼接
      private void remove() {
          before.after = after;
          after.before = before;
      }
    
      /**
       * Inserts this entry before the specified existing entry in the list.
       */
      private void addBefore(Entry<K,V> existingEntry) {
          after  = existingEntry;
          before = existingEntry.before;
          before.after = this;
          after.before = this;
      }
    
      /**
       * This method is invoked by the superclass whenever the value
       * of a pre-existing entry is read by Map.get or modified by Map.set.
       * If the enclosing Map is access-ordered, it moves the entry
       * to the end of the list; otherwise, it does nothing.
       */
      void recordAccess(HashMap<K,V> m) {
          LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
          if (lm.accessOrder) {
              lm.modCount++;
              remove();
              addBefore(lm.header);
          }
      }
    
      void recordRemoval(HashMap<K,V> m) {
          remove();
      }
    

    } 在HashMap.Entity的基础上添加before和after,构成一个双向链表。

  • 构造函数不同, 添加了accessOrder 用户选择排序的方式

  •   accessOrder     the ordering mode - <tt>true</tt> for
    	access-order, <tt>false</tt> for insertion-order
    

在构造方法中如果设置为true的话, 那么就按照访问的顺序排序(LRU)否则按照插入顺序排序。

##hashMap添加元素代码

public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

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添加元素代码 ###因为LinkedHashMap extends HashMap 所以LinkedHashMap拥有HashMap所有方法。LinkedHashMap集合在添加方法时,默认调用父元素的方法, 并维护双向链表。LinkedHashMap 重写了 addEntry和 createEntry。 ####addEntry 添加了移除最旧使用的条目。 在LRU中用到 ####createEntry 在原来的方法上添加了对链表的维护

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);
    }
}

/**
 * This override differs from addEntry in that it doesn't resize the
 * table or remove the eldest entry.
 */
void createEntry(int hash, K key, V value, int bucketIndex) {
    HashMap.Entry<K,V> old = table[bucketIndex];
    Entry<K,V> e = new Entry<>(hash, key, value, old);
    table[bucketIndex] = e;
    e.addBefore(header);
    size++;
}

转载于:https://my.oschina.net/xbding/blog/700203

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值