Java之映射(map)
目錄
1.兩種常用映射比較
2.基本映射操作
3.更新映射項
集是一個集合,它可以快速地查找現有的元素。但是,要查看一個元素,需要有要查找元素的精確副本。這不是一種非常通用的查找方式,因為在集合中查找元素總是要遍歷集合。通常,我們知道某些鍵的信息,并想要查找與之對應的元素。映射(map)數據結構就是為此而設計的。映射用來存放鍵/值對。如果提供了鍵,就能夠查找到值。它們之間是一一對應關系。
----注:以下所有介紹基于java 8(java 1.8)----
1.兩種常用映射比較
- Java類庫為映射提供了常用的兩個通用的實現:HashMap和TreeMap,這兩個類都實現了Map接口。
- HashMap對鍵進行散列,TreeMap用鍵的整體順序對元素進行排序,并將其組織成搜索樹。
- 散列或比較函數只能作用于鍵。與鍵關聯的值不能進行散列或比較。
- HashMap比TreeMap稍微快一些,所以在不需要按照排列順序訪問鍵的時候,最好選用HashMap。
- HashMap有一個子類也比較常用——LinkedHashMap,這個映射集合和HashMap的不同點就是,它將鍵/值對以插入順序進行排列,即遍歷的時候會按照插入的順序進行訪問元素。
2.基本映射操作
- OP->>要進行鍵值存儲,必須使用put方法。鍵必須是唯一的,如果對一對映射調用兩次put方法,則后一次調用會覆蓋前一次調用,并返回第一次調用的結果。
- OP->>要進行鍵值訪問,必須使用get方法,且只能通過鍵來訪問到值。
- OP->>如果找不到值卻不想返回一個空對象,則使用getOrDefault(var1,var2),如果找不到值則返回var2。
- OP->>要進行鍵值對的移除,則要使用remove(key)的方法。
- OP->>要想獲取鍵值對的數量,則要使用size()方法。
- OP->>要迭代處理每個鍵和值,最好是使用forEach方法,可以向這個方法提供一個lambda表達式,用來依次處理映射中的每一個元素。比如 scores.forEach((k,v)->System.out.println("key="+k+",value="+v));
?
下面示例程序演示了映射的操作過程,首先將鍵/值對添加到映射中。然后從映射中刪除一個鍵,同時與之對應的值也被刪除了。接下來,修改與某一個鍵對應的值,并調用get方法查看這個值。最后,迭代處理該映射集。
代碼:
package Collection.Map;import java.util.*;public class MapTest {public static void main(String[] args) {Map<String,Employee> staff=new HashMap<>();staff.put("144-25-5464", new Employee("Amy Lee"));staff.put("567-24-2546", new Employee("Harry Hacker"));staff.put("157-62-7935", new Employee("Gary Cooper"));staff.put("456-62-5527", new Employee("Francesca Cruz"));//打印所有成員System.out.println(staff);//刪除某一成員staff.remove("567-24-2546");//替代一個成員staff.put("456-62-5527", new Employee("Francesca Miller"));//查看一個成員System.out.println(staff.get("157-62-7935"));//遍歷映射staff.forEach((k,v)->System.out.println("key="+k+",value="+v));} }class Employee{String name;public Employee(String name) {this.name = name;}public String toString() {return "[name="+name+"]";} }運行結果:
?
下面是Map接口中常用的幾個方法及其解釋(從JDK 8文檔copy的)
- V get(Object key)
獲取與鍵對應的值;返回與鍵對應的對象,如果在映射中沒有這個對象則返回null。鍵可以為null。
- default V getOrDefault(Object key,V defaultValue)
獲得與鍵關聯的值;返回與鍵關聯的對象,或者如果未在映射中找到這個鍵,則返回defaultValue。
- V put(K key,V value)
將鍵與對應的值關系插入到映射中。如果這個鍵已經存在,新的對象將取代與這個鍵對應的舊對象。這個方法將返回鍵對應的舊值。如果這個鍵以前沒有出現過則返回null。鍵可以為null,但值不能為null。
- void putAll(Map<? extends K,? extends V> entries)
將給定映射中所有條目添加到這個映射中。
- boolean containsKey(Object key)
如果映射中已經有這個鍵,則返回true。
- boolean containsValue(Object value)
如果映射中已經有這個值,返回true。
- default void forEach(BiConsumer<? super K,? super V> action)
對這個映射中的所有鍵/值應用這個動作。
?
下面是HashMap類中常用的幾個方法及其解釋(從JDK 8文檔copy的)
- HashMap()
默認構造器
- HashMap(int initialCapacity)
用給定的容量構造一個空散列映射
- HashMap(int initialCapacity,float loadFactor)
用給定的容量和裝填因子構造一個空散列映射(裝填因子是一個0.0~1.0之間的一個數值。這個數值決定散列表填充百分比。一旦到了這個比例,就要將其再散列到更大的表中)。默認的裝填因子是0.75。
?
下面是TreeMap類中常用的幾個方法及其解釋(從JDK 8文檔copy的)
- TreeMap()
為實現Comparable接口的鍵構造一個空的樹映射
- TreeMap(Comparator<? super K> c)
構造一個樹映射,并使用一個指定的比較器對鍵進行排序
- TreeMap(Map<? extends K,? extends V> entries)
構造一個樹映射,并將某個映射中的所有條目添加到樹映射中
- TreeMap(SortedMap<? extends K,? extends V> entries)
構造一個樹映射,將某個有序映射中的所有條目添加到樹映射中,并使用與給定的有序映射相同的比較器。
?
下面是SortedMap接口(TreeMap實現了這個接口)的幾個方法及其解釋(從JDK 8文檔copy的)
- Comparator<? super K> comparator()
返回鍵進行排序的比較器。如果鍵是用Comparable接口的comparaTo方法進行比較的,返回null
- K firstKey()
- K lastKey()
返回映射中最小元素和最大元素
3.更新映射項
我們從前面的方法中知道,更新一個映射項使用的是put方法,但是,考慮下面一種情況,假如我想將下面一段話進行單詞統計,然后將得到的結果存放到一個映射表中。
句子:I am a handsome boy and you are a beautiful girl , so we can marry , then make love , finally create new lives . I believe certainly that our son will be a handsome boy and daughter will be a beautiful girl too , because I am a handsome boy and you are a beautiful girl .
我們可以定義一個counts的映射表。如果我們想向里面添加元素,我們會像如下那樣做:
counts.put(word,counts.get(word)+1);
但是有一個問題,如果原先映射表中不存在這個單詞,get方法就會返回一個null,這個時候就會拋出一個空指針異常。代碼和結果如下:
package Collection.Map;import java.util.*;public class MapTest2 {public static void main(String[] args) {String words="I am a handsome boy and you are a beautiful girl , so we can marry , then make love , finally create new lives . I believe certainly "+ "that our son will be a handsome boy and daughter will be a beautiful girl too , because I am a handsome boy and you are a beautiful girl .";Map<String,Integer> counts=new HashMap<>();Scanner in=new Scanner(words);String word=null;while(in.hasNext()) {word=in.next();counts.put(word, counts.get(word)+1);}in.close();System.out.println(counts);}}結果:
如果就使用前面我們所介紹方法,可以有以下兩種解決方案,第一種是在使用put方法之前首先進行檢查,第二種是使用getOrDefault方法。
下面是兩種示例代碼:
第一種:
package Collection.Map;import java.util.*;public class MapTest2 {public static void main(String[] args) {String words="I am a handsome boy and you are a beautiful girl , so we can marry , then make love , finally create new lives . I believe certainly "+ "that our son will be a handsome boy and daughter will be a beautiful girl too , because I am a handsome boy and you are a beautiful girl .";Map<String,Integer> counts=new HashMap<>();Scanner in=new Scanner(words);String word=null;while(in.hasNext()) {word=in.next();if(counts.get(word)==null) {counts.put(word,1);}else {counts.put(word, counts.get(word)+1);} }in.close();System.out.println(counts);} }第二種:
package Collection.Map;import java.util.*;public class MapTest2 {public static void main(String[] args) {String words="I am a handsome boy and you are a beautiful girl , so we can marry , then make love , finally create new lives . I believe certainly "+ "that our son will be a handsome boy and daughter will be a beautiful girl too , because I am a handsome boy and you are a beautiful girl .";Map<String,Integer> counts=new HashMap<>();Scanner in=new Scanner(words);String word=null;while(in.hasNext()) {word=in.next();counts.put(word, counts.getOrDefault(word, 0)+1);}in.close();System.out.println(counts);}}結果:...
除了像以上那樣進行修改,下面還可以提供兩種方法使其做的更好:
第一種是使用putIfAbsent方法,從字面意思上理解,就是不在的時候放入,正如我們所想,就是這樣。
具體在這個例子中使用的時候首先調用這個方法,如果不存在就放入一個0,然后調用put方法。第二種就是使用merge方法,merge方法是解決這個問題最好的方法,merge方法可以簡化這個常見的操作,如果原先的鍵不存在,下面的調用:counts.merge(word,1,Integer::sum);將把word與1關聯,否則使用Integer::sum方法組合原值和1(也就是將原值和1求和)。下面演示這兩個解決方案:
方案一:
package Collection.Map;import java.util.*;public class MapTest2 {public static void main(String[] args) {String words="I am a handsome boy and you are a beautiful girl , so we can marry , then make love , finally create new lives . I believe certainly "+ "that our son will be a handsome boy and daughter will be a beautiful girl too , because I am a handsome boy and you are a beautiful girl .";Map<String,Integer> counts=new HashMap<>();Scanner in=new Scanner(words);String word=null;while(in.hasNext()) {word=in.next();counts.putIfAbsent(word, 0);counts.put(word, counts.get(word)+1);}in.close();System.out.println(counts);}}方案二:
package Collection.Map;import java.util.*;public class MapTest2 {public static void main(String[] args) {String words="I am a handsome boy and you are a beautiful girl , so we can marry , then make love , finally create new lives . I believe certainly "+ "that our son will be a handsome boy and daughter will be a beautiful girl too , because I am a handsome boy and you are a beautiful girl .";Map<String,Integer> counts=new HashMap<>();Scanner in=new Scanner(words);String word=null;while(in.hasNext()) {word=in.next();counts.merge(word, 1, Integer::sum);}in.close();System.out.println(counts);}}結果同上。
?
下面給出了幾個常見的關于更新映射項的方法(從JDK 8文檔copy的)
- default V merge(K key,V value,Bifunction<? super Vzaa,? super V,? extends V> remappingFunction)
如果key與一個非null值v關聯,將函數應用到v和value,將key與結果關聯,或者如果結果為null,則刪除這個鍵。否則,將key與value關聯,返回get(key)
- default V compute(K key,Bifunction<? super K,? super V,? extends V> remappingFunction)
將函數應用到key和get(key)。將key與結果相關聯。或者如果結果為null,則刪除這個鍵,返回get(key)
- default V computeIfPresent(K key,Bifunction<? super K,? super V,? extends V> remappingFunction)
如果key與一個非null值v關聯,將函數應用到key和v,將key與結果關聯,或者如果為null,則刪除這個鍵。返回get(key)
- default V computeIfAbsent(K key,Function<? super K,? extends V> mappingFunction)
將函數應用到key,除非key與一個非null值關聯。鍵key與結果關聯,或者如果結果為null,則刪除這個鍵,返回get(key)
- default replaceAll(Bifunction<? super K,? super V,? extends V> remappingFunction)
在所有映射項上應用函數。將鍵與非null結果關聯,對于null結果,則將相應的鍵刪除。
4.映射視圖
有時候我們需要查看映射中的鍵集合,值集合(因為值可能存在相同的元素,所以嚴格來說不算是一個集合),以及鍵/值對集合。
下面三種方式分別返回鍵集合,值集合,鍵/值對集合
Set<K> keySet() Collection<V> values() Set<Map.Entry<K,V>> entrySet()下面一個程序演示了以上方法的調用,及其使用意義:
代碼:
package Collection.Map;import java.util.*; import java.util.Map.Entry;public class MapView {public static void main(String[] args) {Map<String,Integer> test=new HashMap<>();test.put("于理想",1);test.put("張琛",2);test.put("張艷杰",3);test.put("張哲鑫",4);test.put("閆智",5);test.put("孫崇偉",6);//下面枚舉鍵:Set<String> keys=test.keySet();for(String key:keys) {System.out.print(key+" ");}System.out.println();//下面枚舉值:Collection<Integer> values=test.values();for(Integer value:values) {System.out.print(value+" ");}System.out.println();//下面枚舉鍵/值對Set<Map.Entry<String, Integer>> mapping=test.entrySet();for(Map.Entry<String, Integer> map:mapping) {System.out.print(map+" ");}System.out.println();//注意:上面最后一個曾經是訪問所有映射條目的最有效的方法,但是,現在只需要使用forEach方法即可;test.forEach((k,v)->System.out.println("鍵="+k+",值="+v));} }運行結果:
?
參考資料《Java核心技術 卷I 第10版》
總結
以上是生活随笔為你收集整理的Java之映射(map)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不用找,你想要的简约ppt模板素材都在这
- 下一篇: html毕业答辩ppt,毕业答辩ppt