HashMap和HashTable的比较:
属性 | HashMap | HashTable |
线程安全 | 非线程安全(如果要保证线程安全用ConcurrentHashMap) | 线程安全(内部的方法基本都被sychronized修饰) |
效率 | 高于HashTable | 低(因为线程安全) |
对于Null Key 和Null Value的支持 | null可以作为键,但只能有一个null键,可有多个键所对应的值为null | 不允许为null,只有键值中有一个为nul,就抛出空指针异常 |
初始容量和每次扩充量 |
|
|
HashMap和HashSet的比较:
看HashSet源码可发现,HashSet底层是基于HashMap实现的,除去clone()方法、writeObject()方法、readObjcet()方法是自己实现之外,其余方法都是直接调用HashMap里的方法。
属性 | HashMap | HashTabe |
实现接口 | 实现了Map接口 | 实现了Set接口 |
存储内容 | 存储键值对,key不可重复,值可重复 | 仅存储对象,不允许有重复值 |
添加元素方法 | put(key,value) | add() |
相等性判断 | 使用键key计算Hashcode | 使用成员对象比较Hashcode,如果Hashcode的相同,调用equals()方法比较 |
效率 | 快,因为通过唯一key获取值 | 相对慢 |
测试代码:
public class TestHash {
public static void main(String[] args){
HashMap map = new HashMap();
Hashtable table = new Hashtable();
HashSet set = new HashSet();
map.put("1k","1");
map.put("2k","2");
map.put("3k","3");
map.put("1k","4");
map.put("4k",null);
table.put("1k","1");
table.put("2k","2");
table.put("3k","3");
table.put("1k","4");
set.add("1");
set.add("2");
set.add("3");
set.add("1");
System.out.println("key:8k"+" value:"+map.get("8"));//HashMap中允许一个键为空,即没有对应的key时,会返回null
System.out.println("key:4k"+" value:"+map.get("4k"));//有对应的key,但是值为空
//为区别以上两种情况,最好通过containsKey来判断
System.out.println("是否含有8k这个key:"+map.containsKey("8k"));
for(Object m:map.entrySet()){
System.out.println("HashMap:"+m);
}
for(Object t :table.keySet()){
System.out.println("HashTable:"+t);
}
for(Object s :set){
System.out.println("HashSet:"+s);
}
}
}
结果: