摘要:線程安全是線程安全的,不是線程安全的。是添加的,貌似沒人用過這個,棧長我也沒用過。。最后一點有幾個人知道知道的給棧長點個贊回應(yīng)一下,不知道的有收獲的也點一個贊支持一下吧。
HashMap 和 Hashtable 是 Java 開發(fā)程序員必須要掌握的,也是在各種 Java 面試場合中必須會問到的。
但你對這兩者的區(qū)別了解有多少呢?
現(xiàn)在,棧長我給大家總結(jié)一下,或許有你不明朗的地方,在棧長的指點下都會撥開迷霧見晴天。
1、線程安全Hashtable 是線程安全的,HashMap 不是線程安全的。
為什么說 HashTable 是線程安全的?
來看下 Hashtable 的源碼,Hashtable 所有的元素操作都是 synchronized 修飾的,而 HashMap 并沒有。
public synchronized V put(K key, V value); public synchronized V get(Object key); ...2、性能優(yōu)劣
既然 Hashtable 是線程安全的,每個方法都要阻塞其他線程,所以 Hashtable 性能較差,HashMap 性能較好,使用更廣。
如果要線程安全又要保證性能,建議使用 JUC 包下的 ConcurrentHashMap。
3、NULLHashtable 是不允許鍵或值為 null 的,HashMap 的鍵值則都可以為 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 = key.hashCode(); ... }
HashMap hash 方法邏輯:
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
可以看出 Hashtable key 為 null 會直接拋出空指針異常,value 為 null 手動拋出空指針異常,而 HashMap 的邏輯對 null 作了特殊處理。
4、實現(xiàn)方式Hashtable 的繼承源碼:
public class Hashtableextends Dictionary implements Map , Cloneable, java.io.Serializable
HashMap 的繼承源碼:
public class HashMapextends AbstractMap implements Map , Cloneable, Serializable
可以看出兩者繼承的類不一樣,Hashtable 繼承了 Dictionary類,而 HashMap 繼承的是 AbstractMap 類。
Dictionary 是 JDK 1.0 添加的,貌似沒人用過這個,棧長我也沒用過。。
5、容量擴容HashMap 的初始容量為:16,Hashtable 初始容量為:11,兩者的負載因子默認都是:0.75。
/** * Constructs a new, empty hashtable with a default initial capacity (11) * and load factor (0.75). */ public Hashtable() { this(11, 0.75f); } /** * Constructs an empty HashMap with the default initial capacity * (16) and the default load factor (0.75). */ public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted }
當現(xiàn)有容量大于總?cè)萘?* 負載因子時,HashMap 擴容規(guī)則為當前容量翻倍,Hashtable 擴容規(guī)則為當前容量翻倍 + 1。
6、迭代器HashMap 中的 Iterator 迭代器是 fail-fast 的,而 Hashtable 的 Enumerator 不是 fail-fast 的。
所以,當其他線程改變了HashMap 的結(jié)構(gòu),如:增加、刪除元素,將會拋出 ConcurrentModificationException 異常,而 Hashtable 則不會。
可以來看下這個區(qū)別的演示:
/** * 微信公眾號:Java技術(shù)棧 **/ public static void main(String[] args) { Maphashtable = new Hashtable<>(); hashtable.put("t1", "1"); hashtable.put("t2", "2"); hashtable.put("t3", "3"); Enumeration > iterator1 = (Enumeration >) hashtable.entrySet().iterator(); hashtable.remove(iterator1.nextElement().getKey()); while (iterator1.hasMoreElements()) { System.out.println(iterator1.nextElement()); } Map hashMap = new HashMap<>(); hashMap.put("h1", "1"); hashMap.put("h2", "2"); hashMap.put("h3", "3"); Iterator > iterator2 = hashMap.entrySet().iterator(); hashMap.remove(iterator2.next().getKey()); while (iterator2.hasNext()) { System.out.println(iterator2.next()); } }
輸出信息:
t2=2 t1=1 Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442) at java.util.HashMap$EntryIterator.next(HashMap.java:1476) at java.util.HashMap$EntryIterator.next(HashMap.java:1474) at cn.javastack.Test.main(Test.java:37)
看到了吧?
所以,這條同樣也是 Enumeration 和 Iterator 的區(qū)別。
最后一點有幾個人知道?知道的給棧長點個贊回應(yīng)一下,不知道的有收獲的也點一個贊支持一下吧。
有收獲?轉(zhuǎn)發(fā)給更多的人吧!
本文原創(chuàng)首發(fā)于微信公眾號:Java技術(shù)棧(id:javastack),關(guān)注公眾號在后臺回復 "java" 可獲取更多,轉(zhuǎn)載請原樣保留本信息。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/72568.html
摘要:記得,那是一個周末,棧長去某知名互聯(lián)網(wǎng)公司面試,好像不到五分鐘,我就被面試官親切地趕出來了,當時我那個尷尬,內(nèi)心深受打擊。。。 你們可能會想,棧長這么菜的嗎?5分鐘都堅持不了? 本文說起來會有點尷尬,畢竟這是棧長我曾經(jīng)經(jīng)歷過的故事。。。 那時候的棧長還真菜,每天寫著 if/ for 及一些簡單的業(yè)務(wù)邏輯代碼,雖工作有些日子了,但技術(shù)水平還停留在剛畢業(yè)的起步階段。。。 記得,那是一個周末...
摘要:的工作原理是近年來常見的面試題。讓我們再來看看這些問題設(shè)計哪些知識點的概念中解決碰撞的方法和的應(yīng)用,以及它們在中的重要性不可變對象的好處多線程的條件競爭重新調(diào)整的大小總結(jié)的工作原理基于原理,我們通過和方法儲存和獲取對象。 HashMap 的工作原理是近年來常見的 Java 面試題。幾乎每個 Java 程序員都知道 HashMap,都知道哪里要用 HashMap,知道Hashtable和...
摘要:的函數(shù)都是同步的,這意味著它是線程安全的。直接使用對象的。是的輕量級實現(xiàn)非線程安全的實現(xiàn)都完成了接口,主要區(qū)別在于能否鍵對值能為。同時其內(nèi)部方法有區(qū)別中將的方法去掉了,改為和避免混淆。支持的遍歷種類不同只支持迭代器遍歷。 java在數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個接口java.util.Map。 Map包含三個實現(xiàn)類HashMap、Hashtable、TreeMap。Map是用來存儲鍵對值 ...
摘要:面向切面編程的目標就是分離關(guān)注點。不會出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染。線程不安全就是不提供數(shù)據(jù)訪問保護,有可能出現(xiàn)多個線程先后更改數(shù)據(jù)造成所得到的數(shù)據(jù)是臟數(shù)據(jù)和區(qū)別是的輕量級實現(xiàn)非線程安全的實現(xiàn) spingmvc 和 structs的區(qū)別 我們用struts2時采用的傳統(tǒng)的配置文件的方式,并沒有使用傳說中的0配置。 spring3 mvc可以認為已經(jīng)100%零配置了(除了配置spring ...
摘要:棧長看了下,確實是添加的,最早的一個集合類,這樣也說得過去。那為什么不在后面的版本中修復它呢可能是為了考慮兼容使用老版本的系統(tǒng)吧。棧長又去證實了下,沒有和這個類,所有開頭的并發(fā)類和接口都在這里了。 前幾天在寫《HashMap 和 Hashtable 的 6 個區(qū)別》這篇文章的時候,差點把 Hashtable 寫成了 HashTable,后來看源碼證實了是:Hashtable,小寫的 t...
閱讀 2715·2021-10-14 09:47
閱讀 5013·2021-09-22 15:52
閱讀 3403·2019-08-30 15:53
閱讀 1496·2019-08-30 15:44
閱讀 737·2019-08-29 16:41
閱讀 1723·2019-08-29 16:28
閱讀 492·2019-08-29 15:23
閱讀 1687·2019-08-26 12:20