13

【java】hashmap 和 hashtable 的区别到底是什么? | iTimeTraveler

 4 years ago
source link: https://itimetraveler.github.io/2015/11/10/%E3%80%90Java%E3%80%91HashMap%20%E5%92%8C%20HashTable%20%E7%9A%84%E5%8C%BA%E5%88%AB%E5%88%B0%E5%BA%95%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【Java】HashMap 和 HashTable 的区别到底是什么?

  • 第一、继承不同

    第一个不同主要是历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。

public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Serializable {...}
public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V>, Cloneable, Serializable {...}

而HashMap继承的抽象类AbstractMap实现了Map接口:

public abstract class AbstractMap<K, V> implements Map<K, V> {...}
  • 第二、线程安全不一样

    Hashtable 中的方法是同步的,而HashMap中的方法在默认情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

//这是Hashtable的put()方法:
/**
* Associate the specified value with the specified key in this
* {@code Hashtable}. If the key already exists, the old value is replaced.
* The key and value cannot be null.
*
* @param key
* the key to add.
* @param value
* the value to add.
* @return the old value associated with the specified key, or {@code null}
* if the key did not exist.
* @see #elements
* @see #get
* @see #keys
* @see java.lang.Object#equals
*/
public synchronized V put(K key, V value) {
if (key == null) {
throw new NullPointerException("key == null");
} else if (value == null) {
throw new NullPointerException("value == null");
}
int hash = Collections.secondaryHash(key);
HashtableEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
HashtableEntry<K, V> first = tab[index];
for (HashtableEntry<K, V> e = first; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
//这是HashMap的put()方法:
/**
* Maps the specified key to the specified value.
*
* @param key
* the key.
* @param value
* the value.
* @return the value of any previous mapping with the specified key or
* {@code null} if there was no such mapping.
*/
@Override public V put(K key, V value) {
if (key == null) {
return putValueForNullKey(value);
}

int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
preModify(e);
V oldValue = e.value;
e.value = value;
return oldValue;
}
}

从上面的源代码可以看到Hashtable的put()方法是synchronized的,而HashMap的put()方法却不是。

  • 第三、允不允许null值

    从上面的put()方法源码可以看到,Hashtable中,key和value都不允许出现null值,否则会抛出NullPointerException异常。
    而在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

  • 第四、遍历方式的内部实现上不同

    Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

  • 第五、哈希值的使用不同

    HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

  • 第六、内部实现方式的数组的初始大小和扩容的方式不一样

    HashTable中的hash数组初始大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

【总结】:

HashMap 线程不安全 允许有null的键和值 效率高一点、 方法不是Synchronize的要提供外同步 有containsvalue和containsKey方法 HashMap 是Java1.2 引进的Map interface 的一个实现 HashMap是Hashtable的轻量级实现 Hashtable 线程安全 不允许有null的键和值 效率稍低、 方法是是Synchronize的 有contains方法方法 Hashtable 继承于Dictionary 类 Hashtable 比HashMap 要旧

【建议】:

一些资料建议,当需要同步时,用Hashtable,反之用HashMap。但是,因为在需要时,HashMap可以被同步,HashMap的功能比Hashtable的功能更多,而且它不是基于一个陈旧的类的,所以有人认为,在各种情况下,HashMap都优先于Hashtable。

【参考资料】:

1、Hashtable、HashMap源代码
2、Java的HashMap和HashTable
3、HashMap与HashTable的区别


Recommend

  • 64

    &nbsp;&nbsp;&nbsp;&nbsp;首先请先阅读这两个的源码。一、hashMap、hashTable都是Map接口的实现类,但是hashMap类继承自抽象类abstractMap类,hashTable继承自Dictionary类,该类在jdk中这样描述:可见该类已经过时。二、hashTable里面的方法都是...

  • 44
    • ittiger.cn 5 years ago
    • Cache

    Hashtable、HashMap、TreeMap

    Hashtable、HashMap、TreeMap都是比较常见的一些Map实现,它们都是 key-value 键值对的形式存储和操作数据的容器类,同时他们的元素中不能有重复的key,一个key也只能映射一个value值。 下面我从不同的维度来分别...

  • 11

    <? extends T>和<? super T>是Java泛型中的“通配符(Wildcards)”和“边界(Bounds)”的概念。 <? extends T>:是指 “上界通配符(Upper Boun...

  • 8
    • itimetraveler.github.io 4 years ago
    • Cache

    java 8系列之重新认识hashmap | iTimeTraveler

    本文来自美团点评技术团队: Java 8系列之重新认识HashMap 摘要HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随...

  • 11
    • itimetraveler.github.io 4 years ago
    • Cache

    java访问权限修饰符的区别 | iTimeTraveler

    Java访问权限修饰符的区别   Java有四种访问权限,其中三种有访问权限修饰符,分别为private,public和protected,还有一种不带任何修饰符: private: Java语言中对访问权限限制的最窄的修饰符...

  • 8

    【Android】dip和px之间到底如何转换 在Android xml布局文件中,我们既可以设置px,也可以设置dp(或者dip)。一般情况下,我们都会选择使用dp,这样可以保证不同屏幕分辨率的机器上布局一致...

  • 8
    • wangzhiyao.github.io 2 years ago
    • Cache

    Java HashMap 与 Hashtable 的区别

    2 年前发表9 个月前更新Code2 分钟读完 (大约351个字)Java HashMap 与 Hashtable 的区别1.HashMap

  • 6

    基于J11,该类已经淘汰,如果使用线程安全的则用 ConcurrentHashMap ,用线程不安全的则使用 HashMap 。仅与HashMap进行比较 结构以及依赖关系 HashTable 的结构如下图

  • 3

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 大家好,我是小彭。

  • 8

    Social Follow us on social media for more news, content and background stories from our authors, editors and events. Share your personal experience with us.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK