ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 8 HashMap(一)—— 构造方法

2021-04-03 23:00:40  阅读:164  来源: 互联网

标签:Node Map Java HashMap 构造方法 int initialCapacity key


一、类属性

    //默认容量16
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
    //最大容量2的30次方
    static final int MAXIMUM_CAPACITY = 1 << 30;
    //默认加载因子0.75
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    //单个节点上的链表长度大于8时转换为红黑树
    static final int TREEIFY_THRESHOLD = 8;
    //单个节点上的红黑树大小小于6时退化为链表
    static final int UNTREEIFY_THRESHOLD = 6;
    //当最小容量大于64时单个节点上的链表才有可能转换为红黑树
    static final int MIN_TREEIFY_CAPACITY = 64;

二、对象属性

    //Node数组
    transient Node<K, V>[] table;
    //Entry集合
    transient Set<Map.Entry<K, V>> entrySet;
    //当前Map的长度
    transient int size;
    /**
     * 已对HashMap进行结构修改的次数。
     * 结构修改是指更改HashMap中的节点或以其他方式修改其内部结构(例如,节点的增加和修改)的修改。
     * 此字段用于使HashMap的Collection-view上的迭代器快速失败。
     * (请参见ConcurrentModificationException)
     */
    transient int modCount;
    /**
     * 下一个要调整大小的大小值(capacity*loadFactor),扩容位置。
     */
    int threshold;
    /**
     * 加载因子
     */
    final float loadFactor;

三、构造方法中会用到的方法

   /**
     * @return 大于当前传入数字的最小2次幂的值,如果结果大于最大允许容量,则返回最大运行容量值
     */
    static int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        if (n < 0) {
            return 1;
        } else {
            if (n >= MAXIMUM_CAPACITY) {
                return MAXIMUM_CAPACITY;
            } else {
                return n + 1;
            }
        }
    }
   /**
     * @param evict 最初构造此Map时为false,否则为true(中继到afterNodeInsertion方法)。
     */
    final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
        //获得参数Map的参数长度
        int s = m.size();
        if (s > 0) {
            //如果当前Map没有初始化
            if (table == null) {
                //计算参数Map出去当前Map的加载因子
                //作用在于如果参数Map大小+1设置为当前Map的threshold(扩容位置)是否会大于最大容量
                float ft = ((float) s / loadFactor) + 1.0F;
                //比较最大容量与ft,取小值;
                int t = ((ft < (float) MAXIMUM_CAPACITY) ?
                        (int) ft : MAXIMUM_CAPACITY);
                //如果t大于当前Map的threshold(扩容位置)
                if (t > threshold) {
                    //重新计算当前Map的扩容位置
                    threshold = tableSizeFor(t);
                }
            } else if (s > threshold) {
                //如果当前Map已经初始化,且参数Map的大小大于扩容位置
                //进行扩容
                resize();
            }
            //遍历参数Map的Node节点放入当前Map
            for (Entry<? extends K, ? extends V> e : m.entrySet()) {
                K key = e.getKey();
                V value = e.getValue();
                putVal(hash(key), key, value, false, evict);
            }
        }
    }

四、构造方法

    /**
     * 用HashMap(int initialCapacity, float loadFactor)和HashMap(int initialCapacity)
     * 方法创建HashMap对象会初始化扩容位置threshold,大小为tableSizeFor(initialCapacity)
     * 但是在初始化后会进行修正
     */

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

    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
    }

    public HashMap(Map<? extends K, ? extends V> m) {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        putMapEntries(m, false);
    }

五、其他一些方法

为下面的章节做铺垫

    /**
     * @return key为null返回0,key不为空返回key的后16位和前16位的异或运算结果
     */
    static <K> int hash(K key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
    
    Node<K, V> newNode(int hash, K key, V value, Node<K, V> next) {
        return new Node<>(hash, key, value, next);
    }

    /*用于从TreeNodes转换为Node*/
    Node<K, V> replacementNode(Node<K, V> p, Node<K, V> next) {
        return new Node<>(p.hash, p.key, p.value, next);
    }

    TreeNode<K, V> newTreeNode(int hash, K key, V value, Node<K, V> next) {
        return new TreeNode<>(hash, key, value, next);
    }

    /*用于从Node转换为TreeNode*/
    TreeNode<K, V> replacementTreeNode(Node<K, V> p, Node<K, V> next) {
        return new TreeNode<>(p.hash, p.key, p.value, next);
    }

标签:Node,Map,Java,HashMap,构造方法,int,initialCapacity,key
来源: https://blog.csdn.net/weixin_48872249/article/details/115422225

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有