HashMap和ConcurrentHashMap
HashMap :HashMap是线程不安全的,在并发环境下,可能会形成环状链表,导致get操作时,cpu空转,所以,在并发环境中使用HashMap是非常危险的。
HashTable : 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
, HashTable和HashMap的实现原理几乎一样,差别无非是1.HashTable不允许key和value为null;2.HashTable是线程安全的。但是HashTable线程安全的策略实现代价却太大了,简单粗暴,get/put所有相关操作都是synchronized的,这相当于给整个哈希表加了一把大锁,多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞,相当于将所有的操作串行化,在竞争激烈的并发场景中性能就会非常差。
ConcurrentHashMap:HashTable性能差主要是由于所有操作需要竞争同一把锁,而如果容器中有多把锁,每一把锁锁一段数据,这样在多线程访问时不同段的数据时,就不会存在锁竞争了,这样便可以有效地提高并发效率。这就是ConcurrentHashMap所采用的"分段锁"思想。
HashMap
哈希表:利用了通过下标定位一次就可以查找到元素的特性,哈希表的主干是数组,再加上链表或者红黑树来应对哈希冲突
哈希冲突:不同元素经过哈希函数的计算得出的存储位置相同。
1、HashXXX(HashSet,HashMap)和TreeXXX(TreeSet,TreeMap)的区别?
①底层实现:HashXXX基于数组、链表、红黑树;TreeXXX基于红黑树。
②元素要求:HashXXX是无序存储,允许存放null;TreeXXX是有序存储(实现比较器),不允许存放null
③使用要求:HashXXX需要覆写equals()和HashCode();TreeXXX需要实现Comparable接口或传入Comparator比较器。
2、HashMap底层究竟是如何实现?
HashMap的底层,JDK1.8是基于数组、链表、红黑树实现,HashMap采用懒加载,第一次put的时候才会初始化哈希表(resize()方法)。默认数组初始化长度16(1<<4)
3.HashMap怎么确定当前元素在数组中的位置?
首先根据HashMap中的hash()函数(h&#