一、HashMap简介
HashMap是在JDK1.2中引入的Map的实现类。
- HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。
- HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap。
- HashMap 实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆。
- HashMap存数据的过程是:
HashMap内部维护了一个存储数据的Entry数组,HashMap采用链表解决冲突,每一个Entry本质上是一个单向链表。当准备添加一个key-value对时,首先通过hash(key)方法计算hash值,然后通过indexFor(hash,length)求该key-value对的存储位置,计算方法是先用hash&0x7FFFFFFF后,再对length取模,这就保证每一个key-value对都能存入HashMap中,当计算出的位置相同时,由于存入位置是一个链表,则把这个key-value对插入链表头。
- HashMap中key和value都允许为null。key为null的键值对永远都放在以table[0]为头结点的链表中。
二、Hashtable简介
- Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。
- Hashtable也是JDK1.0引入的类,是线程安全的,能用于多线程环境中。
- Hashtable同样实现了Serializable接口,它支持序列化,实现了Cloneable接口,能被克隆。
三、比较
具体来说的话hashmap和hashtable一共有7个方面的不同,下面来介绍一下。
1、hash值不同
HashTable
:直接使用对象的hashCode
HashMap
:重新计算hash值
2、两个遍历方式的内部实现不同
Hashtable
、HashMap
两者都是使用了Iterator
,但是,因为一些历史原因,Hashtable
除了使用了Iterator
之外,还使用了Enumeration
。
3、是否提供contains方法
Hashtable
:Hashtable
和HashMap
不同,它保留了contains
、containsValue
以及containsKey
3个方法
HashMap
:它去掉了Hashtable
的contains
方法,改为了containsKey
和containsValue
4、内部实现使用的数组初始化和扩容方式不同
HashTable
:在不指定容量的情况下的默认容量为11;不要求底层数组的容量一定要为2的整数次幂;扩容时将容量变为原来的2倍加1。
HashMap
:在不指定容量的情况下的默认容量为16;要求一定为2的整数次幂;扩容时,将容量变为原来的2倍
HashTable
中hash数组默认大小是11,增加的方式是old*2+1
5、key和value是否允许null值
Hashtable
:key
和value
都不允许出现null
值
HashMap
:null
能够作为键,这样的键只有一个,能够有一个或者是多个键所对应的值为null
6、线程安全性不同
HashMap线程不安全,HashTable线程安全
Hashtable
:Hashtable
中的方法大多是Synchronize
的,在多线程并发的情况下,能够直接使用Hashtable
,HashTable
实现线程安全的代价就是效率变低,因为会锁住整个HashTable
。
HashMap
:在缺省情况下是非Synchronize
的;使用HashMap
的时候就需要自己增加同步处理;HashMap
是线程不安全的。
7、继承的父类不同
Hashtable
:继承Dictionary
类
HashMap
:继承AbstractMap
类
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/104933.html