资源描述:
《java8系列之重新认识hashmap-编程开发技术》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、Java8系列Z重新认识HashMap-编程开发技术Java8系列之重新认识HashMap原文出处:前利简介Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要右四个常用的实现类,分别是HashMap>Hashtable、LinkedHashMap和TreeMap,类继承关系如下图所示:下面针对各个实现类的特点做一些说明:(1)HashMap:它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。HashMap最多只允许一条记录的键为null,允许多条记录的值为nulloHashMa
2、p非线程安全,即任一时刻可以有多个线程同时HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrcntHashMapo(2)Hashtable:Hashtable是遗留类,很多映射的常用功能与HashMap类似,不同的是它承自Dictionary类,并口是线程安全的,任一时间只有一个线程能写Hashtable,并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。Hashtable不建议在新代码中使用,
3、不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。(1)LinkedHashMap:LinkedHashMap是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的,也可以在构造吋带参数,按照访问次序排序。⑷TreeMeip:TreeMap实现SortedMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。如果使用排序的映射,建议使用Tre
4、eMap0在使用TreeMap时,key必须实现Comparable接口或者在构造TreeMap传入口定义的Comparator,否则会在运行时抛出java.lang.ClassCastException类型的异常。对于上述四种Map类型的类,要求映射中的key是不可变对象。不可变对象是该对象在创建后它的哈希值不会被改变。如杲对象的哈希值发生变化,Map对象很可能就定位不到映射的位置了。通过上面的比较,我们知道了HashMap是Java的Map家族中一个普通成员,鉴于它可以满足大多数场景的使用条件,所以是使用频度最高的一个。下文我们主要结合源码,从存储结构、常用方法分析、扩
5、容以及安全性等方面深入讲解HashMap的工作原理。内部实现搞清楚HashMap,首先需要知道HashMap是什么,即它的存储结构-字段;其次弄明白它能干什么,即它的功能实现-方法。下面我们针对这两个方面详细展开讲解。存储结构-字段从结构实现来讲,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,如下如所示。数组table「■二i;=Node!转换为红黑树这里需要讲明口两个问题:数据底层具体存储的是什么?口这样的存储方式有什么口优点呢?(1)从源码可知,HashMap类中有一个非常重要的字段,就是Node[]table,即哈希桶数组,明显它
6、是一个Node的数组。我们来看Node[JDK1.8]是何物。staticclassNodeimplementsMap.Entry〈K,V>{finalinthash;//用來定位数组索引位置finalKkey;Vvalue;Nodenext;//链表的下一个nodeNode(inthash,Kkey,Vvalue,Nodenext){...}publicfinalKgetKeyO{...}publicfinalVgctValucO{・・・}publicpublicpublicpublicfinalbooleanequals(Objecto)}
7、finalStringtoString(){...}finalinthashCode(){...}finalVsetValue(VnewValue){...Node是HashMap的一个内部类,实现了Map.Entry接口,本质是就足一个映射(键值对)。上图中的每个黑色圆点就是一个Node对象。(2)HashMap就是使用哈希表来存储的。哈希表为解决冲突,可以采用开放地址法和链地址法等來解决问题,Java中HashMap采用了链地址法。链地址法,简单来说,就是数组加链表的结合。在每个数组元素上都一个链表结构,当数据