HashMap实现原理分析(5)

put方法的基本过程如下:
(1)对key的hashcode进行hash计算,获取应该保存到数组中的index。
(2)判断index所指向的数组元素是否为空,如果为空则直接插入。
(3)如果不为空,则依次查找entry中next所指定的元素,判读key是否相等,如果相等,则替换旧的值,返回。
(4)如果都不相等,则将此链表头元素赋值给待插入Node的next变量,让后将待插入元素插入到Node数组中去。
(5)Java 8 在没有降低哈希冲突的度的情况下,使用红黑书代替链表,

static final int TREEIFY_THRESHOLD = 8; static final int UNTREEIFY_THRESHOLD = 6; ``` 展示了Java 8的HashMap在使用树和使用链表之间切换的阈值。当冲突的元素数增加到8时,链表变为树;当减少至6时,树切换为链表。中间有2个缓冲值的原因是避免频繁的切换浪费计算机资源。 Java 8 HashMap使用的树是红黑树,它的实现基本与JCF中的TreeMap相同。通常,树的有序性通过两个或更多对象比较大小来保证。Java 8 HashMap中的树也通过对象的Hash值(这个hash值与哈希桶索引值不同,索引值在这个hash值的基础上对桶大小M取模,译者注)作为对象的排序键。因为使用Hash值作为排序键打破了Total Ordering(可以理解为数学中的小于等于关系,译者注),因此这里有一个tieBreakOrder()方法来处理这个问题。 ###2.2.5 get 方法

public V get(Object key) {
Node

从上面的代码以及注释中可以看出,get操作还是比较简单的,先是根据key进行hash映射,得到其在table中的index,然后遍历真个Entry[index]链表。 ##3.java 关键字 ###3.1 transient的作用及使用方法 一个对象只要实现了Serilizable接口,这个对象就可以被序列化。将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。 1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。 2transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。 3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。 例外情况: 对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。 ###3.2 native关键字 1native 是用做java 和其他语言(如c++)进行协作时用的也就是native 后的函数的实现不是用java写的。 2。既然都不是java,那就别管它的源代码了 ##4.hashMap与hashSet的区别

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/ba84f9159fcb5ef51d4a9c2beef7571d.html