前言
之前有讲到过两种List集合,ArrayList底层是使用数组实现的,LinkedList是使用双向链表实现的。HashMap更像是两者的结合,底层采用了数组+单向链表+红黑树的结构,HashMap的底层结构是一个数组(哈希桶),而数组的元素是一个单向链表,链表中的每一个节点对应了hash表中的每一个元素。当数组长度大于8的时候,就会转化为红黑树,以提升查询和插入的效率。特点是:遍历时无序、线程不安全(体现在内部迭代器中,下次一起再写)。
继承关系
继承了AbstractMap类,AbstractMap中提供了一些主要方法,提供了map的所有操作方法实现Map接口,Map接口在AbstractMap中就已经实现了,这里也不顶大用,但Java的很多集合类都这么做的实现Cloneable接口,是为了使用Object.clon()方法,不实现也可以使用,但是会抛出异常。实现Serializable接口,表示该类可以被实例化数据结构
Node的定义//实际存储数据的数组,是一个NodeK,V类型的数组,NodeK,V是一个内部类
transientNodeK,V[]table;
//内部类,HashMap底层数组的组成元素
staticclassNodeK,VimplementsMap.EntryK,V{
finalinthash;
//哈希值
finalKkey;
//元素的key
Vvalue;
//元素的value
NodeK,Vnext;
//当前元素的下一个元素
//构造方法
Node(inthash,Kkey,Vvalue,NodeK,Vnext){
this.hash=hash;
this.key=key;
this.value=value;
this.next=next;
}
//返回当前元素的Key
publicfinalKgetKey(){
returnkey;
}
//返回当前元素的value
publicfinalVgetValue(){
returnvalue;
}
//返回当前元素的key+value
publicfinalStringtoString(){
returnkey+=+value;
}
//重写Object类的hashCode方法,返回的值是key的hashCode值和value的hashCode值进行异或运算
publicfinalinthashCode(){
//^Java异或运算符,转成二进制后逐个进行运算,得到一个数字,这个数字是0或是自己
//例如inta=4^6;4对应的二进制数为:(0);6对应的是:(0)
//运算方程是:inta=0^0;运算过程:00=0;11=0;01=1;00=0
//运算的结果就是:(二进制),对应转换成十进制就是2
returnObjects.hashCode(key)^Objects.hashCode(value);
}
//设置一个新的值返回旧的值
publicfinalVsetValue(VnewValue){
VoldValue=value;
value=newValue;
returnoldValue;
}
//重写Object类的equals方法,用于判断是否相等
publicfinalBooleanequals(Objecto){
if(o==this)
returntrue;
//如果类型是Map.Entry
if(oinstanceofMap.Entry){
Map.Entry?,?e=(Map.Entry?,?)o;
//且键键、值值都相等,那么返回true
if(Objects.equals(key,e.getKey())
Objects.equals(value,e.getValue()))
returntrue;
}
returnfalse;
}
}
读者福利:转发+