海安零距离 海安论坛 海安新闻 海安

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2655|回复: 0

JDK源码分析-HashMap

[复制链接]

6234

主题

6234

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
18716
发表于 2019-12-27 18:12 | 显示全部楼层 |阅读模式
一.HashMap的内下属性

1.1 成员变量

1.1.1 size:

HashMap包罗的KV键值对的数量,也就是我们通常调用Map.size()方法的返回值
  1.     public int size() {        return size;    }
复制代码
1.1.2 modCount

HashMap的结构被修改的次数(包罗KV映射数量和内部结构rehash次数),用于判断迭代器梳理中不划一的快速失败。
  1. abstract class HashIterator {...  final Node nextNode() {            Node[] t;            Node e = next;            if (modCount != expectedModCount)                throw new ConcurrentModificationException();            if (e == null)                throw new NoSuchElementException();            if ((next = (current = e).next) == null && (t = table) != null) {                do {} while (index < t.length && (next = t[index++]) == null);            }            return e;        }...}
复制代码
1.1.3 threshold

下一次扩容时的阈值,到达阈值便会触发扩容机制resize(阈值 threshold = 容器容量 capacity * 负载因子 load factor)。也就是说,在容器界说好容量之后,负载因子越大,所能容纳的键值对元素个数就越多。盘算方法如下:
  1. 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 >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;    }
复制代码
1.1.4 loadFactor

负载因子,默认是0.75
1.1.5 Node[] table

底层数组,充当哈希表的作用,用于存储对应hash位置的元素,数组长度总是2的N次幂
1.2 内部类

1.2.1 Node
  1. /**     * 界说HashMap存储元素结点的底层实现     */    static class Node implements Map.Entry {        final int hash;//元素的哈希值 由final修饰可知,当hash的值确定后,就不能再修改        final K key;// 键,由final修饰可知,当key的值确定后,就不能再修改        V value; // 值        Node next; // 记载下一个元素结点(单链表结构,用于解决hash辩论)                /**         * Node结点构造方法         */        Node(int hash, K key, V value, Node next) {            this.hash = hash;//元素的哈希值            this.key = key;// 键            this.value = value; // 值            this.next = next;// 记载下一个元素结点        }        public final K getKey()        { return key; }        public final V getValue()      { return value; }        public final String toString() { return key + "=" + value; }        /**         * 为Node重写hashCode方法,值为:key的hashCode 异或 value的hashCode          * 运算作用就是将2个hashCode的二进制中,同一位置相同的值为0,差别的为1。         */        public final int hashCode() {            return Objects.hashCode(key) ^ Objects.hashCode(value);        }        /**         * 修改某一元素的值         */        public final V setValue(V newValue) {            V oldValue = value;            value = newValue;            return oldValue;        }        /**         * 为Node重写equals方法         */        public final boolean equals(Object o) {            if (o == this)                return true;            if (o instanceof Map.Entry) {                Map.Entry e = (Map.Entry)o;                if (Objects.equals(key, e.getKey()) &&                    Objects.equals(value, e.getValue()))                    return true;            }            return false;        }    }
复制代码
1.2.2 TreeNode
  1. static final class TreeNode extends LinkedHashMap.Entry {        //与left、right联合使用实现树结构           TreeNode parent;          TreeNode left;        TreeNode right;        // needed to unlink next upon deletion        TreeNode prev;           //记载树节点颜色         boolean red;     /**     * 操纵方法     * 包罗:树化、链栈化、增删查节点、根节点变更、树旋转、插入/删除节点后平衡红黑树     */     ...}
复制代码
1.3 Key的hash算法
Key的hash算法源码如下:
  1.   static final int hash(Object key) {        int h;         ///key.hashCode()为哈希算法,返回初始哈希值        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);    } 
复制代码
因为HashMap中是允许key 为null的键值对,以是先判断了key == null。当key 不为null的时间,hash算法是先通过key.hashCode()盘算出一个hash值再与改hash值的高16位做异或运算(有关异或运算请移步:java运算符 与(&)、非(~)、或(|)、异或(^)) 上面的key.hashCode()已经盘算出来了一个hash散列值,可以直接拿来用了,为何还要做一个异或运算? 是为了对key的hashCode举行扰动盘算(),防止差别hashCode的高位差别但低位相同导致的hash辩论。简朴点说,就是为了把高位的特性和低位的特性组合起来,低沉哈希辩论的概率,也就是说,只管做到任何一位的变革都能对终极得到的结果产生影响
二. HashMap的初始化

HashMap的初始化有以下四种方法:
<ol>HashMap()
HashMap(int initialCapacity)
HashMap(int initialCapacity, float loadFactor)
HashMap(Map
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|深圳论坛-深圳人的网上家园  

GMT+8, 2020-7-16 21:14 , Processed in 0.123667 second(s), 29 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表