您的位置:首页 > 其它

Hashtable 与HashMap的区别

2015-10-09 15:18 302 查看
哈希表的数据结构 

     哈希表是一个数组和链表的结合体(在数据结构称“链表散列“),如下图示:



当我们往哈希表中插入元素的时候,先根据key的hash值得到这个元素在数组中的位置(即下标),然后就可以把这个元素放到对应的位置中 了。如果这个元素所在的位子上已经存放其他元素了,那么在同一个位子上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。

HashMap 和Hashtable是哈希表的具体实现。

HashMap中put方法的实现:

<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;">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;			//把哈希表中数组地址赋值给tab
int hash = key.hashCode();		//获得哈希码
int index = (hash & 0x7FFFFFFF) % tab.length; 	//通过哈希码对数组长
//度取余的方法获得数组中的下标
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {	//元素变量指向数组中第index个变量
//如果不空,说明已经有元素存在,判断是否要找的元素,直到最后。
if ((e.hash == hash) && e.key.equals(key)) {//如果该元素已经存在, 则修改成新值,并返回旧值
V old = e.value;
e.value = value;
return old;
}
}

modCount++;			//改良次数加一
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();

tab = table;
index = (hash & 0x7FFFFFFF) % tab.length;
}

// Creates the new entry.如果元素不存在则添加新元素
Entry<K,V> e = tab[index];
tab[index] = new Entry<K,V>(hash, key, value, e);
count++;
return null;
}</span></span>


hashMap中put方法的实现:

<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;"><pre name="code" class="java">public V put(K key, V value) {
if (key == null)            //如果是空key则不允许插入
return putForNullKey(value);
int hash = hash(key.hashCode());    //获得哈希码
int i = indexFor(hash, table.length);    //获得数组下标
for (Entry<K,V> e = table[i]; e != null; e = e.next) {        //通过hash和key判断此元素是否在hashMap中存在,
//存在修改新值返回旧值
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}

modCount++;
//如果hashMap中不存在此元素,则添加
addEntry(hash, key, value, i);
return null;
}</span></span>


HashTable和HashMap区别

    第一,继承不同。

    public class Hashtable extends Dictionary implements Map
    public class HashMap  extends AbstractMap implements Map

    第二

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

    第三

    Hashtable中,key和value都不允许出现null值。

    在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

    第四,两个遍历方式的内部实现上不同。

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

    第五

    哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

    第六

    Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。 

 

HashMap的使用:
<span style="font-family:FangSong_GB2312;font-size:18px;">import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.junit.Test;

public class Test3 {
@Test
public void test3() {
Map map = new HashMap();
map.put("语文", "90");
map.put("语文", "80");//value 80 将替代 90
map.put("数学", "85");
map.put("英语", "90");

Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
System.out.println(entry);
}
}

}</span>


输出结果:

       语文=80

       英语=90

       数学=85
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hashtable hashmap 区别