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修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)
transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被
transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被
transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被
transient修饰,均不能被序列化。
例外情况:
对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被
transient修饰无关。
###
3.2 native关键字
1。
native 是用做java 和其他语言(如c++)进行协作时用的也就是
native 后的函数的实现不是用java写的。
2。既然都不是java,那就别管它的源代码了
##
4.hashMap与hashSet的区别