HashMap子类的介绍

2021-09-06 14:19:09 浏览数 (1)

HashMap简单介绍

Java为数据结构中的映射定义了一个接口java.util.Map,分别是HashMap、Hashtable、LinkedHashMap和TreeMap,类继承关系如下图所示:

JDK1.8之前,哈希表底层采用数组 链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。

*​ JDK1.8中,哈希表存储采用数组 链表 红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间 各个子类的简单介绍以及使用场景:

HashMap:它是根据HashCode值来存储数据,大多数的情况下可以直接定位到它的值,所以访问数据挺快的。HashMap保证的键的唯一不重复,需要重写的ashcode() 和 quals() 方法。 在非并发操作的情况下,HashMap就可以完成正常的需求。需要注意一点,HashMap是非线程安全的,任一时刻可以有多个线程同时重写HashMap,可能会导致数据的不一致,而且多线程的环境下,HashMap进行put操作会引起死循环,故在并发情况下,不能使用hashMap。

ConcurrentHashMap:介绍HashMap中说到了它的使用场景中多线程会有线程不安全的问题,既然问题出现,就会有解决的方法。我这边介绍两个方案,一是使用Collections的 synchronizedMap方法使HashMap具有线程安全的能力,二就是使用concurrentHashMap。ConcurrentHashMap 是设计为非阻塞的。在更新时会局部锁住某部分数据,但不会把整个表都锁住。同步读取操作则是完全非阻塞的。好处是在保证合理的同步前提下,效率很高。坏处是严格来说读取操作不能保证反映最近的更新。例如线程A调用putAll写入大量数据,期间线程B调用get,则只能get到目前为止已经顺利插入的部分数据。

https://blog.csdn.net/ji1162765575/article/details/111309612

应该根据具体的应用场景选择合适的HashMap。

Hashtable:功能与HashMap类似,不通点是,承自Dictionary类,并且是线程安全的,但在任一时间只有一个线程能写Hashtable,并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。Hashtable不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。

LinkedHashMap:LinkedHashMap是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的,也可以在构造时带参数,按照访问次序排序。在需要保证顺序的情境下,使用LinkedHashMap。

TreeMap:TreeMap实现SortedMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。如果使用排序的映射,建议使用TreeMap。在使用TreeMap时,key必须实现Comparable接口或者在构造TreeMap传入自定义的Comparator,否则会在运行时抛出java.lang.ClassCastException类型的异常。

0 人点赞