如何在源码上添加自己的注释
打开jdk下载位置
解压src文件夹,打开idea,ctrl+shift+alt+s打开项目配置
选择jdk版本1.7,然后点击Sourcepath
选择刚刚解压的src文件目录,然后选择src.zip的文件点击- 号,项目中只留下刚才解压的src文件即可
打开源码,输入时会出一个提示框,直接点击ok即可,然后就可以输入自己的注释了
在开始前先了解一下JDK1.7的HashMap的数据结构,就算没有研究过源码也听过JDK1.7中HashMap是数组加链表,1.8中是数组加链表加红黑树,今天我们主要研究1.7,首先数组肯定都知道,链表这个一听以为是很难的东西,其实一点也不难
什么叫链表呢,以java代码形式
假设现在有一个节点,里有具体的值和下一个节点的引用
public class Node{ private int number; private Node next; }当节点的next引用指向下一个Node节点,许多的节点连接起来就叫做链表
JDK1.7的数据结构就是如下图所示
在开始前建议自己跟着打开对应的类,方法来自己看一看源码,不然很容易就不知道在哪里了
HashMap中的全局变量 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; static final int MAXIMUM_CAPACITY = 1 << 30; static final float DEFAULT_LOAD_FACTOR = 0.75f; static final Entry<?, ?>[] EMPTY_TABLE = {}; transient Entry<K, V>[] table = (Entry<K, V>[]) EMPTY_TABLE; transient int size; int threshold; final float loadFactor; transient int modCount;我们来看一下全局变量,简单描述一下它们的作用
DEFAULT_INITIAL_CAPACITY默认的初始容量,而大小使用了一个左移运算符,怎么来看它的值呢?java中所有的位运算都是在二进制的情况下进行的
首先1的二进制是 0000 0001 而<< 4 符号的意思是将所有的数字往左边移动4位,移出来的位置用0替换
也就是 0001 0000 转换为10进制就是16,也就是HashMap的默认容量
MAXIMUM_CAPACITY最大容量,也是使用位运算符,1<<30 转换为10进制就是1073741824
DEFAULT_LOAD_FACTOR默认的负载因子,默认为0.75f,现在可能不太清楚先有个印象即可
Entry[] EMPTY_TABLE初始化的一个空数组
Entry<K, V>[] table = (Entry<K, V>[]) EMPTY_TABLE真正存储数据的数组
size存储元素的个数,map.size()方法就是直接返回这个变量
public int size() { return size; } threshold临界值,当容量到达这个容量是进行判断是否扩容,而这个临界值计算公式就是,容量大小乘以负载因子,如果初始化没有设置map的大小和负载因子的话,默认就是16*0.75=12
loadFactor如果创建HashMap时设置了负载因子,那么会赋值给这个变量,没有特殊需求的话一般不需要设置这个值,太大导致链表过长,影响get方法,太小会导致经常进行扩容浪费性能
modCountHashMap的结构被修改的次数,用于迭代器
构造方法首先来看无参构造
public HashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); }调用了重载的构造,传入的就是默认大小(16)和默认的负载因子大小(0.75f)
那么我们来看有参构造
public HashMap(int initialCapacity, float loadFactor) { //初始容量不能小于0 if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); //初始容量是否大于最大容量 if (initialCapacity > MAXIMUM_CAPACITY) //如果大于最大容量,则将容量设置为最大容量 initialCapacity = MAXIMUM_CAPACITY; //如果负载系数小于0或者不是一个数字抛出异常 if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); // 设置负载因子,临界值此时为容量大小,后面第一次put时由inflateTable(int toSize)方法计算设置 this.loadFactor = loadFactor; threshold = initialCapacity; //空方法,由其他实现类实现 init(); } put方法