HashMap和HashTable的6个区别,你未必知道!

首先这个问题是面试中很常见的问题,但一般的面试者只能回答出两三点,而且这两个在平时开发中也很常用。

1.线程安全

HashTable 是线程安全的,HashMap不是。观察一下HashTable的put的方法的源码和HashMap的put的方法的源码就知道了:

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

HashTable的所有元素的操作都是有synchronized修饰的

2.性能优劣

既然HashTable是线程安全的,每个方法都要阻塞其他线程,所以性能方面肯定是比较差了,HashMap性能更好,所以使用更广,如果既要保证线程安全又要保证性能,最好使用JUC包下的ConcurrenceHashMap

3.NULL 值

HashTable是不允许key或者value为NULL的,而HashMap则可以。看源码:

分析一下HashTable的put的方法:

 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 = hash(key);
        int index = (hash & 0x7FFFFFFF) % tab.length;
        ...

如果key为null的话直接抛出空指针,HashMap的put的方法:

 public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        ...

对null值做了处理。

扫描二维码关注公众号,回复: 4992305 查看本文章

4.实现方式

HashTable的实现方式:

HashMap的实现方式:

 

两者继承的父类不同。

5.容量扩充

HashTable的无参构造:

HashMap的无参构造:

 当现有容量大于总容量*负载因子时,HashTable的扩容规则是当前容量翻倍+1;HashMap的扩容规则是当前容量翻倍;

6.迭代器

//csdn博客---HopeLee
Hashtable<String,String> ht = new Hashtable();
        ht.put("t1","2");
        ht.put("t2","3");
        ht.put("t3","4");

        Enumeration<Map.Entry<String, String>> iterator =(Enumeration<Map.Entry<String, String>>) ht.entrySet().iterator();
        ht.remove(iterator.nextElement().getKey());
        while(iterator.hasMoreElements())
        {
            System.out.println(iterator.nextElement());
        }
        System.out.println("====================");

        HashMap<String,String> hm =new HashMap<>();
        hm.put("h1","2");
        hm.put("h2","3");
        hm.put("h3","4");

        Iterator<Map.Entry<String, String>> iterator2 = hm.entrySet().iterator();
        hm.remove(iterator2.next().getKey());
        while(iterator2.hasNext())
        {
            System.out.println(iterator2.next());
        }

输出的结果是:

t2=3
t1=2
====================
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:922)
	at java.util.HashMap$EntryIterator.next(HashMap.java:962)
	at java.util.HashMap$EntryIterator.next(HashMap.java:960)
	at com.lff.nov.DatabaseTest.main(DatabaseTest.java:64)

 HashMap的迭代器Iterator是fail-fast的,而HashTable的迭代器Enumeration不是,所以当其他线程有改变HashMap的结构时,如删除、增加元素,就会抛出java.util.ConcurrentModificationException。

猜你喜欢

转载自blog.csdn.net/Hope_lee/article/details/84845134