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