首页 > 试题广场 >

HashMap和Hashtable有什么区别?

[问答题]
HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
HashMap允许键和值是null,而Hashtable不允许键或者值是null。
Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
一般认为Hashtable是一个遗留的类。
发表于 2019-04-28 16:21:36 回复(0)
更多回答

1、HashMap是非线程安全的,HashTable是线程安全的。

2、HashMap的键和值都允许有null值存在,而HashTable则不行。

3、因为线程安全的问题,HashMap效率比HashTable的要高。
4、Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。

    一般现在不建议用HashTable, ①是HashTable是遗留类,内部实现很多没优化和冗余。②即使在多线程环境下,现在也有同步的ConcurrentHashMap替代,没有必要因为是多线程而用HashTable。
发表于 2017-03-27 12:44:15 回复(4)

ConcurrentHashMap具体是怎么实现线程安全的呢,肯定不可能是每个方法加synchronized,那样就变成了HashTable。

从ConcurrentHashMap代码中可以看出,它引入了一个“分段锁”的概念,具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。

在ConcurrentHashMap中,就是把Map分成了N个Segment,put和get的时候,都是现根据key.hashCode()算出放到哪个Segment中:

发表于 2017-07-21 15:24:29 回复(0)
甘头像
实际上一般现在不建议用HashTable, 一是HashTable是遗留类,内部实现很多没优化和冗余。其次即使在多线程环境下,现在也有同步的ConcurrentHashMap替代,没有必要因为是多线程而用HashTable。

还有一点, HashMap只允许一个key为null,使用的情况可以参考:
http://stackoverflow.com/questions/2945309/what-is-the-use-of-adding-a-null-key-or-value-to-a-hashmap-in-java
发表于 2016-07-27 08:54:28 回复(0)
HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
HashMap允许键和值是null,而Hashtable不允许键或者值是null。
Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
一般认为Hashtable是一个遗留的类。
发表于 2015-10-29 12:10:41 回复(2)
三个值得注意的地方,一是hashmap允许键或值为空,二十hashtable是线程同步的,先天适合多线程的环境,三是hashtable可以返回对对键的枚举

此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。

为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。

Hashtable 的实例有两个参数影响其性能:初始容量 和加载因子容量 是哈希表中 的数量,初始容量 就是哈希表创建时的容量。注意,哈希表的状态为 open:在发生“哈希冲突”的情况下,单个桶会存储多个条目,这些条目必须按顺序搜索。加载因子 是对哈希表在其容量自动增加之前可以达到多满的一个尺度。初始容量和加载因子这两个参数只是对该实现的提示。关于何时以及是否调用 rehash 方法的具体细节则依赖于该实现。

通常,默认加载因子(.75)在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查找某个条目的时间(在大多数Hashtable 操作中,包括 get 和 put 操作,都反映了这一点)。

初始容量主要控制空间消耗与执行 rehash 操作所需要的时间损耗之间的平衡。如果初始容量大于 Hashtable 所包含的最大条目数除以加载因子,则永远 不会发生 rehash 操作。但是,将初始容量设置太高可能会浪费空间。

如果很多条目要存储在一个 Hashtable 中,那么与根据需要执行自动 rehashing 操作来增大表的容量的做法相比,使用足够大的初始容量创建哈希表或许可以更有效地插入条目。

下面这个示例创建了一个数字的哈希表。它将数字的名称用作键:

   Hashtable<String, Integer> numbers
     = new Hashtable<String, Integer>();
   numbers.put("one", 1);
   numbers.put("two", 2);
   numbers.put("three", 3);

要获取一个数字,可以使用以下代码:

   Integer n = numbers.get("two");
     if (n != null) {
         System.out.println("two = " + n);
     }}

由所有类的“collection 视图方法”返回的 collection 的 iterator 方法返回的迭代器都是快速失败 的:在创建 Iterator 之后,如果从结构上对 Hashtable 进行修改,除非通过 Iterator 自身的 remove 方法,否则在任何时间以任何方式对其进行修改,Iterator 都将抛出ConcurrentModificationException。因此,面对并发的修改,Iterator 很快就会完全失败,而不冒在将来某个不确定的时间发生任意不确定行为的风险。由 Hashtable 的键和元素方法返回的 Enumeration  是快速失败的。

注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误做法:迭代器的快速失败行为应该仅用于检测程序错误。

从Java 2 平台 v1.2起,此类就被改进以实现 Map 接口,使它成为 Java Collections Framework 中的一个成员。不像新的 collection 实现,Hashtable 是同步的

编辑于 2016-01-20 22:27:14 回复(2)
HashMap允许键和值是null,而Hashtable不允许键或者值是null。

两者散列计算方式不同,因此HashMap Capacity高位运算,取模运算,需要Capacity是 2的幂次(用户输入不足,自动补足)。
int index = (hash & 0x7FFFFFFF) % tab.length;//Hashtable因此Capacity无要求。 

扩容方式不同HashMap变为原来的2倍。
newThr = oldThr << 1; // double threshold HashMap扩容为原来的两倍
int newCapacity = (oldCapacity << 1) + 1;//Hashtable 扩容2倍 + 1;

Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。

HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。一般认为Hashtable是一个遗留的类。
编辑于 2020-12-14 09:58:06 回复(0)
HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。 Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
发表于 2019-08-14 17:55:45 回复(1)

1⃣️:hashmap 线程不安全,hashtable 线程安全。

2⃣️:hashmap 允许null ,hashtable 不允许null

3⃣️:hash map 线程不安全,故效率高,hashtable ,线程安全,效率相比较低

4⃣️:hash table 同步,更适合单线程,hashtable 更适合多线程环境。

五:hashtable 是遗留类,有很多没优化和冗余,故,hashtable 少用。

发表于 2019-05-12 10:56:21 回复(0)
什么是线程安全。简单地说,你看一个类里面每个方法都加了synchronized修饰符,那它就是线程安全的。 既然类里面每一个操作都加了线程同步操作,那么在外面就不用再写synchronized了。 比如Vector和ArrayList,二者唯一的区别就是Vector每个方法都自带同步机制。 这样的话,比如我要往集合里面加一个元素,又要保证多个线程不会同时调用同一个对象的add()方法,ArrayList里面就要酱紫写: ArrayList&lt;String&gt; list = new ArrayList&lt;&gt;(); synchronized (list) { list.add(&quot;233&quot;); } 而Vector里面只要酱紫写就行了: Vector&lt;String&gt; list = new Vector&lt;&gt;(); list.add(&quot;233&quot;); 为什么? 因为ArrayList的add方法是酱紫定义的: public boolean add(E object) { ... } 而Vector的add方法是酱紫定义的: public synchronized boolean add(E object) { ..... } 所以同样调用add()方法,对Vector对象再加synchronized就是多此一举。
编辑于 2017-01-04 11:45:56 回复(0)
补充几点: 1.扩容的参数不一样,HashMap要保证每次扩容后是2的次方倍,Hashtable是扩大一倍。 2.散列计算不同。HashMap因为容量是2的次方倍,所以使用减1与(具体百度,手机不好解释)的散列方式而非取余,优化了散列速度。Hashtable我记得是直接取余(没电脑在手,没法看源码)
发表于 2016-04-29 08:47:14 回复(0)
相同点:两者都实现了map接口 不同点:hashtable是同步的,不允许键和值为null,线程安全,适合于多线程环境,hashmap与之相反,适合于单线程环境。 一般情况下不推荐使用hashtable,因为内部实现没有优化和冗余,即使是同步也可以使用ConcurrentMap替代。 在ConcurrentMap中引入了一个分段锁的概念,具体可以理解为将一个map拆分成很多个hashtable,接着根据key.hashcode()把key放入到对应的hashtable中。
发表于 2021-10-15 09:02:01 回复(0)
<p>1.hashmap是允许键值是null,hashtable不允许</p><p>2.hashmap是非线程安全的,hashtable是线程安全的</p><p>3.hashmap效率高</p><p>4.hashtable是同步的,所以适合多线程,hashmap适合单线程</p>
发表于 2020-10-20 23:38:18 回复(0)
1.HashMap线程不安全,即效率高,HashTable线程安全,性能低。
2.HashMap只允许一个key为null,允许多个value为null,HashTable不允许键或者值为null
3.HashTable是同步的,即适合多线程环境,都是由于是遗留类,代码有很多没优化和冗余,故,hashtable基本不用,
  一般现在不建议用HashTable, ①是HashTable是遗留类,内部实现很多没优化和冗余。②即使在多线程环境下,现在也有同步的ConcurrentHashMap替代,没有必要因为是多线程而用HashTable。
而且hashmap是单线程
发表于 2020-08-31 16:04:50 回复(0)
HashMap不是线程安全的。 HashTable是线程安全的。 HashMap允许键和值是null,而HashTable不允许。因为线程安全原因,HashMap比HashTable要快。   一般现在不建议用HashTable, ①是HashTable是遗留类,内部实现很多没优化和冗余。②即使在多线程环境下,现在也有同步的ConcurrentHashMap替代,没有必要因为是多线程而用HashTable。
编辑于 2020-08-31 15:27:14 回复(0)
HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点: HashMap允许键和值是null,而Hashtable不允许键或者值是null。 Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。 HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。 一般认为Hashtable是一个遗留的类。
编辑于 2020-07-11 16:06:23 回复(0)
<p>1.线程安全</p><p>2.底层数据结构</p><p>3.key-value是否可以为null</p><p>4.初始大小和每次扩容大小</p><p>5.执行效率</p>
发表于 2020-05-31 20:54:22 回复(0)

hashmap 线程不安全,允许键值对可以为null,适合单线程,

hashtable线程安全,键值对不可以有null,适合多线程

编辑于 2020-03-04 11:11:15 回复(0)

hashmap是非线性安全的,而hashtable不是。hashmap执行效率更高,而hashtable较低。

hashmap允许有null作为键值对,而hashtable不行。

hashmap更适合单线程环境下,而hashtable不适合。

发表于 2020-02-27 21:45:54 回复(0)

hashtable 是线程安全的

编辑于 2019-10-28 18:42:01 回复(1)

hash map适合单线程,hashtable适合多线程

hash map允许键值为null 而hashtable不允许

hashtable是遗留的类,内部有很多问题没有解决所以不推荐使用

发表于 2019-09-23 15:00:20 回复(0)