> 文章列表 > HashMap与Hashtable的这九个区别,你知道吗

HashMap与Hashtable的这九个区别,你知道吗

HashMap与Hashtable的这九个区别,你知道吗

Hashtable

Hashtable是原始的java.util的一部分,属于一代集合类,是一个Dictionary具体的实现 。Java1.2重构的Hashtable实现了Map接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似。

Hashtable与HashMap的区别

  • 1)Hashtable属于一代集合,继承了Dictionary类,也实现了Map接口,HashMap属于二代集合,实现与Map接口,没有与Dictionary类产生关系;

  • 2)Hashtable支持iterator遍历(Map接口中的),也支持Enumeration遍历(Dictionary),HahsMap只支持iterator遍历

  • 3)Hashtable与HashMap底层都是采用hash表这种数据结构,JDK8对HashMap进行了优化(引入红黑树),但并没有对Hashtable进行优化;

  • 4)HashMap默认的数组大小是16,Hashtable则是11,两者的负载因子都是0.75,并且都允许传递初始化的数组大小和负载因子

  • 5)HashMap对null key和null value进行了特殊处理,可以存储null key和null value,Hashtable则不能存储null key和null value;

  • 6)当HashMap存储的元素数量>数组容量*负载因子,数组扩容至原来的2倍,Hashtable则是2倍+1;

  • 7)HashMap在添加元素时使用的是:元素本身的hash算法 ^ (元素本身的hash算法 >>> 16),而Hashtable则是直接采用元素本身的hash算法;

    Tips:>>代表有符号位移,>>>代表无符号位移;

  • 8)HashMap在使用foreach迭代时不能对元素内容进行增删,否则触发并发修改异常。Hahstable中支持Enumeration迭代,使用Enumeration迭代元素时,可以对集合进行增删操作;

  • 9)Hashtable是线程安全的,效率低,安全性高;HashMap是线程不安全的,效率高,安全性低;


1)测试存储Null key和Null value:

package com.dfbz.hashtable;import java.util.HashMap;
import java.util.Hashtable;/* @author lscl* @version 1.0* @intro:*/
public class Demo02_HashMapHashtable的区别_null问题 {public static void main(String[] args) {HashMap<Integer, String> hashMap = new HashMap<>();/*HashMap对null key和null value并且,HashMap对null key做了特殊处理,HashMap永远将Null key存储在第0位数组上*/hashMap.put(1, null);hashMap.put(null, "大闸蟹");System.out.println(hashMap);            // {null=大闸蟹, 1=null}}public static void test1(){Hashtable<Integer, String> hashtable = new Hashtable<>();// Hashtable存储null key和null value的时候会出现空指针异常: Exception in thread "main" java.lang.NullPointerExceptionhashtable.put(1, null);hashtable.put(null, "大闸蟹");}
}

2)测试并发修改异常问题:

package com.dfbz.hashtable;import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Set;/* @author lscl* @version 1.0* @intro:*/
public class Demo03_HashMapHashtable的区别_并发修改问题 {public static void main(String[] args) {Hashtable<Integer, String> hashtable = new Hashtable<>();hashtable.put(1, "拌粉");hashtable.put(2, "汤粉");hashtable.put(3, "炒粉");hashtable.put(4, "泡粉");Enumeration<Integer> keys = hashtable.keys();while (keys.hasMoreElements()) {Integer key = keys.nextElement();if (key == 2) {/*Hashtable在使用Enumeration遍历时,允许对集合进行增删操作注意: Hashtable使用foreach迭代也不能对元素进行增删操作*/hashtable.put(5, "扎粉");
//                hashtable.remove(3);}}System.out.println(hashtable);}/* hashMap在使用foreach迭代时不允许对集合进行增删等操作*/public static void test1() {HashMap<Integer, String> hashMap = new HashMap<>();hashMap.put(1, "拌粉");hashMap.put(2, "汤粉");hashMap.put(3, "炒粉");hashMap.put(4, "泡粉");Set<Integer> keys = hashMap.keySet();for (Integer key : keys) {if (key == 2) {// hashMap在迭代时不允许对集合进行增删等操作hashMap.remove(3);
//                hashMap.put(5, "扎粉");}}}
}

Dictionary类

Dictionary类是一代集合中的双列集合顶层类,Dictionary类中的方法都是双列集合中最基本的方法;严格意义来说Java中所有的双列集合都应该继承与Dictionary类,但Java2推出了一系列二代集合,其中二代集合中的Map接口也已经替代了Dictionary接口,成为双列集合的顶层接口,因此Dictionary接口下面没有太多的实现类;

Tips:目前JDK已经不推荐使用Dictionary类了;

  • Dictionary接口方法如下:
方法 说明
Enumeration<V> elements() 返回此字典中值的枚举。
V get(Object key) 返回该字典中键映射到的值。
boolean isEmpty() 检测该字典是否为空。
Enumeration<K> keys() 返回此字典中键的枚举。
V put(K key, V value) 添加一对key,value到字典中
V remove(Object key) 根据对应的key从字典中删除value。
int size() 返回此字典中的条目数。
  • 方法测试:
package com.dfbz.hashtable;import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;/* @author lscl* @version 1.0* @intro:*/
public class Demo01_Hashtable基本使用 {public static void main(String[] args) {Dictionary<Integer, String> hashtable = new Hashtable<>();hashtable.put(1, "南昌拌粉");hashtable.put(2, "粉蒸肉");hashtable.put(3, "福羹");hashtable.put(4, "藜蒿炒腊肉");hashtable.put(5, "瓦罐汤");String s1 = hashtable.get(3);System.out.println(s1);                             // 福羹String s2 = hashtable.remove(2);System.out.println(s2);                             // 粉蒸肉System.out.println(hashtable);                      // {5=瓦罐汤, 4=藜蒿炒腊肉, 3=福羹, 1=南昌拌粉}System.out.println("-------------");// 获取到Hashtable的所有keyEnumeration<Integer> keys = hashtable.keys();while (keys.hasMoreElements()){Integer key = keys.nextElement();System.out.println(key);}System.out.println("-------------");// 获取到Hashtable的所有valueEnumeration<String> vals = hashtable.elements();while (vals.hasMoreElements()){String val = vals.nextElement();System.out.println(val);}System.out.println("-----------------");System.out.println(hashtable.size());                   // 4}
}