标签:去掉 val 数组 线程安全 color value 冲突 遍历 空指针
HashTable类是通过数组+链表(单节点)实现的map集合,继承自Dictionary类,实现了三个接口,分别是Map,Cloneable和java.io.Serializable, 在初始化时有2个重要的参数,初始容量(默认11)和负载因子是0.75, Hashtable直接使用对象的hashCode值,使用除留余数发来获得最终的位置, put方法 put方法的主要逻辑如下: 先获取synchronized锁,如果value和key为null,直接抛出空指针异常,如果不为null,则获取key的hashcode值, 然后让hashcode值 & 0xFFFFFFF(int的最大值) 做按位与运算,将结果与数组的长度取模,得到插入元素位置的索引 而后通过索引获取对应Entry节点,如果节点为null,直接将值存入,如果不为null,则判断当前传入的hash值与entry的 hash值是否一致,equals是否相等,如果相等,则将新值替换成旧值,如果不相等,则将当前Entry节点赋值给next节点,将 新的值存入entry节点. 在添加时同样会判断当前entry数组中的长度是否大于了扩容阀值,会调用rehash()方法进行扩容 get方法 先获取synchronized锁,通过key的hash值做按位与运算,将结果与数组的长度取模,得到插入元素位置的索引 在对应位置的链表中寻找具有相同hash和key的节点,返回节点的value。 如果遍历结束都没有找到节点,则返回null。 HashMap和HashTable的区别: 1.继承上 Hashtable继承自Dictionary类,HashMap继承自AbstractMap类 但二者都实现了Map接口 2.构造上 Hashtable的默认容量为11,默认负载因子为0.75,Hashtable的容量可以为任意整数,最小值为1 HashMap默认容量为16,默认负载因子也是0.75,而HashMap的容量始终为2的n次方 3.线程安全性上 Hashtable是线程安全的,它里面的方法都加了synchronized HashMap是线程不安全的,效率高,会报并发修改异常 4.是否为null上 HashMap允许null可以作为键,但是能有一个 Hashtable中key和value都不允许为null,会报空指针异常 5.索引效率上的不同 hashtable使用的是key的hashcode值做按位与运算,目的是将值转化成正值,因为hash值有可能为负,而后再对数组长度取模运算 hashmap是将key再进行hashcode取值,将值右移16位后做^(按位异或运算),最后再与数组长度-1 做按位与运算,效率较高 6.解决hashcode冲突上的不同 hashtable使用的是Entry节点来保证冲突的 hashmap是使用链表|红黑树来保证hashcode冲突的
7.遍历方式的不同 Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式
8.contains方法上的不同 hashtable有contains,containsValue和containsKey三个方法 hashMap把contains方法去掉了,只保留了containsKey和containsValue方法
标签:去掉 val 数组 线程安全 color value 冲突 遍历 空指针
原文地址:https://www.cnblogs.com/MrRightZhao/p/12631544.html