JAVA8 hashmap源码阅读笔记(红黑树链表)

一:hashmap的13 个成员变量

  1. static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
    -> 数组默认初始容量:16
  2. static final int MAXIMUM_CAPACITY = 1 << 30;
    -> 数组最大容量2 ^ 30 次方
  3. static final float DEFAULT_LOAD_FACTOR = 0.75f;
    -> 默认负载因子的大小:0.75
  4. static final int MIN_TREEIFY_CAPACITY = 64;
    -> 树形最小容量:哈希表的最小树形化容量,超过此值允许表中桶转化成红黑树
  5. static final int TREEIFY_THRESHOLD = 8;
    -> 树形阈值:当链表长度达到8时,将链表转化为红黑树
  6. static final int UNTREEIFY_THRESHOLD = 6;
    -> 树形阈值:当链表长度小于6时,将红黑树转化为链表
  7. transient int modCount; -> hashmap修改次数
  8. int threshold; -> 可存储key-value 键值对的临界值 需要扩充时;值 = 容量 * 加载因子
  9. transient int size; 已存储key-value 键值对数量
  10. final float loadFactor; -> 负载因子
  11. transient Set< Map.Entry< K,V >> entrySet; -> 缓存的键值对集合
  12. transient Node< K,V>[] table; -> 链表数组(用于存储hashmap的数据)

二:构造方法

    /**
     * 默认无参构造方法:
     * 初始容量16
     * 负载因子0.75
     */
public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; 
    }
    /**
     * 参数为初始容量
     */
public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR); //调用HashMap(int initialCapacity, float loadFactor) 构造方法
    }
    /**
     * 参数为初始容量 和 负载因子
     */
public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
     if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }
    /**
     * 设置可存储的 key-value 键值对最大值
     * 返回值为传入参数最接近的且大于等于的2的n次方
     * 传入参数 3 -> 4
     * 传入参数 5 -> 8
     * 传入参数 32 -> 32
     * 传入参数 33 -> 64
     */
    static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= 1 << 30) ? 1 << 30 : n + 1;
    }
    /*
     * 构造一个新的 HashMap与指定的相同的映射 Map 。
     */
    public HashMap(Map<? extends K, ? extends V> m) {
       this.loadFactor = DEFAULT_LOAD_FACTOR;
       putMapEntries(m, false);
   }
   // 具体实现将map 内元素遍历插入hash表中
    final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
        int s = m.size();
        if (s > 0) {
            if (table == null) { // pre-size
                float ft = ((float)s / loadFactor) + 1.0F;// ft代表 在默认负载因子下,该hashmap的容量
                int t = ((ft < (float)MAXIMUM_CAPACITY) ?
                         (int)ft : MAXIMUM_CAPACITY);// 相当于执行 (int)Math.floor(ft);
                if (t > threshold)
                    threshold = tableSizeFor(t);// 重新设置临界值
            }
            else if (s > threshold)
                resize();
            // 一次将元素插入 后面详细讲解
            for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
                K key = e.getKey();
                V value = e.getValue();
                putVal(hash(key), key, value, false,evict);
            }
        }
    }

三:Node< K,V > 存储结构

// 用于存储key-value键值
// Map.Entry仅定义一些方法 因此不列出详细代码
  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值