文章目录
- HashMap中的循环链表是如何产生的?
- HashMap为什么用红黑树而不用B树?
- HashMap为什么线程不安全?
- HashMap和HashTable的区别
HashMap中的循环链表是如何产生的?
- 在多线程的情况下,当重新调整HashMap大小的时候,就会存在条件竞争,
- 因为如果两个线程都发现HashMap需要重新调整大小了,它们会同时试着调整大小。 在调整大小的过程中,存储在链表中的元素的次序会反过来,
- 因为移动到新的bucket位置的时候,HashMap并不会将元素放在链表的尾部,而是放在头部,这是为了避免尾部遍历。
- 如果条件竞争发生了,那么就会产生死循环了。
HashMap为什么用红黑树而不用B树?
- B/B 树多用于外存上时,B/B 也被成为一个磁盘友好的数据结构。
- HashMap本来是数组 链表的形式,链表由于其查找慢的特点,所以需要被查找效率更高的树结构来替换。
- 如果用B/B 树的话,在数据量不是很多的情况下,数据都会“挤在”一个结点里面,这个时候遍历效率就退化成了链表。
HashMap为什么线程不安全?
HashMap在并发执行put操作时,可能会导致形成循环链表,从而引起死循环。
HashMap和HashTable的区别
- Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现,所以HashMap比Hashtable的性能高一点。
- Hashtable不允许使用null作为key和value,如果试图把null值放进Hashtable中,将会引发空指针异常,但HashMap可以使用null作为key或value。
- 从Hashtable的类名上就可以看出它是一个古老的类,它的命名甚至没有遵守Java的命名规范:每个单词的首字母都应该大写。也许当初开发Hashtable的工程师也没有注意到这一点,后来大量Java程序中使用了Hashtable类,所以这个类名也就不能改为HashTable了,否则将导致大量程序需要改写。
- 与Vector类似的是,尽量少用Hashtable实现类,即使需要创建线程安全的Map实现类,也无须使用Hashtable实现类,可以通过Collections工具类把HashMap变成线程安全的Map。