Java 數(shù)據(jù)結(jié)構(gòu)之 Map 學習總結(jié)

Java 數(shù)據(jù)結(jié)構(gòu)之 Map 學習總結(jié)

今天總結(jié)學習一下鍵值映射關(guān)系Map。

先了解下Map

Map 是一種把鍵對象和值對象映射的集合,它的每一個元素都包含一對鍵對象和值對象。 Map沒有繼承于Collection接口 從Map集合中檢索元素時,只要給出鍵對象,就會返回對應(yīng)的值對象。

Map是一個接口,實例化Map可以采用下面的方式:

HashMap//Map基于散列表的實現(xiàn)。插入和查詢“鍵值對”的開銷是固定的??梢酝ㄟ^構(gòu)造器設(shè)置容量capacity和負載因子load factor,以調(diào)整容器的性能。

LinkedHashMap//類似于HashMap,但是迭代遍歷它時,取得“鍵值對”的順序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一點。而在迭代訪問時發(fā)而更快,因為它使用鏈表維護內(nèi)部次序。

TreeMap//底層是二叉樹數(shù)據(jù)結(jié)構(gòu),線程不同步,可用于給Map集合中的鍵進行排序。

HashTable//HashMap是Hashtable的輕量級實現(xiàn),非線程安全的實現(xiàn)他們都實現(xiàn)了map接口,主要區(qū)別是HashMap鍵值可以為空null,效率可以高于Hashtable。

ConcurrentHashMap//ConcurrentHashMap通常只被看做并發(fā)效率更高的Map,用來替換其他線程安全的Map容器,比如Hashtable和Collections.synchronizedMap。

WeakHashMap//弱鍵(weak key)Map,Map中使用的對象也被允許釋放: 這是為解決特殊問題設(shè)計的。如果沒有map之外的引用指向某個“鍵”,則此“鍵”可以被垃圾收集器回收。

IdentifyHashMap//使用==代替equals()對“鍵”作比較的hash map

ArrayMap//ArrayMap是一個映射的數(shù)據(jù)結(jié)構(gòu),它設(shè)計上更多的是考慮內(nèi)存的優(yōu)化,內(nèi)部是使用兩個數(shù)組進行數(shù)據(jù)存儲,一個數(shù)組記錄key的hash值,另外一個數(shù)組記錄Value值,它和SparseArray一樣,也會對key使用二分法進行從小到大排序,在添加、刪除、查找數(shù)據(jù)的時候都是先使用二分查找法得到相應(yīng)的index,然后通過index來進行添加、查找、刪除等操作,所以,應(yīng)用場景和SparseArray的一樣,如果在數(shù)據(jù)量比較大的情況下,那么它的性能將退化至少50%。

SparseArray//SparseArray比HashMap更省內(nèi)存,在某些條件下性能更好,主要是因為它避免了對key的自動裝箱(int轉(zhuǎn)為Integer類型),它內(nèi)部則是通過兩個數(shù)組來進行數(shù)據(jù)存儲的,一個存儲key,另外一個存儲value,為了優(yōu)化性能,它內(nèi)部對數(shù)據(jù)還采取了壓縮的方式來表示稀疏數(shù)組的數(shù)據(jù),從而節(jié)約內(nèi)存空間。

Map的基本操作:

Object?put(Object?key,?Object?value):?向集合中加入元素

Object?remove(Object?key):?刪除與KEY相關(guān)的元素

void?putAll(Map?t):??將來自特定映像的所有元素添加給該映像

void?clear():從映像中刪除所有映射

Map使用

這里以最常用的HashMap為例

添加數(shù)據(jù)

Map hashMap =newHashMap<>();

for(inti =0; i < maxCount; i++) {??

? ?? hashMap.put(i,String.valueOf(i));

}

遍歷entrySet方式

long start = System.currentTimeMillis();

for(Map.Entry entry : hashMap.entrySet()) {? ? ?

? ? ? ? Integer key=entry.getKey();

??????? String value=entry.getValue();? ? ?

? ? ??? System.out.println("key: "+ key +"value: "+value);?

? }??

long end = System.currentTimeMillis();?

? System.out.println("for-each方式 cost time : "+ (end - start));

entrySet迭代器遍歷方式

long start1 = System.currentTimeMillis();

Iterator> entries = hashMap.entrySet().iterator();

while(entries.hasNext()) {

???? Map.Entry entry = entries.next();?

? ?? Integer key=entry.getKey();

??? Stringvalue=entry.getValue();? ?

? ? System.out.println("key: "+ key +"value: "+value);

???? }

?long end1 = System.currentTimeMillis();

System.out.println("entrySet iterator迭代器 cost time : "+ (end1 - start1));

鍵找值遍歷

long end1 = System.currentTimeMillis();

?? System.out.println("iterator迭代器 cost time : "+ (end1 - start1));

??? long start2 = System.currentTimeMillis();

?? for (Integerkey: hashMap.keySet()) {? ?

? ? String value= hashMap.get(key);? ?

??? System.out.println("key: "+key+"value: "+value);

}

?? long end2 = System.currentTimeMillis();

? System.out.println("鍵找值遍歷 cost time : "+ (end2 - start2));

keySet迭代器遍歷

long start3 = System.currentTimeMillis();

Iterator iterator=hashMap.keySet().iterator();

while(iterator.hasNext()) {? ? ??

???? Integerkey=iterator.next();? ? ?

? ?? Stringvalue=hashMap.get(key);? ? ?

? ? System.out.println("key: "+key+"value: "+value);? ?

}

long end3 = System.currentTimeMillis();

System.out.println("keySet iterator迭代器 cost time : "+ (end3 - start3));

上述四種情況執(zhí)行結(jié)果如下:

總結(jié):

主要重新熟悉一下Map這種數(shù)據(jù)結(jié)構(gòu),以及更好的在以后的編程中選擇更合適的方式來進行key-value存儲。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容