国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Java中詳細解析Map接口

Java中詳細解析Map接口

2021-11-13 12:19IT劉華強 Java教程

這篇文章主要介紹了Java8 中 Map 接口的新方法,本文通過代碼實例給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

 

Map詳解:

先看圖,便于宏觀了解Map的地位。

Java中詳細解析Map接口

Map接口中鍵和值一一映射. 可以通過鍵來獲取值。

  • 給定一個鍵和一個值,你可以將該值存儲在一個Map對象. 之后,你可以通過鍵來訪問對應(yīng)的值。
  • 當(dāng)訪問的值不存在的時候,方法就會拋出一個NoSuchElementException異常.
  • 當(dāng)對象的類型和Map里元素類型不兼容的時候,就會拋出一個 ClassCastException異常。
  • 當(dāng)在不允許使用Null對象的Map中使用Null對象,會拋出一個NullPointerException 異常。
  • 當(dāng)嘗試修改一個只讀的Map時,會拋出一個UnsupportedOperationException異常。

 

Map基本操作:

Map 初始化

Map<String, String> map = new HashMap<String, String>();

插入元素

map.put("key1", "value1");

獲取元素

map.get("key1")

移除元素

map.remove("key1");

清空map

map.clear();

 

hashMap原理:

hashMap是由數(shù)組和鏈表這兩個結(jié)構(gòu)來存儲數(shù)據(jù)。

數(shù)組:存儲區(qū)間是連續(xù)的,占用內(nèi)存嚴(yán)重,故空間復(fù)雜的很大。但數(shù)組的二分查找時間復(fù)雜度小,為O(1);尋址容易,插入和刪除困難;

鏈表:存儲區(qū)間離散,占用內(nèi)存比較寬松,故空間復(fù)雜度很小,但時間復(fù)雜度很大,達O(N);尋址困難,插入和刪除容易。

hashMap則結(jié)合了兩者的優(yōu)點,既滿足了尋址,又滿足了操作,為什么呢?關(guān)鍵在于它的存儲結(jié)構(gòu)。

它底層是一個數(shù)組,數(shù)組元素就是一個鏈表形式,見下圖:

Java中詳細解析Map接口

Entry: 存儲鍵值對。

Map類在設(shè)計時提供了一個靜態(tài)修飾接口Entry。Entry將鍵值對的對應(yīng)關(guān)系封裝成了鍵值對對象,這樣我們在遍歷Map集合時,就可以從每一個鍵值對對象中獲取相應(yīng)的鍵與值。之所以被修飾成靜態(tài)是為了可以用類名直接調(diào)用。

Java中詳細解析Map接口

每次初始化HashMap都會構(gòu)造一個table數(shù)組,而table數(shù)組的元素為Entry節(jié)點,它里面包含了鍵key,值value,下一個節(jié)點next,以及hash值。

static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        int hash;
}

查看hashMap的API發(fā)現(xiàn),它有4個構(gòu)造函數(shù):

Java中詳細解析Map接口

1、構(gòu)造一個具有默認(rèn)初始容量 (16) 和默認(rèn)加載因子 (0.75) 的空 HashMap。

2、指定初始容量和默認(rèn)加載因子 (0.75) 的空 HashMap。

3、指定初始容量和默認(rèn)加載因子的空HashMap。

4、構(gòu)造一個映射關(guān)系與指定Map相同的新HashMap。

注意:HashMap使用的是懶加載,構(gòu)造完HashMap對象后,只要不進行put方法插入元素之前,HashMap并不會去初始化或者擴容table。

 

Put方法:

首先判斷是否是空數(shù)組(table == EMPTY_TABLE),如果是,開始初始化HashMap的table數(shù)據(jù)結(jié)構(gòu),然后執(zhí)行擴容函數(shù),如果未指定容量,默認(rèn)是大小為16的表,然后根據(jù)加載因子計算臨界值。什么是加載因子呢?hashMap的大小是一定的,如果不夠存儲了肯定要擴容,那么擴容的依據(jù)是什么呢,什么時候確定要擴容了呢?這個時候就需要引入加載因子這個概念,我們假使依舊使用默認(rèn)大小16,加載因子0.75,那么當(dāng)hashMap的size大于12(16*0.75=12)的時候,那么就會進行擴容。

回來說put方法,如果key是null,調(diào)用putForNullKey方法,保存null與key,這是HashMap允許為null的原因。然后計算hash值和用indexFor計算數(shù)據(jù)存在的位置,然后從i出開始迭代e,找到 key 保存的位置。

Java中詳細解析Map接口

Java中詳細解析Map接口

上面說到如果數(shù)組擴容,那么每次要怎么擴容呢?

Java中詳細解析Map接口

Java中詳細解析Map接口

當(dāng)size大于等于某一個閾值thresholdde時候且該table并不是一個空table,因為size 已經(jīng)大于等于閾值了,說明Entry數(shù)量較多,哈希沖突嚴(yán)重,那么若該Entry對應(yīng)的桶不是一個空桶,這個Entry的加入必然會把原來的鏈表拉得更長,因此需要擴容;若對應(yīng)的桶是一個空桶,那么此時沒有必要擴容。如果擴容,table會擴容為原來的兩倍,直到達到數(shù)組的最大長度1<<30(2的30次方),如果size大于這個值,那么就直接修改為Integer.MAX_VALUE。擴容后的元素hash值對應(yīng)的新的桶位置,然后在指定的桶位置上,創(chuàng)建一個新的Entry。

這里需要說明的是,hashmap是可以存放key和value均為null的,存放在table[0]的位置,此時使用put方法在添加元素的時候,如果在table[0]中已經(jīng)存入key為null的元素則給null賦上新的value值并返回后面的值,否則則初始化null的元素,存入put里面存放的值。

public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        hashMap.put(null, null);
        System.out.println(hashMap.get(null));
        Integer a = (Integer) hashMap.put(null, 1);
        System.out.println(a);
        System.out.println(hashMap.get(null));
}

輸出為:
null
null
1

 

Get方法:

Java中詳細解析Map接口

Get比較好理解,判斷key是不是null,如果是,返回getForNullKey的函數(shù)返回值,如果不是,則在table中去找。

Remove方法:

判斷,如果hashMap的size是0,返回null;找到需要移除的元素的前一個節(jié)點,然后把前驅(qū)節(jié)點的next指向刪除節(jié)點的next節(jié)點,此時當(dāng)前節(jié)點沒有任何引用指向,它在程序結(jié)束之后就會被gc回收。

final Entry<K,V> removeEntryForKey(Object key) {
    		if (size == 0) {
    		    return null;
    		}
   		 int hash = (key == null) ? 0 : hash(key);
   		 int i = indexFor(hash, table.length);
    		Entry<K,V> prev = table[i];
    		Entry<K,V> e = prev;
		 while (e != null) {
        		Entry<K,V> next = e.next;
       		 Object k;
       		 if (e.hash == hash &&
        		    ((k = e.key) == key || (key != null && key.equals(k)))) {
        		    modCount++;
         		   size--;
         		   if (prev == e)
          		      table[i] = next;
         		   else
          		      prev.next = next;
          		  e.recordRemoval(this);
         		   return e;
        		}
        		prev = e;
        		e = next;
   		 }
		 return e;
	}

 

Map的遍歷:

map這里可以用增強for和迭代器兩種方式遍歷:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class MapDemo {
    public static void main(String[] args) {
        HashMap<String, String> sets = new HashMap<>();
        sets.put("username", "value1");
        sets.put("password", "value2");
        sets.put("key3", "value3");
        sets.put("key4", "value4");
        sets.put(null,null);
        // 增強for循環(huán) =========== keySet ===================
        for (String s : sets.keySet()) {
            System.out.println(s + ".." + sets.get(s));
        }
        //================== entrySet ======================
        for (Map.Entry<String, String> m : sets.entrySet()) {
            System.out.println(m.getKey() + ".." + m.getValue());
        }
        // 迭代器 ================ keySet ===================
        Iterator it = sets.keySet().iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            System.out.println(key + ".." + sets.get(key));
        }
        //================== entrySet ======================
        Iterator<Map.Entry<String, String>> iterator = sets.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> m = iterator.next();
            System.out.println(m.getKey() + ".." + m.getValue());
        }
    }
}

 

TreeMap

這里簡要介紹下:TreeMap 是一個有序的key-value集合,繼承于AbstractMap,它是通過紅黑樹實現(xiàn)的。TreeMap 實現(xiàn)了NavigableMap接口,實現(xiàn)了Cloneable接口,實現(xiàn)了java.io.Serializable接口。

TreeMap基于紅黑樹(Red-Black tree)實現(xiàn)。該映射根據(jù)其鍵的自然順序進行排序,或者根據(jù)創(chuàng)建映射時提供的 Comparator 進行排序,具體取決于使用的構(gòu)造方法。TreeMap的基本操作 containsKey、get、put 和 remove 的時間復(fù)雜度是 log(n) 。另外,TreeMap是非同步的。 它的iterator 方法返回的迭代器是fail-fastl的。

紅黑樹(Red Black Tree) 是一種自平衡二叉查找樹,是在計算機科學(xué)中用到的一種數(shù)據(jù)結(jié)構(gòu),典型的用途是實現(xiàn)關(guān)聯(lián)數(shù)組。它有五個特點如下:

性質(zhì)1:節(jié)點是紅色或黑色。

性質(zhì)2:根節(jié)點是黑色。

性質(zhì)3:每個葉節(jié)點(NIL節(jié)點,空節(jié)點)是黑色的。

性質(zhì)4:每個紅色節(jié)點的兩個子節(jié)點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續(xù)的紅色節(jié)點)。

性質(zhì)5:從任一節(jié)點到其每個葉子的所有路徑都包含相同數(shù)目的黑色節(jié)點。

詳細了解請點擊。

 

LinkedHashMap:

HashMap是無序的,只要不涉及線程安全問題,Map基本都可以使用HashMap。如果我們期待一個有序的Map,這個時候,LinkedHashMap就派上用場了,它雖然增加了時間和空間上的開銷,但是通過維護一個運行于所有條目的雙向鏈表,LinkedHashMap保證了元素迭代的順序,該迭代順序可以是插入順序或者是訪問順序。那么是如何維護的呢,首先參考HashMap的存儲結(jié)構(gòu),將其中的Entry元素增加一個pre指針和一個next指針,這樣,根據(jù)插入元素的順序?qū)⒏鱾€元素依次連接起來,這樣LinkedHashMap就保證了元素的順序。

Java中詳細解析Map接口

繼承自HashMap,實現(xiàn)了Map接口,LinkedHashMap重寫了父類HashMap的get方法,實際在調(diào)用父類getEntry()方法取得查找的元素后,再判斷當(dāng)排序模式accessOrder為true時(即按訪問順序排序),先將當(dāng)前節(jié)點從鏈表中移除,然后再將當(dāng)前節(jié)點插入到鏈表尾部。

實現(xiàn)LRU緩存:

LinkedHashMap和HashMap+LinkedList的操作都是類似的,LRU緩存是我最近看到一個很巧妙的東西,所以推薦大家看一下這篇文章。

 

對比下Hashmap、Hashtable和ConcurrentHashmap:

第一、Hashmap是線程不安全的,Hashtable和ConcurrentHashMap是線程安全的,在Hashtable中使用了關(guān)鍵字synchronized修飾,加上了同步鎖;ConcurrentHashMap在JDK1.7中采用了鎖分離的技術(shù),每一個Segment都獨立上鎖,保證了并發(fā)的安全性;每一個Segment元素存儲的是HashEntry數(shù)組+ 鏈表,Segment的大小是一開始就確定的,后期不能再進行擴容,但是單個Segment里面的數(shù)組是可以擴容的。

Java中詳細解析Map接口

但是在JDK1.8上則摒棄了Segment的概念,而是直接用Node數(shù)組+鏈表+紅黑樹的數(shù)據(jù)結(jié)構(gòu)來實現(xiàn),如下圖所示,并發(fā)控制使用Synchronized和CAS來操作,每一個Node節(jié)點都是用volatile修飾的,整個看起來就像是優(yōu)化過且線程安全的HashMap。

Java中詳細解析Map接口

第二、Hashmap是可以存放key和value均為null的,存放在table[0]的位置,此時使用put方法在添加元素的時候,如果在table[0]中已經(jīng)存入key為null的元素則給null賦上新的value值并返回后面的值,否則則初始化null的元素,存入put里面存放的值。Hashtable和ConcurrentHashMap是不可以存放null的key或者value的,原因和并發(fā)狀態(tài)下的操作有關(guān),當(dāng)在并發(fā)狀態(tài)下執(zhí)行無法分辨是key沒找到的null還是有key值為null,這在多線程里面是模糊不清的,所以不允許put、get為null的元素,如果強行操作就會報空指針異常。

 

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注服務(wù)器之家的更多內(nèi)容!

原文鏈接:https://blog.csdn.net/jiguquan3839/article/details/84546835

延伸 · 閱讀

精彩推薦
  • Java教程Java實現(xiàn)搶紅包功能

    Java實現(xiàn)搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現(xiàn)搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經(jīng)有好久沒有升過級了。升級完畢重啟之后,突然發(fā)現(xiàn)好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發(fā)現(xiàn)了對于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7482021-02-04
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發(fā)項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲国产精品一区二区久久 | 成人妇女免费播放久久久 | 你懂的免费在线观看 | 精品国产乱码久久久久久牛牛 | 中文字幕综合 | 日韩美女毛片 | 欧美激情一区二区三级高清视频 | 婷婷午夜天 | 亚洲欧美高清 | 伊人网在线视频观看 | 一区二区乱码 | 国产中文字幕网 | 亚洲综合色视频在线观看 | 精品免费视频 | 亚洲精品9999| 色综合视频 | 亚洲精品专区 | 亚洲成人中文字幕 | 国产精品一二三区视频出来一 | av片免费看 | 在线免费国产 | 日本免费在线 | 久在线 | 亚洲精品在线视频观看 | 人人人人澡人人爽人人澡 | а天堂中文最新一区二区三区 | 影音先锋中文字幕在线观看 | 日本不卡在线 | 亚洲va国产天堂va久久 en | 欧美精品一区二区三区在线播放 | 国产在线一区二区三区 | www.色.com | 国产精品久久久久久久久 | 男人的天堂2018 | 一区二区三区免费观看视频 | 天天操,夜夜操 | 亚洲精品一区二区三区 | 国产人妖一区 | 在线国产一区二区 | 久久久久久久久久久久久av | 黄色免费在线观看 |