欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

源码见这里 1. 时间 劳务派遣管理系统 HashTable产生于JDK 1.1

点击: 次  来源:宝鼎软件 时间:2017-05-31

原文出处: 措施员赵鑫

HashMap和HashTable有什么差异?在口试和被口试的进程中,我问过也被问过这个问题,也见过了不少答复,本日抉择写一写本身心目中的抱负谜底。

代码版本

JDK每一版本都在改造。本文接头的HashMap和HashTable基于JDK 1.7.0_67。源码见这里

1. 时间

HashTable发生于JDK 1.1,而HashMap发生于JDK 1.2。从时间的维度上来看,HashMap要比HashTable呈现得晚一些。

2. 作者

以下是HashTable的作者:

以下代码及注释来自java.util.HashTable

* @author Arthur van Hoff
* @author Josh Bloch
* @author Neal Gafter

以下是HashMap的作者:

以下代码及注释来自java.util.HashMap

* @author Doug Lea
* @author Josh Bloch
* @author Arthur van Hoff
* @author Neal Gafter

可以看到HashMap的作者多了大神Doug Lea。不相识Doug Lea的,可以看这里。

3. 对外的接口(API)

HashMap和HashTable都是基于哈希表来实现键值映射的东西类。接头他们的差异,我们首先来看一下他们袒露在外的API有什么差异。

3.1 Public Method

下面两张图,我画出了HashMap和HashTable的类担任体系,并列出了这两个类的可供外部挪用的果真要领。

源码见这里 1. 时间 劳务调派打点系统  HashTable发生于JDK 1.1

源码见这里 1. 时间 劳务调派打点系统  HashTable发生于JDK 1.1

从图中可以看出,两个类的担任体系有些差异。固然都实现了Map、Cloneable、Serializable三个接口。可是HashMap担任自抽象类AbstractMap,而HashTable担任自抽象类Dictionary。个中Dictionary类是一个已经被废弃的类,这一点我们可以从它代码的注释中看到:

以下代码及注释来自java.util.Dictionary

* <strong>NOTE: This class is obsolete. New implementations should
* implement the Map interface, rather than extending this class.</strong>

同时我们看到HashTable比HashMap多了两个果真要领。一个是elements,这来自于抽象类Dictionary,鉴于该类已经废弃,所以这个要领也就没什么用处了。另一个多出来的要领是contains,这个多出来的要领也没什么用,因为它跟containsValue要领成果是一样的。代码为证:

以下代码及注释来自java.util.HashTable

 public synchronized boolean contains(Object value) {
     if (value == null) {
         throw new NullPointerException();
     }

     Entry tab[] = table;
     for (int i = tab.length ; i-- > 0 ;) {
         for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {
             if (e.value.equals(value)) {
                 return true;
             }
         }
     }
     return false;
 }

 public boolean containsValue(Object value) {
     return contains(value);
 }

所以从果真的要领上来看,这两个类提供的,是一样的成果。都提供键值映射的处事,可以增、删、查、改键值对,可以对建、值、键值对提供遍历视图。支持浅拷贝,支持序列化。

3.2 Null Key & Null Value

HashMap是支持null键和null值的,而HashTable在碰着null时,会抛出NullPointerException异常。这并不是因为HashTable有什么非凡的实现层面的原因导致不能支持null键和null值,这仅仅是因为HashMap在实现时对null做了非凡处理惩罚,将null的hashCode值定为了0,从而将其存放在哈希表的第0个bucket中。我们一put要领为例,看一看代码的细节:

以下代码及注释来自java.util.HashTable

public synchronized V put(K key, V value) {

    // 假如value为null,抛出NullPointerException
    if (value == null) {
        throw new NullPointerException();
    }

    // 假如key为null,在挪用key.hashCode()时抛出NullPointerException

    // ...
}


以下代码及注释来自java.util.HasMap

public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    // 当key为null时,挪用putForNullKey非凡处理惩罚
    if (key == null)
        return putForNullKey(value);
    // ...
}

private V putForNullKey(V value) {
    // key为null时,放到table[0]也就是第0个bucket中
    for (Entry<K,V> e = table[0]; e != null; e = e.next) {
        if (e.key == null) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    modCount++;
    addEntry(0, null, value, 0);
    return null;
}

4. 实现道理

本节接头HashMap和HashTable在数据布局和算法层面,有什么差异。

4.1 数据布局

HashMap和HashTable都利用哈希表来存储键值对。在数据布局上是基内情同的,都建设了一个担任自Map.Entry的私有的内部类Entry,每一个Entry工具暗示存储在哈希表中的一个键值对。

Entry工具独一暗示一个键值对,有四个属性:

-K key 键工具
-V value 值工具
-int hash 键工具的hash值
-Entry entry 指向链表中下一个Entry工具,可为null,暗示当前Entry工具在链表尾部