Java集合之Map接口與實現(xiàn)類詳解
初識Map
Map接口沒有從Collection接口繼承,Map接口用于維護(hù)“鍵-值”對數(shù)據(jù),這個“鍵-值”對就是Map中的元素,Map提供“鍵(Key)”到“值(value)”的映射,一個Map中鍵值必須是唯一的,不能有重復(fù)的鍵,因為Map中的“鍵-值”對元素是通過鍵來唯一標(biāo)識的,Map的鍵是用Set集合來存儲的,所以充當(dāng)鍵元素的類必須重寫hashCode()和equals()方法,通過鍵元素來檢索對應(yīng)值元素
Map中常用方法
V put(K key, V value) //向Map集合中添加鍵值對 V get(Object key) //返回指定鍵映射到的值,通過key獲取value void clear() //從此映射中刪除所有映射,清空Map集合 boolean containsKey(Object key) //判斷Map是否包含某個key boolean containsValue(Object value) //判斷Map是否包含某個value boolean isEmpty() //判斷Map中元素個數(shù)是否為0 Set<K> keySet() //獲取Map集合中所有的key(所有的鍵都是一個“Set集合”) V remove(Object key) //通過key刪除鍵值對,如果存在,則從該映射中移除鍵的映射(可選操作) int size() //獲取Map集合中鍵值對的個數(shù)
HashMap
HashMap特點(diǎn)
(1)HashMap實現(xiàn)了Map 接口
(4)HashMap以Hash表為基礎(chǔ)構(gòu)建
(2)HashMap 允許鍵(Key)為空和值(Value)為空
(3)HashMap不是線程安全的,不能用在多線程環(huán)境中
HashMap常用的構(gòu)造方法如下
(1)HashMap():創(chuàng)建一個空 HashMap 對象,并為其分配默認(rèn)的初始容量和加載因子
(2)HashMap(int initialCapacity):創(chuàng)建一個空 HashMap 對象,并為其分配指定的初始容量
(3)HashMap(int initialCapacity,float loadFactor);創(chuàng)建一個空 HashMap 對象,并其分配指定的初始容量和加載因子
(4)HashMap(Map m):創(chuàng)建一個與給定Map 對象具有相同鍵-值對的 HashMap 對象
HashMap方法的簡單使用
import java.security.Key; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class Warehouse1 { public static void main(String[] args){ HashMap<String,Integer> hashMap=new HashMap<>(); hashMap.put("年齡",20); hashMap.put("身高",180); hashMap.put("體重",60); System.out.println("鍵為年齡所對應(yīng)的值為:"+hashMap.get("年齡")); System.out.println("該map是否包含鍵為“年齡”?"+hashMap.containsKey("年齡")); System.out.println("該map是否包含鍵值為90?"+hashMap.containsValue(90)); System.out.println("該map是否為空?"+hashMap.isEmpty()); System.out.println("該map的長度大小為:"+hashMap.size()); System.out.println("移除鍵為“體重“的鍵值對"+hashMap.remove("體重")); System.out.println("哈希映射中的內(nèi)容如下:"+hashMap); Set<String> keys=hashMap.keySet(); Iterator<String> iterator=keys.iterator(); System.out.println("hashmap中的元素如下:"); while(iterator.hasNext()){ String s= iterator.next(); Integer name= hashMap.get(s); System.out.println(s+":"+name); } } }
輸出:
鍵為年齡所對應(yīng)的值為:20
該map是否包含鍵為“年齡”?true
該map是否包含鍵值為90?false
該map是否為空?false
該map的長度大小為:3
移除鍵為“體重“的鍵值對60
哈希映射中的內(nèi)容如下:{年齡=20, 身高=180}
hashmap中的元素如下:
年齡:20
身高:180
小tips:在輸出map中的元素時,我們不能直接使用iterator[迭代器],對元素進(jìn)行遍歷輸出,因為迭代只能用在Set/List這種單列存放數(shù)據(jù)的集合中,而map是雙列的,并且也不能使用foreach語句對map進(jìn)行輸出,因為foreach語句的本質(zhì)也是迭代,只能用在單列集合中。
LinkedHashMap
LinkedHashMap有如下特點(diǎn)
1:LinkedHashMap實現(xiàn)了Map接口
2:LinkedHashMap繼承了HashMap,內(nèi)部還有一個雙向鏈表維護(hù)鍵-值對的順序,每個鍵-值對即位于哈希表中,也位于雙向鏈表中
3:LinkedHashMap保存了兩種元素順序,輸入順序和訪問順序,插入順序是指先添加的元素在前面,后添加的元素在后面,修改對應(yīng)的元素不會影響元素的順序,訪問順序指的是get/put操作,對一個鍵執(zhí)行put/get操作后,其對應(yīng)的鍵-值對會移動到鏈表末尾,所以最末尾的元素是最近訪問的,最開始的是最久沒有被訪問的
4:LinkedHashMap不是線程安全的,不能用在多線程環(huán)境中
LinkedHashMap的構(gòu)造方法如下
1:LinkedHashMap();構(gòu)造一個空的LinkedHashMap對象
2:LinkedHashMap(Map m);構(gòu)造一個具有和給定Map相同鍵-值對的LinkedHashMap對象
3:LinkedHashMap(int capacity):構(gòu)造一個給定初始容量capacity的LinkedHashMap對象
4:LinkedHashMap(int capacity,float fillRatio):構(gòu)造一個給定初始容量capacity和填充比fillRatio的LinkedHashMap對象
5:LinkedHashMap(int capacity,float fillRatio,boolean accessOrder):構(gòu)造一個給定初始容量capacity,填充比fillRatio以及是否被訪問順序的LinkedHashMap對象,access-sOrder為true表示按訪問順序,否則按插入順序。
注:前四種構(gòu)造方法創(chuàng)建的LinkedHashMap對象都是按插入順序
注:fillRatio是裝載因子,范圍在0-1.0之間,默認(rèn)是0.75。當(dāng)實際元素個數(shù)/容量 > fillRatio, HashMap自動進(jìn)行擴(kuò)容,以保證檢索速度
舉例:
分別創(chuàng)建兩個LinkedHashMap對象-----linkedHashMap和linkedHashMap1
linkedHashMap是以上述五種方法中的第一種構(gòu)造的LinkedHashMap對象,而linkedHashMap1是以上述五種方法中的第5種構(gòu)造的LinkedHashMap對象.
代碼如下:
import java.security.Key; import java.util.*; public class Warehouse1 { public static void main(String[] args){ LinkedHashMap<String,Integer> linkedHashMap=new LinkedHashMap<>(); linkedHashMap.put("number1",10); linkedHashMap.put("number2",20); linkedHashMap.put("number3",30); linkedHashMap.put("number4",40); linkedHashMap.get("number1"); linkedHashMap.get("number4"); Set <Map.Entry<String,Integer>> sets=linkedHashMap.entrySet();//Map.Entry是Map的一個內(nèi)部類,表達(dá)一個 key/value映射關(guān)系 System.out.println("linkedHashMap中的元素為:"); for(Map.Entry<String,Integer> entry:sets) { System.out.println("鍵為:" + entry.getKey() + ",值為:" + entry.getValue()); } System.out.println("---------------"); LinkedHashMap<String,Integer> linkedHashMap1=new LinkedHashMap<String,Integer>(3,0.5f,true); linkedHashMap1.put("number1",10); linkedHashMap1.put("number2",20); linkedHashMap1.put("number3",30); linkedHashMap1.put("number4",40); linkedHashMap1.get("number1"); linkedHashMap1.get("number4"); linkedHashMap1.put("number3",1000); Set<Map.Entry<String,Integer>> set=linkedHashMap1.entrySet(); System.out.println("linkedHashMap1中的元素為:"); for(Map.Entry<String ,Integer> entry1:set) { System.out.println("鍵為:" + entry1.getKey() + "值為:" + entry1.getValue()); } } }
輸出:
linkedHashMap中的元素為:
鍵為:number1,值為:10
鍵為:number2,值為:20
鍵為:number3,值為:30
鍵為:number4,值為:40
---------------
linkedHashMap1中的元素為:
鍵為:number2值為:20
鍵為:number1值為:10
鍵為:number4值為:40
鍵為:number3值為:1000
通過輸出結(jié)果,我們不難發(fā)現(xiàn),linkedHashMap中的元素輸出的順序為我們插入時的順序,而linkedHashMap1中的元素輸出順序為訪問順序,由于這種構(gòu)造對象的方法,我們設(shè)置了access-sOrder為true,因此輸出順序按訪問順序,linkedHashMap1.get(“number1”),表示訪問number1,訪問完之后,該鍵值對就移動到最后,下面兩行的操作產(chǎn)生的影響也是這樣linkedHashMap1.get(“number4”);linkedHashMap1.put(“number3”,1000)。
當(dāng)按照訪問順序時,put和get去操作已經(jīng)存在的Entry時,都會把Entry移動到雙向鏈表的表尾[實際是先刪除再插入]
TreeMap
TreeMap有如下特點(diǎn)
1:TreeMap實現(xiàn)了SortedMap接口
2:TreeMap和實現(xiàn)Map的其他對象不同的是,它不具有調(diào)優(yōu)選項
3:TreeMap中所有元素必須是可比較的
4:TreeMap不是線程安全的
TreeMap的構(gòu)造方法如下
1:TreeMap():構(gòu)造一個空的TreeMap對象
2:TreeMap(Map m):構(gòu)造一個具有和給定Map相同鍵-值對的TreeMap對象
3:TreeMap(Comparator c):構(gòu)造一個空的TreeMap對象,并且規(guī)定特定的排列方式
4:TreeMap(SortedMap a):構(gòu)造一個與給定的SortedMap具有相同鍵-值對,相同排列規(guī)則的TreeMap對象
TreeMap方法的簡單使用
import java.util.*; public class Warehouse1 { public static void main(String[] args) { TreeMap<String,String> treeMap=new TreeMap<>(); treeMap.put("水果","蘋果"); treeMap.put("汽車","奔馳"); treeMap.put("城市","西安"); System.out.println("映射中的元素是:"+treeMap); Set<String> keySet=treeMap.keySet(); Iterator<String> iterator=keySet.iterator(); System.out.println("TreeMap類實現(xiàn)的Map映射,按鍵值升序排列元素如下:"); while(iterator.hasNext()){ String it=iterator.next(); String name=treeMap.get(it); System.out.println(it+":"+name); } } }
輸出:
映射中的元素是:{城市=西安, 水果=蘋果, 汽車=奔馳}
TreeMap類實現(xiàn)的Map映射,按鍵值升序排列元素如下:
城市:西安
水果:蘋果
汽車:奔馳
注:TreeMap默認(rèn)排序規(guī)則:按照key的字典順序來排序[升序],當(dāng)然也可以通過Comparator接口,去自定義排序規(guī)則。
HashMap和TreeMap的比較
HashMap和TreeMap在實際應(yīng)用中要使用哪一個,還是需要根據(jù)實際情況進(jìn)行分析,在Map中插入,刪除和定位元素,HashMap是最好的選擇,但是如果要按順序遍歷鍵,那么TreeMap會更好,根據(jù)集合大小,先把元素添加到HashMap,再把這種映射轉(zhuǎn)換成一個用于有序鍵遍歷的TreeMap會更快,使用HashMap要求添加的鍵類明確定義了hashcode()實現(xiàn),有了TreeMap實現(xiàn),添加到映射的元素一定是可排序的。
Hashtable
Hashtable有如下特點(diǎn)
1:Hashtable實現(xiàn)了map接口
2:Hashtable以Hash表基礎(chǔ)構(gòu)建
3:Hashtable和HashMap在執(zhí)行過程中具有一定的相似性
4:Hashtable中不允許空元素,即鍵和值都不允許為空
5:Hashtable是線程安全的,可以在多線程環(huán)境中使用
Hashtable的四個構(gòu)造方法如下
Hashtable();創(chuàng)建一個空Hashtable對象,并為其分配默認(rèn)的初始容量和加載因子
Hashtable(int initialcapacity);創(chuàng)建一個空Hashtable對象,并為其分配指定的初始容量
Hashtable(int initialcapacity,float loadFactor):創(chuàng)建一個空Hashtable對象,并指定其初始容量和加載因子
Hashtable(Map m);創(chuàng)建一個與給定Map對象具有相同鍵-值對的Hashtable對象
Hashtable新增的常用方法
舉例:
import java.util.*; public class Warehouse1 { public static void main(String[] args) { Hashtable<String,Double> hashtable=new Hashtable<>(); hashtable.put("王俊凱",new Double(350.55)); hashtable.put("王源",new Double(3250.55)); hashtable.put("易烊千璽",new Double(1350.55)); Enumeration<String> names=hashtable.keys(); while(names.hasMoreElements()){ String name=names.nextElement(); System.out.println(name+":"+hashtable.get(name)); } double new_double=hashtable.get("易烊千璽").doubleValue(); hashtable.put("易烊千璽",new Double(new_double+2000)); System.out.println("易烊千璽的新余額為:"+hashtable.get("易烊千璽")); } }
輸出:
易烊千璽:1350.55
王源:3250.55
王俊凱:350.55
易烊千璽的新余額為:3350.55
集合中元素的遍歷
Collection接口的iterator()方法返回一個iterator對象,iterator接口能以迭代方式逐個訪問集合中各個元素,并安全地從Collection中除去適當(dāng)?shù)脑兀琲terator接口中定義的方法如下所示:
iterator接口中的方法
- boolean hasNext();判斷游標(biāo)右邊是否還有元素
- Object next();返回游標(biāo)右邊的元素并將游標(biāo)移動到該元素后
- void remove();刪除游標(biāo)左邊的元素,通常在next()方法之后執(zhí)行,只執(zhí)行一次
Enumeration接口的功能與iterator接口類似,也能夠?qū)现械脑剡M(jìn)行遍歷,但是Enumeration接口只對Vector,Hashtable類提供遍歷方法,并且不支持移除操作,實現(xiàn)Enumeration接口的對象,它生成一系列元素,一次生成一個,連續(xù)調(diào)用,nextElement方法將返回一系列的連續(xù)元素
Enumeration接口中的方法
boolean hasMoreELements(); 如果存在訪問的更多元素,則返回true
Object nextEment(); 返回下一個元素的引用
到此這篇關(guān)于Java集合之Map接口與實現(xiàn)類詳解的文章就介紹到這了,更多相關(guān)Java Map接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java?CompletableFuture實現(xiàn)原理分析詳解
CompletableFuture是Java8并發(fā)新特性,本文我們主要來聊一聊CompletableFuture的回調(diào)功能以及異步工作原理是如何實現(xiàn)的,需要的可以了解一下2022-09-09idea中方法、注釋、導(dǎo)入類折疊或是展開的設(shè)置方法
這篇文章主要介紹了idea中方法、注釋、導(dǎo)入類折疊或是展開的設(shè)置,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04SpringMVC?bean實現(xiàn)加載控制方法詳解
SpringMVC是一種基于Java,實現(xiàn)了Web?MVC設(shè)計模式,請求驅(qū)動類型的輕量級Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦?;谡埱篁?qū)動指的就是使用請求-響應(yīng)模型,框架的目的就是幫助我們簡化開發(fā),SpringMVC也是要簡化我們?nèi)粘eb開發(fā)2022-08-08Java實現(xiàn)在正則表達(dá)式中控制大小寫的方法
這篇文章主要介紹了Java實現(xiàn)在正則表達(dá)式中控制大小寫的方法,結(jié)合實例形式分析了java正則表達(dá)式中傳遞控制參數(shù)的功能與相關(guān)操作技巧,需要的朋友可以參考下2017-04-04Spring Boot啟動時調(diào)用自己的非web邏輯
在spring Boot中,有些代碼是WEB功能,例如API等,但是有些邏輯是非WEB,啟動時就要調(diào)用并持續(xù)運(yùn)行的,該如何加載自己的非WEB邏輯呢,下面通過實例代碼給大家講解,一起看看吧2017-07-07以Spring Boot的方式顯示圖片或下載文件到瀏覽器的示例代碼
這篇文章主要介紹了以Spring Boot的方式顯示圖片或下載文件到瀏覽器的示例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01SpringBoot結(jié)合FreeMarker視圖渲染的實現(xiàn)
FreeMarker它允許開發(fā)人員使用模板和數(shù)據(jù)來生成輸出文本,如HTML網(wǎng)頁、電子郵件、配置文件和源代碼等,本文主要介紹了SpringBoot結(jié)合FreeMarker視圖渲染的實現(xiàn),感興趣的可以了解一下2024-03-03Java用單向環(huán)形鏈表來解決約瑟夫環(huán)Josepfu問題
如果把單鏈表的最后一個節(jié)點(diǎn)的指針指向鏈表頭部,而不是指向NULL,那么就構(gòu)成了一個單向循環(huán)鏈表,通俗講就是把尾節(jié)點(diǎn)的下一跳指向頭結(jié)點(diǎn)2021-10-10