每个java程序员都知道,HashMap是java中最重要的集合类之一,也是找工作面试中非常常见的考点,因为HashMap的实现本身确实蕴含了很多精妙的代码设计。
public V put(K var1, V var2) {
return this.putVal(hash(var1), var1, var2, false, true);
}
final V putVal(int var1, K var2, V var3, boolean var4, boolean var5) {
HashMap.Node[] var6 = this.table;//首先获取map当前的node的数组
int var8;
if (this.table == null || (var8 = var6.length) == 0) {
var8 = (var6 = this.resize()).length;//判断当前node数组是否为空,如果为空的话,让其重新初始化,resize()方法
}
Object var7;
int var9;
if ((var7 = var6[var9 = var8 - 1 & var1]) == null) {
var6[var9] = this.newNode(var1, var2, var3, (HashMap.Node)null);//根据传进来的key的hash值计算当前要put的值存在哪个node下面,如果为空则新建一个
} else {
Object var10;
label79: {
Object var11;
if (((HashMap.Node)var7).hash == var1) { //在上一个if里面var7已经复制查找到的不为空的node,如果查找的hash和想要put进来的k的hash相等
var11 = ((HashMap.Node)var7).key;//赋值var11位当前node的key
if (((HashMap.Node)var7).key == var2 || var2 != null && var2.equals(var11)) {//判断node的key和所要插进来的key是否相等
var10 = var7;//将当前的 node赋值var10
break label79;
}
}
if (var7 instanceof HashMap.TreeNode) {//判断查找到的node如果已经是红黑数的时候
var10 = ((HashMap.TreeNode)var7).putTreeVal(this, var6, var1, var2, var3);//添加当前的值到数里面
} else {
int var12 = 0;
while(true) {//在这里用了个循环
var10 = ((HashMap.Node)var7).next;//在上面判断并且计算出要插入的值得key的hash要存的node下面,因为是链表结构,所以当以上情况都没有精要
//在当前的node下加入
if (((HashMap.Node)var7).next == null) {//如果下一个为null
((HashMap.Node)var7).next = this.newNode(var1, var2, var3, (HashMap.Node)null);//在当前链表下新加
if (var12 >= 7) {//判断当前链表的长度是否已经大于7
this.treeifyBin(var6, var1);//存成数结构
}
break;
}
if (((HashMap.Node)var10).hash == var1) {//如果当前的node的key相等
var11 = ((HashMap.Node)var10).key;
if (((HashMap.Node)var10).key == var2 || var2 != null && var2.equals(var11)) {
break;
}
}
var7 = var10;//如果以上情况都不存在,继续寻找下一个
++var12;//累计连边的长度
}
}
}
if (var10 != null) {//最后判断var10是否为空,如果不为空则在map里面已经存在和要存的值key相等,然后用新的value覆盖旧的
Object var13 = ((HashMap.Node)var10).value;
if (!var4 || var13 == null) {
((HashMap.Node)var10).value = var3;
}
this.afterNodeAccess((HashMap.Node)var10);
return var13;
}
}
++this.modCount;
if (++this.size > this.threshold) {
this.resize();
}
this.afterNodeInsertion(var5);
return null;
}
接下来就是get方法了
public V get(Object var1) {
HashMap.Node var2;
return (var2 = this.getNode(hash(var1), var1)) == null ? null : var2.value;
}
final HashMap.Node getNode(int var1, Object var2) {
HashMap.Node[] var3 = this.table;//获取当前node数组
HashMap.Node var4;
int var6;
if (this.table != null && (var6 = var3.length) > 0 && (var4 = var3[var6 - 1 & var1]) != null) {//判断数组不为空,并且获取到的hash存在的链表节点不为空
Object var7;
if (var4.hash == var1) {//如果就在当前链表的node和要查的key相等,直接返回房钱的node
var7 = var4.key;
if (var4.key == var2 || var2 != null && var2.equals(var7)) {
return var4;
}
}
HashMap.Node var5 = var4.next;//获取链表的下一个
if (var4.next != null) {
if (var4 instanceof HashMap.TreeNode) {//判断查到的是数结构的话,去查询红黑树
return ((HashMap.TreeNode)var4).getTreeNode(var1, var2);
}
do {//循环依次在当前的链表下查找,如果没有就返回null
if (var5.hash == var1) {
var7 = var5.key;
if (var5.key == var2 || var2 != null && var2.equals(var7)) {
return var5;
}
}
} while((var5 = var5.next) != null);
}
}
return null;
在源码里,我们可以看到里面一些put,get的方法都是调用自身的final心事的方法,里面的含义除了不被允许修改外应该还有其他一些含义,,,,,
而且在里面一些变量的复制都是在if或者fou里面直接赋值,没有一丝多余,干净,只不过看的让热头晕,,,