摘要:線程安全是線程安全的,不是線程安全的。是添加的,貌似沒人用過這個(gè),棧長(zhǎng)我也沒用過。。最后一點(diǎn)有幾個(gè)人知道知道的給棧長(zhǎng)點(diǎn)個(gè)贊回應(yīng)一下,不知道的有收獲的也點(diǎn)一個(gè)贊支持一下吧。
HashMap 和 Hashtable 是 Java 開發(fā)程序員必須要掌握的,也是在各種 Java 面試場(chǎng)合中必須會(huì)問到的。
但你對(duì)這兩者的區(qū)別了解有多少呢?
現(xiàn)在,棧長(zhǎng)我給大家總結(jié)一下,或許有你不明朗的地方,在棧長(zhǎng)的指點(diǎn)下都會(huì)撥開迷霧見晴天。
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 是線程安全的,每個(gè)方法都要阻塞其他線程,所以 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 會(huì)直接拋出空指針異常,value 為 null 手動(dòng)拋出空指針異常,而 HashMap 的邏輯對(duì) null 作了特殊處理。
4、實(shí)現(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 添加的,貌似沒人用過這個(gè),棧長(zhǎng)我也沒用過。。
5、容量擴(kuò)容HashMap 的初始容量為:16,Hashtable 初始容量為:11,兩者的負(fù)載因子默認(rèn)都是: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 }
當(dāng)現(xiàn)有容量大于總?cè)萘?* 負(fù)載因子時(shí),HashMap 擴(kuò)容規(guī)則為當(dāng)前容量翻倍,Hashtable 擴(kuò)容規(guī)則為當(dāng)前容量翻倍 + 1。
6、迭代器HashMap 中的 Iterator 迭代器是 fail-fast 的,而 Hashtable 的 Enumerator 不是 fail-fast 的。
所以,當(dāng)其他線程改變了HashMap 的結(jié)構(gòu),如:增加、刪除元素,將會(huì)拋出 ConcurrentModificationException 異常,而 Hashtable 則不會(huì)。
可以來看下這個(gè)區(qū)別的演示:
/** * 微信公眾號(hào):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ū)別。
最后一點(diǎn)有幾個(gè)人知道?知道的給棧長(zhǎng)點(diǎn)個(gè)贊回應(yīng)一下,不知道的有收獲的也點(diǎn)一個(gè)贊支持一下吧。
有收獲?轉(zhuǎn)發(fā)給更多的人吧!
本文原創(chuàng)首發(fā)于微信公眾號(hào):Java技術(shù)棧(id:javastack),關(guān)注公眾號(hào)在后臺(tái)回復(fù) "java" 可獲取更多,轉(zhuǎn)載請(qǐng)?jiān)瓨颖A舯拘畔ⅰ?/pre>
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72568.html
摘要:記得,那是一個(gè)周末,棧長(zhǎng)去某知名互聯(lián)網(wǎng)公司面試,好像不到五分鐘,我就被面試官親切地趕出來了,當(dāng)時(shí)我那個(gè)尷尬,內(nèi)心深受打擊。。。 你們可能會(huì)想,棧長(zhǎng)這么菜的嗎?5分鐘都堅(jiān)持不了? 本文說起來會(huì)有點(diǎn)尷尬,畢竟這是棧長(zhǎng)我曾經(jīng)經(jīng)歷過的故事。。。 那時(shí)候的棧長(zhǎng)還真菜,每天寫著 if/ for 及一些簡(jiǎn)單的業(yè)務(wù)邏輯代碼,雖工作有些日子了,但技術(shù)水平還停留在剛畢業(yè)的起步階段。。。 記得,那是一個(gè)周末...
摘要:的工作原理是近年來常見的面試題。讓我們?cè)賮砜纯催@些問題設(shè)計(jì)哪些知識(shí)點(diǎn)的概念中解決碰撞的方法和的應(yīng)用,以及它們?cè)谥械闹匾圆豢勺儗?duì)象的好處多線程的條件競(jìng)爭(zhēng)重新調(diào)整的大小總結(jié)的工作原理基于原理,我們通過和方法儲(chǔ)存和獲取對(duì)象。 HashMap 的工作原理是近年來常見的 Java 面試題。幾乎每個(gè) Java 程序員都知道 HashMap,都知道哪里要用 HashMap,知道Hashtable和...
摘要:的函數(shù)都是同步的,這意味著它是線程安全的。直接使用對(duì)象的。是的輕量級(jí)實(shí)現(xiàn)非線程安全的實(shí)現(xiàn)都完成了接口,主要區(qū)別在于能否鍵對(duì)值能為。同時(shí)其內(nèi)部方法有區(qū)別中將的方法去掉了,改為和避免混淆。支持的遍歷種類不同只支持迭代器遍歷。 java在數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個(gè)接口java.util.Map。 Map包含三個(gè)實(shí)現(xiàn)類HashMap、Hashtable、TreeMap。Map是用來存儲(chǔ)鍵對(duì)值 ...
摘要:面向切面編程的目標(biāo)就是分離關(guān)注點(diǎn)。不會(huì)出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染。線程不安全就是不提供數(shù)據(jù)訪問保護(hù),有可能出現(xiàn)多個(gè)線程先后更改數(shù)據(jù)造成所得到的數(shù)據(jù)是臟數(shù)據(jù)和區(qū)別是的輕量級(jí)實(shí)現(xiàn)非線程安全的實(shí)現(xiàn) spingmvc 和 structs的區(qū)別 我們用struts2時(shí)采用的傳統(tǒng)的配置文件的方式,并沒有使用傳說中的0配置。 spring3 mvc可以認(rèn)為已經(jīng)100%零配置了(除了配置spring ...
摘要:棧長(zhǎng)看了下,確實(shí)是添加的,最早的一個(gè)集合類,這樣也說得過去。那為什么不在后面的版本中修復(fù)它呢可能是為了考慮兼容使用老版本的系統(tǒng)吧。棧長(zhǎng)又去證實(shí)了下,沒有和這個(gè)類,所有開頭的并發(fā)類和接口都在這里了。 前幾天在寫《HashMap 和 Hashtable 的 6 個(gè)區(qū)別》這篇文章的時(shí)候,差點(diǎn)把 Hashtable 寫成了 HashTable,后來看源碼證實(shí)了是:Hashtable,小寫的 t...
閱讀 2670·2021-10-14 09:47
閱讀 4974·2021-09-22 15:52
閱讀 3380·2019-08-30 15:53
閱讀 1477·2019-08-30 15:44
閱讀 711·2019-08-29 16:41
閱讀 1683·2019-08-29 16:28
閱讀 467·2019-08-29 15:23
閱讀 1649·2019-08-26 12:20