1、静态方法和实例方法的区别
2、ArrayList和HashMap的区别
3、HashMap的底层原理
一、静态方法和实例方法有何不同?
在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。
二、ArrayList和HashMap的区别
ArrayList和HashMap的capacity都是16,它俩扩容一次的结果分别是24,32,ArrayList扩容翻0.75倍,HashMap翻1倍,为什么?原因:1是通过计算出来的hash,高位保留,低位与高位做异或,得到一个hash值,与15做与操作,也就是对16取余,就是在数组中的桶,这个特点只对2的幂次方生效;2是扩容的时候需要做re哈希过程,re哈希过程需要把这个元素从原来的列表上去放置低位或者高位这俩个选择上,而出现高位或者低位选择的原因是因为%16和%32得到的结果可能是俩个结果,一个是在原来的位置上不动,一个是要放到高位上(高位上加了个16),这个特点也只对2的幂次方生效。也就是因为这俩个特点HashMap扩容必须是2的幂次方,一次翻一倍;而ArrayList不存在一个re哈希的过程,不存在列表出现,它就是在数组上依次往后排,它每次就扩容一小部分。arraylist也可以扩容一倍,但是它浪费空间,它对2的幂次方不敏感。
三、HashMap底层原理
默认初始化大小(DEFAULT_INITIAL_CAPACITY)是1左移4位,
最大容量maximum_capacity(MAXIMUM_CAPACITY)是1左移30位;
默认加载因子(DEFAULT_LOAD_FACTOR)=0.75,
默认加载阈值=16*0.75=12;
树化阈值(TREEIFY_THRESHOLD)=8;
注:满足树化的俩个条件:一个链超过8,数组的容量达到64。
从树塌缩成列表的的阈值(UNTREEIFY_THRESHOLD)=6;
最小树化容量(MIN_TREEIFY_CAPACITY)=64;
HashMap put 一个value会发生什么,put的时候会调用putValue,putValue会先计算hash值,过程是:高位保留,低位与高位做异或,得到一个它的hash值,与15做与操作,也就是对16取余,得到的值就是在数组中的位置(桶);如果这个桶为空直接放,如果这个桶有值,第一判断key的HoshCode和之前放的HoshCode值是否一样,第二key的物理内存地址和之前放的物理内存地址是否一样,第三它俩是否equals,如果有任何一个过程成立就将value替换掉,如果不成立就判断下一个key是不是相等,如果都不相等,到了最后一个就把这个元素插入(万一出现了key值一样,覆盖这个值,如果没有出现,替换掉)
如果放置的内容的个数大于TREEIFY_THRSHOLD -1,现在就要做treeify,如果到了64就要扩容,就要做re哈希过程:把它和老的容量相与,与如果等于0它就在低位,如果不等于0,它就移到高位上去,位置就是加上老容量。
re哈希完了以后,列表有可能小于8,这是一种扩容过程。}