转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46481759
在Android编程或者面试中经常会遇到JAVA 面向对象和集合的知识点。自己结合实际的编程以及阅读网上资料总结一下。
java面向对象
==和equal()的区别
- 基本数据类型。
byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==),比较的是他们的值。 - 复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在JVM中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为也是比较对象的内存地址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。 - String的equal()
(1)String类中的equals首先比较地址,如果是同一个对象的引用,可知对象相等,返回true。
(2)若果不是同一个对象,equals方法挨个比较两个字符串对象内的字符,只有完全相等才返回true,否则返回false。
String、StringBuffer、StringBuilder的区别
String 字符串常量(对象不可变,线程安全)
private final char value[];
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
char[] value;
如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。
在大部分情况下 StringBuilder > StringBuffer> String
final, finally, finalize的区别
- final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
- finally是异常处理语句结构的一部分,表示总是执行。
- finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
Overload和Override的区别
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被”屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。
java 继承
extends关键字,子类扩展了父类,也具有父类的全部成员变量和方法,但是Java的子类不能获得父类的构造器。
Java没有C++中的多继承特征,每个类最多只有一个直接父类(单继承)
当调用子类构造器来初始化子类对象时,父类构造器总会在子类构造器之前执行。
创建任何Java对象,最先执行的总是java.lang.object类的构造器,从该类所在继承树最顶层类的构造器开始执行,然后依次向下执行。
Java多态
如果Java引用变量的编译时类型和运行时类型不一致是,就可能出现多态。
运行时该引用变量的方法总是表现出子类方法的行为特征。(出现重写)
Java中多态的实现方式:接口实现,继承父类进行方法重写(父类引用指向子类对象),同一个类中进行方法重载。
抽象类和接口的区别
接口和抽象类的概念不一样。接口是对动作的抽象(吃),抽象类是对根源的抽象(人)。
一个类只能继承一个类(抽象类),但是可以实现多个接口(吃,行)。
1. 接口可以多继承,抽象类不行
2. 抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
3. 接口中基本数据类型为public static 而抽类象不是,是普通变量类型。
4. 抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
5. 抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
内部类作用
放在一个类的内部的类我们就叫内部类。
作用
1. 内部类可以很好的实现隐藏,方便将存在一定逻辑关系的类组织在一起。
一般的非内部类,是不允许有private与protected权限的,但内部类可以。
2. 内部类拥有外围类的所有元素的访问权限。
3. 可是实现多重继承,每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整。
4. 可以避免修改接口而实现同一个类中两种同名方法的调用。
5. 方便编写线程代码。
java对象序列化
- 概念
序列化:把Java对象转换为字节序列的过程。
反序列化:把字节序列恢复为Java对象的过程。
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。
读取对象的顺序与写入时的顺序要一致。
对象的默认序列化机制写入的内容是:对象的类,类签名,以及非瞬态和非静态字段的值。 - 用途
对象的序列化主要有两种用途:
1) 把对象转换成平台无关的二进制流永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
java集合
HashSet类
hashSet用Hash算法来存储集合中的元素,具有很好的存取和查找性能。
特点:
1. 无序
2. 不是同步的
3. 集合元素值可为null
4. 不允许包含相同的元素
存入一个元素:
HashSet调用该对象的hashCode()方法得到hashCode值,根据该hashCode值确定该对象的存储位置。
访问一个元素:
HashSet先计算该元素的hashCode值,然后直接到该hashCode值对应的位置去取出该元素。
如果元素相同则添加失败add()返回false。
HashSet集合判断两个元素相同的标准是两个对象equals()方法比较相等,并且hashCode值也相等。
如果两个对象的hashCode值相同,equals()返回false时,会在同一个位置用链式结构来保存。导致性能下降。
ArrayList和Vector有何异同点
ArrayList和Vector在很多时候都很类似。
1. 两者都是基于索引的,内部由一个数组支持。
2. 两者维护插入的顺序,我们可以根据插入顺序来获取元素。
3. ArrayList和Vector的迭代器实现都是fail-fast的。
4. ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。
以下是ArrayList和Vector的不同点。
1. Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
2. ArrayList比Vector快,它因为有同步,不会过载。
3. ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。
HashMap类和Hashtable类
HashMap和Hashtable判断两个key相等的标准是两个key的equals()方法比较返回true,并且hashCode值也相等。
对同一个Key,只会有一个对应的value值存在。
如何算是同一个Key? 首先,两个key对象的hash值相同,其次,key对象的equals方法返回真
所以用做key的对象必须重写equals()和hashCode()方法,保证两个方法的判断标准一致——两个key的equals方法返回真,hashCode值也相同。
HashMap和Hashtable的区别
- HashMap允许key和value为null,而HashTable不允许。
- HashTable是同步的(线程安全),而HashMap不是(线程不安全)。所以HashMap适合单线程环境,HashTable适合多线程环境。HashMap比HashTable的性能高点。
- HashMap和Hashtable中key-value对无序。但在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的。
- HashMap提供对key的Set进行iterator遍历,因此它是fail-fast的,但Hashtable提供对key的Enumeration进行遍历,它不支持fail-fast。(fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。)
- Hashtable被认为是个遗留的类,如果你寻求在迭代的时候修改Map,你应该使用CocurrentHashMap。
- HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
hashCode()和equals()方法有何重要性
- hashCode是根类Obeject中的方法。
默认情况下,Object中的hashCode() 返回对象的32位jvm内存地址。也就是说如果对象不重写该方法,则返回相应对象的32为JVM内存地址。 - HashMap使用Key对象的hashCode()和equals()方法去决定key-value对的索引。当我们试着从HashMap中获取值的时候,这些方法也会被用到。如果这些方法没有被正确地实现,在这种情况下,两个不同Key也许会产生相同的hashCode()和equals()输出,HashMap将会认为它们是相同的,然后覆盖它们,而非把它们存储到不同的地方。同样的,所有不允许存储重复数据的集合类都使用hashCode()和equals()去查找重复,所以正确实现它们非常重要。equals()和hashCode()的实现应该遵循以下规则:
2.1 如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()总是为true的。
2.2 如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。
在Java中,HashMap是如何工作的?
HashMap在Map.Entry静态内部类实现中存储key-value对。HashMap使用哈希算法,在put和get方法中,它使用hashCode()和equals()方法。当我们通过传递key-value对调用put方法的时候,HashMap使用Key hashCode()和哈希算法来找出存储key-value对的索引。Entry存储在LinkedList中,所以如果存在entry,它使用equals()方法来检查传递的key是否已经存在,如果存在,它会覆盖value,如果不存在,它会创建一个新的entry然后保存。当我们通过传递key调用get方法时,它再次使用hashCode()来找到数组中的索引,然后使用equals()方法找出正确的Entry,然后返回它的值。
其它关于HashMap比较重要的问题是容量、负荷系数和阀值调整。HashMap默认的初始容量是32,负荷系数是0.75。阀值是为负荷系数乘以容量,无论何时我们尝试添加一个entry,如果map的大小比阀值大的时候,HashMap会对map的内容进行重新哈希,且使用更大的容量。容量总是2的幂,所以如果你知道你需要存储大量的key-value对,比如缓存从数据库里面拉取的数据,使用正确的容量和负荷系数对HashMap进行初始化是个不错的做法。
HashMap源码剖析
跟着兰亭风雨走就行了,很强大:
http://blog.csdn.net/ns_code/article/details/36034955
<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">package java.util; import java.io.*; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 默认的初始容量(容量为HashMap中槽的数目)是16,且实际容量必须是2的整数次幂。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> DEFAULT_INITIAL_CAPACITY = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换) </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> MAXIMUM_CAPACITY = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 默认加载因子为0.75 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> DEFAULT_LOAD_FACTOR = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.75</span>f; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 存储数据的Entry数组,长度是2的幂。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap采用链表法解决冲突,每一个Entry本质上是一个单向链表 </span> transient Entry[] table; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap的底层数组中已用槽的数量 </span> transient <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> size; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap的阈值,用于判断是否需要调整HashMap的容量(threshold = 容量*加载因子) </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> threshold; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 加载因子实际大小 </span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> loadFactor; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap被改变的次数 </span> transient <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">volatile</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> modCount; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 指定“容量大小”和“加载因子”的构造函数 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">HashMap</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> initialCapacity, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> loadFactor) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (initialCapacity < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IllegalArgumentException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Illegal initial capacity: "</span> + initialCapacity); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap的最大容量只能是MAXIMUM_CAPACITY </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//加载因此不能小于0</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (loadFactor <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> || Float.isNaN(loadFactor)) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IllegalArgumentException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Illegal load factor: "</span> + loadFactor); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 找出“大于initialCapacity”的最小的2的幂 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> capacity = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (capacity < initialCapacity) capacity <<= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置“加载因子” </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.loadFactor = loadFactor; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置“HashMap阈值”,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。 </span> threshold = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)(capacity * loadFactor); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建Entry数组,用来保存数据 </span> table = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Entry[capacity]; init(); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 指定“容量大小”的构造函数 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">HashMap</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> initialCapacity) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>(initialCapacity, DEFAULT_LOAD_FACTOR); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 默认构造函数。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">HashMap</span>() { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置“加载因子”为默认加载因子0.75 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.loadFactor = DEFAULT_LOAD_FACTOR; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置“HashMap阈值”,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。 </span> threshold = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建Entry数组,用来保存数据 </span> table = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Entry[DEFAULT_INITIAL_CAPACITY]; init(); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 包含“子Map”的构造函数 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">HashMap</span>(Map<? extends K, ? extends V> m) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>(Math.max((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) (m.size() / DEFAULT_LOAD_FACTOR) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将m中的全部元素逐个添加到HashMap中 </span> putAllForCreate(m); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//求hash值的方法,重新计算hash值</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> h) { h ^= (h >>> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>) ^ (h >>> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">12</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> h ^ (h >>> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>) ^ (h >>> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回h在数组中的索引值,这里用&代替取模,旨在提升效率 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// h & (length-1)保证返回值的小于length </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> indexFor(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> h, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> length) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> h & (length-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">size</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> size; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">isEmpty</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> size == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取key对应的value </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> V <span class="hljs-title" style="box-sizing: border-box;">get</span>(Object key) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (key == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> getForNullKey(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取key的hash值 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash = hash(key.hashCode()); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在“该hash值对应的链表”上查找“键值等于key”的元素 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Entry<K,V> e = table[indexFor(hash, table.length)]; e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; e = e.next) { Object k; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//判断key是否相同</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.hash == hash && ((k = e.key) == key || key.equals(k))) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//没找到则返回null</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取“key为null”的元素的值 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap将“key为null”的元素存储在table[0]位置,但不一定是该链表的第一个位置! </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> V <span class="hljs-title" style="box-sizing: border-box;">getForNullKey</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Entry<K,V> e = table[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]; e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; e = e.next) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.key == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap是否包含key </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">containsKey</span>(Object key) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> getEntry(key) != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回“键为key”的键值对 </span> final Entry<K,V> getEntry(Object key) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取哈希值 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap将“key为null”的元素存储在table[0]位置,“key不为null”的则调用hash()计算哈希值 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash = (key == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) ? <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> : hash(key.hashCode()); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在“该hash值对应的链表”上查找“键值等于key”的元素 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Entry<K,V> e = table[indexFor(hash, table.length)]; e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; e = e.next) { Object k; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.hash == hash && ((k = e.key) == key || (key != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && key.equals(k)))) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> e; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将“key-value”添加到HashMap中 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> V <span class="hljs-title" style="box-sizing: border-box;">put</span>(K key, V <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若“key为null”,则将该键值对添加到table[0]中。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (key == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> putForNullKey(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash = hash(key.hashCode()); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = indexFor(hash, table.length); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Entry<K,V> e = table[i]; e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; e = e.next) { Object k; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出! </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span> = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; e.recordAccess(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> oldValue; } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若“该key”对应的键值对不存在,则将“key-value”添加到table中 </span> modCount++; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将key-value添加到table[i]处</span> addEntry(hash, key, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>, i); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// putForNullKey()的作用是将“key为null”键值对添加到table[0]位置 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> V <span class="hljs-title" style="box-sizing: border-box;">putForNullKey</span>(V <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Entry<K,V> e = table[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]; e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; e = e.next) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.key == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { V oldValue = e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span> = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; e.recordAccess(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> oldValue; } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 如果没有存在key为null的键值对,则直接题阿见到table[0]处! </span> modCount++; addEntry(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建HashMap对应的“添加方法”, </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 它和put()不同。putForCreate()是内部方法,它被构造函数等调用,用来创建HashMap </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 而put()是对外提供的往HashMap中添加元素的方法。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">putForCreate</span>(K key, V <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash = (key == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) ? <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> : hash(key.hashCode()); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = indexFor(hash, table.length); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若该HashMap表中存在“键值等于key”的元素,则替换该元素的value值 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Entry<K,V> e = table[i]; e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; e = e.next) { Object k; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.hash == hash && ((k = e.key) == key || (key != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && key.equals(k)))) { e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span> = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若该HashMap表中不存在“键值等于key”的元素,则将该key-value添加到HashMap中 </span> createEntry(hash, key, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>, i); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将“m”中的全部元素都添加到HashMap中。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 该方法被内部的构造HashMap的方法所调用。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">putAllForCreate</span>(Map<? extends K, ? extends V> m) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 利用迭代器将元素逐个添加到HashMap中 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) { Map.Entry<? extends K, ? extends V> e = i.next(); putForCreate(e.getKey(), e.getValue()); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 重新调整HashMap的大小,newCapacity是调整后的容量 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> resize(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> newCapacity) { Entry[] oldTable = table; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> oldCapacity = oldTable.length; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果就容量已经达到了最大值,则不能再扩容,直接返回</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (oldCapacity == MAXIMUM_CAPACITY) { threshold = Integer.MAX_VALUE; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 新建一个HashMap,将“旧HashMap”的全部元素添加到“新HashMap”中, </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 然后,将“新HashMap”赋值给“旧HashMap”。 </span> Entry[] newTable = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Entry[newCapacity]; transfer(newTable); table = newTable; threshold = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)(newCapacity * loadFactor); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将HashMap中的全部元素都添加到newTable中 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> transfer(Entry[] newTable) { Entry[] src = table; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> newCapacity = newTable.length; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; j < src.length; j++) { Entry<K,V> e = src[j]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { src[j] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">do</span> { Entry<K,V> next = e.next; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>); } } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将"m"的全部元素都添加到HashMap中 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">putAll</span>(Map<? extends K, ? extends V> m) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 有效性判断 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> numKeysToBeAdded = m.size(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (numKeysToBeAdded == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 计算容量是否足够, </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若“当前阀值容量 < 需要的容量”,则将容量x2。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (numKeysToBeAdded > threshold) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> targetCapacity = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)(numKeysToBeAdded / loadFactor + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (targetCapacity > MAXIMUM_CAPACITY) targetCapacity = MAXIMUM_CAPACITY; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> newCapacity = table.length; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (newCapacity < targetCapacity) newCapacity <<= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (newCapacity > table.length) resize(newCapacity); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 通过迭代器,将“m”中的元素逐个添加到HashMap中。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) { Map.Entry<? extends K, ? extends V> e = i.next(); put(e.getKey(), e.getValue()); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 删除“键为key”元素 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> V <span class="hljs-title" style="box-sizing: border-box;">remove</span>(Object key) { Entry<K,V> e = removeEntryForKey(key); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (e == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ? <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> : e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 删除“键为key”的元素 </span> final Entry<K,V> removeEntryForKey(Object key) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取哈希值。若key为null,则哈希值为0;否则调用hash()进行计算 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash = (key == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) ? <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> : hash(key.hashCode()); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = indexFor(hash, table.length); Entry<K,V> prev = table[i]; Entry<K,V> e = prev; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 删除链表中“键为key”的元素 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 本质是“删除单向链表中的节点” </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { Entry<K,V> next = e.next; Object k; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.hash == hash && ((k = e.key) == key || (key != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && key.equals(k)))) { modCount++; size--; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (prev == e) table[i] = next; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> prev.next = next; e.recordRemoval(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> e; } prev = e; e = next; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> e; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 删除“键值对” </span> final Entry<K,V> removeMapping(Object o) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!(o instanceof Map.Entry)) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; Map.Entry<K,V> entry = (Map.Entry<K,V>) o; Object key = entry.getKey(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash = (key == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) ? <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> : hash(key.hashCode()); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = indexFor(hash, table.length); Entry<K,V> prev = table[i]; Entry<K,V> e = prev; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 删除链表中的“键值对e” </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 本质是“删除单向链表中的节点” </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { Entry<K,V> next = e.next; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.hash == hash && e.equals(entry)) { modCount++; size--; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (prev == e) table[i] = next; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> prev.next = next; e.recordRemoval(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> e; } prev = e; e = next; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> e; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 清空HashMap,将所有的元素设为null </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">clear</span>() { modCount++; Entry[] tab = table; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < tab.length; i++) tab[i] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; size = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 是否包含“值为value”的元素 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">containsValue</span>(Object <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若“value为null”,则调用containsNullValue()查找 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span> == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> containsNullValue(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若“value不为null”,则查找HashMap中是否有值为value的节点。 </span> Entry[] tab = table; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < tab.length ; i++) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Entry e = tab[i] ; e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ; e = e.next) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>.equals(e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>)) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 是否包含null值 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> boolean <span class="hljs-title" style="box-sizing: border-box;">containsNullValue</span>() { Entry[] tab = table; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < tab.length ; i++) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Entry e = tab[i] ; e != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ; e = e.next) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span> == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 克隆一个HashMap,并返回Object对象 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Object <span class="hljs-title" style="box-sizing: border-box;">clone</span>() { HashMap<K,V> result = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { result = (HashMap<K,V>)super.clone(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (CloneNotSupportedException e) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// assert false; </span> } result.table = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Entry[table.length]; result.entrySet = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; result.modCount = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; result.size = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; result.init(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 调用putAllForCreate()将全部元素添加到HashMap中 </span> result.putAllForCreate(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Entry是单向链表。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 它是 “HashMap链式存储法”对应的链表。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 它实现了Map.Entry 接口,即实现getKey(), getValue(), setValue(V value), equals(Object o), hashCode()这些函数 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> class Entry<K,V> implements Map.Entry<K,V> { final K key; V <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 指向下一个节点 </span> Entry<K,V> next; final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 构造函数。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 输入参数包括"哈希值(h)", "键(k)", "值(v)", "下一节点(n)" </span> Entry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> h, K k, V v, Entry<K,V> n) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span> = v; next = n; key = k; hash = h; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final K <span class="hljs-title" style="box-sizing: border-box;">getKey</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> key; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final V <span class="hljs-title" style="box-sizing: border-box;">getValue</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final V <span class="hljs-title" style="box-sizing: border-box;">setValue</span>(V newValue) { V oldValue = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span> = newValue; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> oldValue; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 判断两个Entry是否相等 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若两个Entry的“key”和“value”都相等,则返回true。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 否则,返回false </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final boolean <span class="hljs-title" style="box-sizing: border-box;">equals</span>(Object o) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!(o instanceof Map.Entry)) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; Map.Entry e = (Map.Entry)o; Object k1 = getKey(); Object k2 = e.getKey(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (k1 == k2 || (k1 != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && k1.equals(k2))) { Object v1 = getValue(); Object v2 = e.getValue(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (v1 == v2 || (v1 != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && v1.equals(v2))) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 实现hashCode() </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">hashCode</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (key==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ? <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> : key.hashCode()) ^ (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ? <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>.hashCode()); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final String <span class="hljs-title" style="box-sizing: border-box;">toString</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> getKey() + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"="</span> + getValue(); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 当向HashMap中添加元素时,绘调用recordAccess()。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 这里不做任何处理 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> recordAccess(HashMap<K,V> m) { } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 当从HashMap中删除元素时,绘调用recordRemoval()。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 这里不做任何处理 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> recordRemoval(HashMap<K,V> m) { } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 新增Entry。将“key-value”插入指定位置,bucketIndex是位置索引。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> addEntry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash, K key, V <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> bucketIndex) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 保存“bucketIndex”位置的值到“e”中 </span> Entry<K,V> e = table[bucketIndex]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置“bucketIndex”位置的元素为“新Entry”, </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置“e”为“新Entry的下一个节点” </span> table[bucketIndex] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Entry<K,V>(hash, key, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>, e); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若HashMap的实际大小 不小于 “阈值”,则调整HashMap的大小 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (size++ >= threshold) resize(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> * table.length); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建Entry。将“key-value”插入指定位置。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> createEntry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash, K key, V <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> bucketIndex) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 保存“bucketIndex”位置的值到“e”中 </span> Entry<K,V> e = table[bucketIndex]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置“bucketIndex”位置的元素为“新Entry”, </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置“e”为“新Entry的下一个节点” </span> table[bucketIndex] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Entry<K,V>(hash, key, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>, e); size++; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashIterator是HashMap迭代器的抽象出来的父类,实现了公共了函数。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 它包含“key迭代器(KeyIterator)”、“Value迭代器(ValueIterator)”和“Entry迭代器(EntryIterator)”3个子类。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">abstract</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> HashIterator<E> implements Iterator<E> { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 下一个元素 </span> Entry<K,V> next; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// expectedModCount用于实现fast-fail机制。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> expectedModCount; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 当前索引 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> index; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 当前元素 </span> Entry<K,V> current; HashIterator() { expectedModCount = modCount; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (size > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// advance to first entry </span> Entry[] t = table; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将next指向table中第一个不为null的元素。 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 这里利用了index的初始值为0,从0开始依次向后遍历,直到找到不为null的元素就退出循环。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (index < t.length && (next = t[index++]) == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) ; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final boolean <span class="hljs-title" style="box-sizing: border-box;">hasNext</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> next != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取下一个元素 </span> final Entry<K,V> nextEntry() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (modCount != expectedModCount) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ConcurrentModificationException(); Entry<K,V> e = next; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> NoSuchElementException(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 注意!!! </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 一个Entry就是一个单向链表 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 若该Entry的下一个节点不为空,就将next指向下一个节点; </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 否则,将next指向下一个链表(也是下一个Entry)的不为null的节点。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((next = e.next) == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { Entry[] t = table; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (index < t.length && (next = t[index++]) == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) ; } current = e; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> e; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 删除当前元素 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">remove</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (current == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IllegalStateException(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (modCount != expectedModCount) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ConcurrentModificationException(); Object k = current.key; current = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; HashMap.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.removeEntryForKey(k); expectedModCount = modCount; } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// value的迭代器 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> ValueIterator extends HashIterator<V> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> V <span class="hljs-title" style="box-sizing: border-box;">next</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> nextEntry().<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>; } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// key的迭代器 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> KeyIterator extends HashIterator<K> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> K <span class="hljs-title" style="box-sizing: border-box;">next</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> nextEntry().getKey(); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Entry的迭代器 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> EntryIterator extends HashIterator<Map.Entry<K,V>> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Map.Entry<K,V> <span class="hljs-title" style="box-sizing: border-box;">next</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> nextEntry(); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回一个“key迭代器” </span> Iterator<K> newKeyIterator() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> KeyIterator(); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回一个“value迭代器” </span> Iterator<V> newValueIterator() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ValueIterator(); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回一个“entry迭代器” </span> Iterator<Map.Entry<K,V>> newEntryIterator() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> EntryIterator(); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// HashMap的Entry对应的集合 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> transient Set<Map.Entry<K,V>> entrySet = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回“key的集合”,实际上返回一个“KeySet对象” </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Set<K> <span class="hljs-title" style="box-sizing: border-box;">keySet</span>() { Set<K> ks = keySet; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (ks != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ? ks : (keySet = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> KeySet())); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Key对应的集合 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// KeySet继承于AbstractSet,说明该集合中没有重复的Key。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> KeySet extends AbstractSet<K> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Iterator<K> <span class="hljs-title" style="box-sizing: border-box;">iterator</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> newKeyIterator(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">size</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> size; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">contains</span>(Object o) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> containsKey(o); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">remove</span>(Object o) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> HashMap.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.removeEntryForKey(o) != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">clear</span>() { HashMap.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.clear(); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回“value集合”,实际上返回的是一个Values对象 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Collection<V> <span class="hljs-title" style="box-sizing: border-box;">values</span>() { Collection<V> vs = values; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (vs != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ? vs : (values = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Values())); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// “value集合” </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Values继承于AbstractCollection,不同于“KeySet继承于AbstractSet”, </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Values中的元素能够重复。因为不同的key可以指向相同的value。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> Values extends AbstractCollection<V> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Iterator<V> <span class="hljs-title" style="box-sizing: border-box;">iterator</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> newValueIterator(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">size</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> size; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">contains</span>(Object o) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> containsValue(o); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">clear</span>() { HashMap.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.clear(); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回“HashMap的Entry集合” </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Set<Map.Entry<K,V>> <span class="hljs-title" style="box-sizing: border-box;">entrySet</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> entrySet0(); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回“HashMap的Entry集合”,它实际是返回一个EntrySet对象 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Set<Map.Entry<K,V>> <span class="hljs-title" style="box-sizing: border-box;">entrySet0</span>() { Set<Map.Entry<K,V>> es = entrySet; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> es != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ? es : (entrySet = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> EntrySet()); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// EntrySet对应的集合 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// EntrySet继承于AbstractSet,说明该集合中没有重复的EntrySet。 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> EntrySet extends AbstractSet<Map.Entry<K,V>> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Iterator<Map.Entry<K,V>> <span class="hljs-title" style="box-sizing: border-box;">iterator</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> newEntryIterator(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">contains</span>(Object o) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!(o instanceof Map.Entry)) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; Map.Entry<K,V> e = (Map.Entry<K,V>) o; Entry<K,V> candidate = getEntry(e.getKey()); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> candidate != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && candidate.equals(e); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">remove</span>(Object o) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> removeMapping(o) != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">size</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> size; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">clear</span>() { HashMap.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.clear(); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// java.io.Serializable的写入函数 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将HashMap的“总的容量,实际容量,所有的Entry”都写入到输出流中 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">writeObject</span>(java.io.ObjectOutputStream s) throws IOException { Iterator<Map.Entry<K,V>> i = (size > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) ? entrySet0().iterator() : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Write out the threshold, loadfactor, and any hidden stuff </span> s.defaultWriteObject(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Write out number of buckets </span> s.writeInt(table.length); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Write out size (number of Mappings) </span> s.writeInt(size); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Write out keys and values (alternating) </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (i.hasNext()) { Map.Entry<K,V> e = i.next(); s.writeObject(e.getKey()); s.writeObject(e.getValue()); } } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> serialVersionUID = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">362498820763181265</span>L; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// java.io.Serializable的读取函数:根据写入方式读出 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将HashMap的“总的容量,实际容量,所有的Entry”依次读出 </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">readObject</span>(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Read in the threshold, loadfactor, and any hidden stuff </span> s.defaultReadObject(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Read in number of buckets and allocate the bucket array; </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> numBuckets = s.readInt(); table = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Entry[numBuckets]; init(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Give subclass a chance to do its thing. </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Read in size (number of Mappings) </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> size = s.readInt(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Read the keys and values, and put the mappings in the HashMap </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i<size; i++) { K key = (K) s.readObject(); V <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span> = (V) s.readObject(); putForCreate(key, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回“HashMap总的容量” </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> capacity() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> table.length; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回“HashMap的加载因子” </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> loadFactor() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> loadFactor; } } </code>