学习自:
http://www.cnblogs.com/skywang12345/p/3310887.html
https://segmentfault.com/a/1190000008982905
网上能搜到很多相关链接,加之平时在项目中几乎没怎么见到,所以看我给出的链接即可。着重看下面我提出的问题,带着问题去思考可能更好。
问题
1.Hashtable
是不是线程安全的?为什么?
Hashtable
是线程安全的。因为其主要的方法均采用synchronized
(同步锁)修饰。
2.Hashtable
初始容量为何是11?
参考:https://www.zhihu.com/question/29587252 。Hashtable
默认大小是11是因为除(近似)质数求余的分散效果好。
1.8版本中Hashtable
通过rehash()
进行容量自增,里面有一段代码:
不难看出,先将容量自增为原容量的2倍+1,然后拿新容量与
Integer.MAX_VALUE - 8
比较,超出的话直接让容量等于Integer.MAX_VALUE - 8
。最终将新容量数组赋值给table
。
这样操作虽然不保证容量是一个质数,但起码能保证容量是一个奇数。
3.rehash
中int index = (e.hash & 0x7FFFFFFF) % newCapacity;
这段怎么理解?https://stackoverflow.com/questions/9380670/why-does-java-use-hash-0x7fffffff-tab-length-to-decide-the-index-of-a-key
这一步是为了计算扩容后的索引值。e.hash & 0x7FFFFFFF
会返回一个正数,% newCapacity
控制index
索引在容量范围内部。
4.HashMap
与Hashtable
在有很多相似的功能,那么为什么还需要他们两个同时存在?
Hashtabel
继承自Dictionary
,HashMap
继承自AbstractMap
。Dictionary
类已经废弃。Hashtabel
是线程安全的,而HashMap
不是。HashMap
的key
和value
可以为null
,但是Hashtable
不行。Hashtabel
在java 1.1 时就有了,而HashMap
是 java 1.2 才有的。在使用时一般用ArrayList
代替Vector
,LinkedList
代替Stack
,HashMap
代替HashTable
,即使在多线程中需要同步,也是用同步包装类。- 对于哈希值的使用也有所不同,
HashTable
直接使用对象的hashCode
,而HashMap
重新计算hash
值。而且用与代替求模。12345678Hashtable中:int hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;HashMap中static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}