日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HashMap vs ConcurrentHashMap — 示例及Iterator探秘

發布時間:2023/12/19 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HashMap vs ConcurrentHashMap — 示例及Iterator探秘 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

如果你是一名Java開發人員,我能夠確定你肯定知道ConcurrentModificationException,它是在使用迭代器遍歷集合對象時修改集合對象造成的(并發修改)異常。實際上,Java的集合框架是迭代器設計模式的一個很好的實現。

Java 1.5引入了java.util.concurrent包,其中Collection類的實現允許在運行過程中修改集合對象。

ConcurrentHashMap是一個與HashMap很相似的類,但是它支持在運行時修改集合對象。

讓我們通過一個簡單的程序來幫助理解:

ConcurrentHashMapExample.java

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 packagecom.journaldev.util; importjava.util.HashMap; importjava.util.Iterator; importjava.util.Map; importjava.util.concurrent.ConcurrentHashMap; publicclassConcurrentHashMapExample { publicstaticvoidmain(String[] args) { //ConcurrentHashMap Map<String,String> myMap =newConcurrentHashMap<String,String>(); myMap.put("1","1"); myMap.put("2","1"); myMap.put("3","1"); myMap.put("4","1"); myMap.put("5","1"); myMap.put("6","1"); System.out.println("ConcurrentHashMap before iterator: "+myMap); Iterator<String> it = myMap.keySet().iterator(); while(it.hasNext()){ String key = it.next(); if(key.equals("3")) myMap.put(key+"new","new3"); } System.out.println("ConcurrentHashMap after iterator: "+myMap); //HashMap myMap =newHashMap<String,String>(); myMap.put("1","1"); myMap.put("2","1"); myMap.put("3","1"); myMap.put("4","1"); myMap.put("5","1"); myMap.put("6","1"); System.out.println("HashMap before iterator: "+myMap); Iterator<String> it1 = myMap.keySet().iterator(); while(it1.hasNext()){ String key = it1.next(); if(key.equals("3")) myMap.put(key+"new","new3"); } System.out.println("HashMap after iterator: "+myMap); } }

當我們試著運行上面的程序,輸出如下:

1 2 3 4 5 6 7 ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1} ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1} HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1} Exceptioninthread"main"java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793) at java.util.HashMap$KeyIterator.next(HashMap.java:828) at com.test.ConcurrentHashMapExample.main(ConcurrentHashMapExample.java:44)

查看輸出,很明顯ConcurrentHashMap可以支持向map中添加新元素,而HashMap則拋出了ConcurrentModificationException。

查看異常堆棧記錄,可以發現是下面這條語句拋出異常:

1 String key = it1.next();

這就意味著新的元素在HashMap中已經插入了,但是在迭代器執行時出現錯誤。事實上,集合對象的迭代器提供快速失敗(Fail-Fast)的機制,即修改集合對象結構或者元素數量都會使迭代器觸發這個異常。

但是迭代器是怎么知道HashMap被修改了呢,我們可以一次取出HashMap的所有Key然后進行遍歷。

HashMap包含一個修改計數器,當你調用它的next()方法來獲取下一個元素時,迭代器將會用到這個計數器。

HashMap.java

1 2 3 4 5 6 7 /** * HashMap結構的修改次數 * 結構修改是指:改變了HashMap中mapping的個數或者其中的內部結構(比如,重新計算hash值) * 這個字段在通過Collection操作Hashmap時提供快速失敗(Fail-fast)功能。 * (參見 ConcurrentModificationException)。 */ transientvolatileintmodCount;

現在為了證明上面的觀點,我們對原來的代碼做一點修改,使迭代器在插入新的元素后跳出循環。只要在調用put方法后增加一個break:

1 2 3 4 if(key.equals("3")){ myMap.put(key+"new","new3"); break; }

再執行修改后的代碼,會得到下面的輸出結果:

1 2 3 4 ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1} ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1} HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1} HashMap after iterator: {3=1, 2=1, 1=1, 3new=new3, 6=1, 5=1, 4=1}

最后,如果我們不添加新的元素而是修改已經存在的鍵值對會不會拋出異常呢?

修改原來的程序并且自己驗證一下:

1 2 //myMap.put(key+"new", "new3"); myMap.put(key,"new3");

如果你對于輸出結果感覺困惑或者震驚,在下面評論。我會很樂意給出進一步解釋。

你有沒有注意到那些我們在創建集合和迭代器時的尖括號,在Java中這叫做泛型,當涉及到編譯時的類型檢查和去除運行時的ClassCastException的時候會很有幫助。點擊這里可以了解更多泛型教程。

原文鏈接:? journaldev ?翻譯:? ImportNew.com? -? 風戀星
譯文鏈接:? http://www.importnew.com/8162.html
[? 轉載請保留原文出處、譯者和譯文鏈接。 ]

轉載于:https://my.oschina.net/u/165124/blog/373724

總結

以上是生活随笔為你收集整理的HashMap vs ConcurrentHashMap — 示例及Iterator探秘的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。