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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

浅谈关于Java中map这个类衍生的类

發布時間:2023/12/31 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈关于Java中map这个类衍生的类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近又研究了一下關于map衍生的類,hashMap LinkedHashMap?TreeMap?hashTable?ConcurrentHashMap,沒有對代碼的粘貼,純粹用文字根據自己的理解看了一遍,以此簡單的整理。

/**
*定義:Map java中的一種數據存儲結構,它的存儲類型是key,val形式的,key,val都可以為空,但只保存一份,key的存儲是基于鍵的hash
*值進行一些運算得到物理存儲的地址。
*對于Map的實現類,我們著重講一下HashMap Hashtable ConcurrentHashMap
*HashMap: 內部數據存儲的方式是基于數組和鏈表的形式進行存儲的。數組的下標就是根據key的hashCode值進行運算的出來的。下面我們看下
*它是如何計算的:(h = key.hashCode()) ^ (h >>> 16) 這個是計算hash的值防止hash的一個沖突(^相同為0,不同為1)
*計算下標:(n - 1) & hash ( &全1為1 其他為0 ) 計算下標值,其下標值不會超過map自定義的下標值
*計算完下標的值以后,接下來就是解決hash沖突,和值得替換。
*如果映射到的下標上面值為空,直接創建一個新的節點放到對應的
*下標下面就可以了。數組放的對象Node是實現Map內部的Entry接口,儲存的值有hash,鍵,值,鏈表的下一個元素。
*如果不為空,判斷hash值和值是否與此下標下的值相等,如果相等就覆蓋,不等遍歷鏈表上的值進行比較。
*首先:這里需要注意的是binCount 這個值是判斷在解決沖突的使用鏈表還是用紅黑樹
*第二:在遍歷的時候,其實很簡單的就是有一個無限的for循環,然后就是修改e的值,以及鏈表轉樹的過程。
*接下來你會發現兩個方法:afterNodeAccess? afterNodeInsertion,這兩個是用于排序的,但是hashmap并沒有實現,所以是無須的,
*而LinkedHashMap實現了這兩個方法,所以LinkedHashMap是有序的。
*最后最重要的就是一個擴容機制,注意兩點吧:
*第一:擴容后的大小為多少,一般是原來的2倍,其他情況下可能是是integer的最大值
*第二:在擴容的時候,(e.hash & oldCap) == 0 這個我也不明白
基本上插入就說完了。
下面是取數:
*取數據就很簡單了,首先根據hash找到對應數據的下標,再分三種情況去找到對應的數據。
其實在hashMap中有幾個關鍵值需要掌握以下:
*DEFAULT_INITIAL_CAPACITY 默認容量大小
*MAXIMUM_CAPACITY 最大的容量
*DEFAULT_LOAD_FACTOR 擴張因子,用于判斷當前的容量是否需要擴容的一個因子
*threshold 擴容標識帶下,大于就擴容
*TREEIFY_THRESHOLD 鏈表轉平衡二叉樹的標識

**/


/**
LinkedHashMap 是一個有順序的map,本身繼承與HashMap 只是他實現了afterNodeAccess? afterNodeInsertion 這個兩個方法
所以他是一個有順序的map,而且里面維護的是一個雙端鏈表
*LinkedHashMap 里面的Entry 繼承制hashmap里的node
*對于插入的操作,本身用到得是父類的方法,只是實現了其中的兩個方法。
*afterNodeAccess:move node to last 訪問過就排到最后
*
*afterNodeInsertion:possibly remove eldest
*
*對于上面的兩部分的理解,其實拿出5分鐘畫個簡單的草圖就理解了。
*
除了LRU ,其他的功能和hashmap差不多。
**/


/**
? *treemap 一種可以自定義排序map,內部引用Comparator實現排序。
? *默認是根據鍵的compareTo 進行排序的
? *可以在實例化treemap的時候 自己實現Comparator類,來實現自己定義的排序規則
? *?
?*/


/**
? *在研究hashMap的時候我們忘說了關于多線程的問題,其實? hashMap是線程不安全的,這樣我們來看下,為什么
? *Hashmap不是線程安全的。
? *首先線程的定義:當在多線程的情況下,我們的數據不會因為線程切換而導致數據異常就是線程安全的。
? *而對于hashmap來說,它在多線程的情況下,在添加,刪除,查詢的時候回出現異常。
? *
? *
**/
/**
? *基于hashmap是線程不安全的,而我們現在都是多線程的環境下,jdk也有線程線程安全的類,hashtable,ConcurrentHashMap ?
? *對于hashtable來說,它在實現線程安全的時候是在所有線程不安全的方法上面添加synchronized關鍵字,而ConcurrentHashMap 1.8之前是針對于Segment
? *的分段鎖外,1.8之后是基于樂觀鎖的思想進行的一個添加和獲取,是一個并發散列映射表的實現,它允許完全并發的讀取,并且支持給定數量的并發更新,
? *加volatile來做線程安全的。但是在一定的程度上,ConcurrentHashMap 不能完全代替hashtable,雖然分段鎖的鎖粒度小,運行的速度快,
? *但是它在極限的條件下會出現一個修改異常,但這個是很小概率發生的,所以我們在用的時候都不太會考慮這個問題。對于hashtable基本就是在
? *hashmap上面進行添加synchronized關鍵字,沒什么好講的,接下來我們重點分析一下ConcurrentHashMap
? *
? *ConcurrentHashMap,從初始化,插入數據,查詢數據,刪除數據四個層面說
? *
? *初始化:初始化和hashmap基本一樣的
? *
? *put:在添加數據的時候,hash的值的計算是一樣的,首先獲取一下添加數據計算出來的位置上面是否有數據,用到了,unsafe
? *安全類,在獲取到為空的情況下,會設置一個空值casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null)),底層
? *的實現是U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v)
? *如果當前的值得hash為-1就 如果調整了大小,可以幫助轉移。基本在添加的時候也是基平衡樹。
? *插入是并發式的,鎖是基于synchronized 的做線程安全,其中優化表大小,以及擴容機制
? *
? *get:也是可以并發的讀,內部的實現是通過unfade的getObjectVolatile根據內存地址進行獲取,保證了除table是Volatile
? *下而內部對象不是Volatile會出現數據異常的情況
? *
? *
?**/

總結

以上是生活随笔為你收集整理的浅谈关于Java中map这个类衍生的类的全部內容,希望文章能夠幫你解決所遇到的問題。

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