HashMap 和 Hashtable 是 Java 开发程序员必须要掌握的,也是在各种 Java 面试场合中必须会问到的。

但你对这两者的区别了解有多少呢?

现在,栈长我给大家总结一下,或许有你不明朗的地方,在栈长的指点下都会拨开迷雾见晴天。

1、线程安全

Hashtable 是线程安全的,HashMap 不是线程安全的。

为什么说 HashTable 是线程安全的?

来看下 Hashtable 的源码,Hashtable 所有的元素操作都是 synchronized 修饰的,而 HashMap 并没有。

public synchronized V put(K key, V value);
public synchronized V get(Object key);
...

2、性能优劣

既然 Hashtable 是线程安全的,每个方法都要阻塞其他线程,所以 Hashtable 性能较差,HashMap 性能较好,使用更广。

如果要线程安全又要保证性能,建议使用 JUC 包下的 ConcurrentHashMap。

3、NULL

Hashtable 是不允许键或值为 null 的,HashMap 的键值则都可以为 null。

那么问题来了,为什么 Hashtable 是不允许 KEY 和 VALUE 为 null, 而 HashMap 则可以?

Hashtable put 方法逻辑:

 public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
} // Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode(); ... }

HashMap hash 方法逻辑:

static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

可以看出 Hashtable key 为 null 会直接抛出空指针异常,value 为 null 手动抛出空指针异常,而 HashMap 的逻辑对 null 作了特殊处理。

4、实现方式

Hashtable 的继承源码:

public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable

HashMap 的继承源码:

public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable

可以看出两者继承的类不一样,Hashtable 继承了 Dictionary类,而 HashMap 继承的是 AbstractMap 类。

Dictionary 是 JDK 1.0 添加的,貌似没人用过这个,栈长我也没用过。。

5、容量扩容

HashMap 的初始容量为:16,Hashtable 初始容量为:11,两者的负载因子默认都是:0.75。

/**
* Constructs a new, empty hashtable with a default initial capacity (11)
* and load factor (0.75).
*/
public Hashtable() {
this(11, 0.75f);
} /**
* Constructs an empty <tt>HashMap</tt> with the default initial capacity
* (16) and the default load factor (0.75).
*/
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

当现有容量大于总容量 * 负载因子时,HashMap 扩容规则为当前容量翻倍,Hashtable 扩容规则为当前容量翻倍 + 1。

6、迭代器

HashMap 中的 Iterator 迭代器是 fail-fast 的,而 Hashtable 的 Enumerator 不是 fail-fast 的。

所以,当其他线程改变了HashMap 的结构,如:增加、删除元素,将会抛出 ConcurrentModificationException 异常,而 Hashtable 则不会。

可以来看下这个区别的演示:

/**
* 微信公众号:Java技术栈
**/
public static void main(String[] args) {
Map<String, String> hashtable = new Hashtable<>();
hashtable.put("t1", "1");
hashtable.put("t2", "2");
hashtable.put("t3", "3"); Enumeration<Map.Entry<String, String>> iterator1 = (Enumeration<Map.Entry<String, String>>) hashtable.entrySet().iterator();
hashtable.remove(iterator1.nextElement().getKey());
while (iterator1.hasMoreElements()) {
System.out.println(iterator1.nextElement());
} Map<String, String> hashMap = new HashMap<>();
hashMap.put("h1", "1");
hashMap.put("h2", "2");
hashMap.put("h3", "3"); Iterator<Map.Entry<String, String>> iterator2 = hashMap.entrySet().iterator();
hashMap.remove(iterator2.next().getKey());
while (iterator2.hasNext()) {
System.out.println(iterator2.next());
} }

输出信息:

t2=2
t1=1
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
at java.util.HashMap$EntryIterator.next(HashMap.java:1476)
at java.util.HashMap$EntryIterator.next(HashMap.java:1474)
at cn.javastack.Test.main(Test.java:37)

看到了吧?

所以,这条同样也是 Enumeration 和 Iterator 的区别。

最后一点有几个人知道?知道的给栈长点个赞回应一下,不知道的有收获的也点一个赞支持一下吧。

有收获?转发给更多的人吧!

本文原创首发于微信公众号:Java技术栈(id:javastack),关注公众号在后台回复 "java" 可获取更多,转载请原样保留本信息。

HashMap 和 Hashtable 的 6 个区别,最后一个没几个人知道!的更多相关文章

  1. HashMap和Hashtable及HashSet的区别

    相关文章1:HashSet,TreeSet和LinkedHashSet的区别 相关文章2:HashSet和TreeSet的区别 Hashtable类     Hashtable继承Map接口,实现一个 ...

  2. java面试题之HashMap和HashTable底层实现的区别

    HashMap和HashTable的区别: 相同点:都是以key和value的形式存储: 不同点: HashMap是不安全的:HashTable线程安全的(使用了synchronized关键字来保证线 ...

  3. java中hashmap和hashtable和hashset的区别

    hastTable和hashMap的区别:(1)Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现.(2)这个不同即是最重要的一点:Ha ...

  4. HashMap和Hashtable的联系和区别

    实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用,早期的版本一般都是安全的. HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分 ...

  5. HashMap、Hashtable和ConcurrentHashMap的区别

    HashTable 底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相 ...

  6. HashMap和Hashtable以及ConcurrentHashMap的区别

    ​ HashMap和Hashtable的区别 何为HashMap HashMap是在JDK1.2中引入的Map的实现类. HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部 ...

  7. hashMap、hashTable、treeMap的区别

    1.hashTable是线程安全的.hashMap不是线程安全的 hashmap 线程不安全 允许有null的键和值 效率高一点. 方法不是Synchronize的要提供外同步 有containsva ...

  8. HashMap、HashTable与ConcurrentHashMap的区别

    1.HashTable与HashMap (1)HashTable和HashMap都实现了Map接口,但是HashTable的实现是基于Dictionary抽象类. (2)在HashMap中,null可 ...

  9. HashMap 和 Hashtable 的 6 个区别

    HashMap 是非常重要且常用的一种集合,还有一个和它类似的集合即Hashtable,有必要知道它们之间的区别. 1.线程安全: Hashtable 是线程安全的,HashMap 则不是线程安全的. ...

随机推荐

  1. VB中将类标记为可序列化

    引用名空间: Imports SystemImports System.Runtime.Serialization 在类前加特性: <Serializable> 更多内容: https:/ ...

  2. java 日志体系目录

    java 日志体系目录 1.1 java 日志体系(一)log4j1.log4j2.logback.jul.jcl.slf4j 1.2 java 日志体系(二)jcl 和 slf4j 2.1 java ...

  3. https及证书

    本文试图以通俗易通的方式介绍Https的工作原理,不纠结具体的术语,不考证严格的流程.我相信弄懂了原理之后,到了具体操作和实现的时候,方向就不会错,然后条条大路通罗马.阅读文本需要提前大致了解对称加密 ...

  4. sql server 临时库文件太大 迁移tempdb数据库

    由于装SQL Server时默认装在系统盘,使用一段时间后,tempdb数据库占了68G,导致整个C盘爆满,彻底解决办法就是迁移tempdb物理文件,移至其他大空间磁盘上. 将 tempdb 从其在磁 ...

  5. sql中varchar(n),nvarchar(n) 长度性能及所占空间分析

    sql中varchar(n),nvarchar(n) 长度性能及所占空间分析 1.varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. ...

  6. Beta冲刺吐槽&&获小黄衫心得

    引 个人感觉本次Beta冲刺最大的槽点还是--反向延长 "冲刺周期" 做的不一样很容易,做的更好才是非常困难的 遗留的问题 经历了Alpha冲刺,组内大多数同学也大都对实践感到些许 ...

  7. Codeforces Round #539 (Div. 2) C Sasha and a Bit of Relax

    题中意思显而易见,即求满足al⊕al+1⊕…⊕amid=amid+1⊕amid+2⊕…⊕ar且l到r的区间长为偶数的这样的数对(l,r)的个数. 若al⊕al+1⊕…⊕amid=amid+1⊕amid ...

  8. python 基础 ------字符串的调用详解(1)

    Python 字符串的的调用方法~~~ 废话不多说直接奔主题 >>>>>>>>>>>>>>>>> ...

  9. Python19/1/11--标签与过滤器/Django模块导入继承/静态文件配置

      1 模板语言之变量: -{{ }} 相当于执行了print -深度查询 . 如果是方法,不能加括号,不能传参数2 过滤器 {{ 变量|过滤器的名字:'参数' }} -add -default -s ...

  10. http跳转https

    参考:http://www.cnblogs.com/tielemao/p/6386362.html webconfig中增加: <configuration> <system.web ...