HashMap和Hashtable分析
程序员文章站
2022-06-04 19:26:12
...
1.先说继承关系吧
Java代码
public class Hashtable< k,v> extends Dictionary< k,v> implements Map< k,v>, Cloneable, java.io.Serializable {…} public class HashMap< k,v> extends AbstractMap< k,v> implements Map< k,v>, Cloneable, Serializable {…}
可以看到hashtable也是继承了Map接口。它们的不同是Hashtable(since JDK1.0)就继承了Dictionary这个抽象类,而HashMap(since JDK1.2)继承的则是AbstractMap这个抽象类。因为在Hashtable中看到继承Map后所实现的方法是JDK1.2版本时加上去的,所以可能是在JDK 1.2开发时Sun工程师出于统一的考虑使得Hashtable也继承了Map接口。
2.我们从同步和并发性上来说说它们两个的不同。
可以通过这两个类得源码来分析,Hashtable中的主要方法都做了同步处理,而HashMap则没有。可以说Hashtable在默认情况支持 同步,而HashMap在默认情况下是不支持的。我们在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加 同步处理了。对HashMap的同步处理可以使用Collections类提供的synchronizedMap静态方法;或者直接使用JDK5.0之后 提供的java.util.concurrent包里的ConcurrentHashMap类。
3.它们对于null值的处理方式了
我们依然能够从源代码中得知,Hashtable中,key和value都不允许出现null值。
在我们使用上面的方法时,如参数value为null,可以从代码中直接看出程序会抛出NullPointerException;而在key为 null时,则会在“int hash = key.hashCode();“这段计算Hash值的过程中抛出NullPointerException。而在在HashMap中,允许null作为 key存在,并且和其他key的特性一样,这样的null值key只能有一个;另外HashMap允许多个value为null。这样大家就要注意了, HashMap中就不能用get(key)方法来判断HashMap中是否存在某个key,因为value为null和不存在该key的Entry都会返 回null值,而应该用containsKey()方法来判断了。
结果
4.hash值的获取方式
还是通过源代码源代码,Hashtable是直接使用key对象的hash值。
而HashMap则是利用key对象的hash值重新计算一个新的hash值。
本文是从网上一篇比较有趣的帖子上转载而来,原文链接
[url]http://www.java3z.com/cwbwebhome/article/article8/81437.html?id=4314[/url]
Java代码
public class Hashtable< k,v> extends Dictionary< k,v> implements Map< k,v>, Cloneable, java.io.Serializable {…} public class HashMap< k,v> extends AbstractMap< k,v> implements Map< k,v>, Cloneable, Serializable {…}
可以看到hashtable也是继承了Map接口。它们的不同是Hashtable(since JDK1.0)就继承了Dictionary这个抽象类,而HashMap(since JDK1.2)继承的则是AbstractMap这个抽象类。因为在Hashtable中看到继承Map后所实现的方法是JDK1.2版本时加上去的,所以可能是在JDK 1.2开发时Sun工程师出于统一的考虑使得Hashtable也继承了Map接口。
2.我们从同步和并发性上来说说它们两个的不同。
可以通过这两个类得源码来分析,Hashtable中的主要方法都做了同步处理,而HashMap则没有。可以说Hashtable在默认情况支持 同步,而HashMap在默认情况下是不支持的。我们在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加 同步处理了。对HashMap的同步处理可以使用Collections类提供的synchronizedMap静态方法;或者直接使用JDK5.0之后 提供的java.util.concurrent包里的ConcurrentHashMap类。
3.它们对于null值的处理方式了
我们依然能够从源代码中得知,Hashtable中,key和value都不允许出现null值。
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();
int index = (hash & 0x7FFFFFFF) % tab.length;
//… }
在我们使用上面的方法时,如参数value为null,可以从代码中直接看出程序会抛出NullPointerException;而在key为 null时,则会在“int hash = key.hashCode();“这段计算Hash值的过程中抛出NullPointerException。而在在HashMap中,允许null作为 key存在,并且和其他key的特性一样,这样的null值key只能有一个;另外HashMap允许多个value为null。这样大家就要注意了, HashMap中就不能用get(key)方法来判断HashMap中是否存在某个key,因为value为null和不存在该key的Entry都会返 回null值,而应该用containsKey()方法来判断了。
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class TestCase {
public static void main(String[] args) {
Map< integer,string> hashMap = new HashMap< integer,string>();
hashMap.put(0, null);
hashMap.put(1, "one");
hashMap.put(2, "two");
hashMap.put(null, "null");
for(Entry< integer, string> e : hashMap.entrySet()) {
System.out.println("Key: " + e.getKey() + " -- Value: " + e.getValue());
}
System.out.println(hashMap.get(0));
System.out.println(hashMap.get(4));
System.out.println("Contains key 0 ? :" + hashMap.containsKey(0));
System.out.println("Contains key 4 ? :" + hashMap.containsKey(4));
System.out.println("Contains value null ? :" + hashMap.containsValue(null));
}
}
结果
Key: null -- Value: null
Key: 0 -- Value: null
Key: 1 -- Value: one
Key: 2 -- Value: two
null
null
Contains key 0 ? :true
Contains key 4 ? :false
Contains value null ? :true
4.hash值的获取方式
还是通过源代码源代码,Hashtable是直接使用key对象的hash值。
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();//hashcode
int index = (hash & 0x7FFFFFFF) % tab.length;
//… }
而HashMap则是利用key对象的hash值重新计算一个新的hash值。
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());//hashcode
int i = indexFor(hash, table.length);
//… }
static int hash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
本文是从网上一篇比较有趣的帖子上转载而来,原文链接
[url]http://www.java3z.com/cwbwebhome/article/article8/81437.html?id=4314[/url]