Map 集合的回顧 與 java8 新增API的學習
阿新 • • 發佈:2019-01-07
簡述一下感想:
本篇部落格重點是對Map 在 java8 版本新增的API的學習PS: 其實在java8版本對所有介面都進行了改寫,Map就是一個典例]
java 8 對Map介面的改寫重點就體現在.它在許多方法的引數中允許傳入一個函式式介面,對map中的資料進行邏輯處理;
重點: 本篇只介紹Map 介面的變化.不涉及Map介面派生的子介面;
重點: 本篇只介紹Map 介面的變化.不涉及Map介面派生的子介面;
重點: 本篇只介紹Map 介面的變化.不涉及Map介面派生的子介面;
重要的事情說3遍!!!!!!!!
Map的特點
1. map的特點
- map 儲存具有對映關係的資料
- map 儲存了兩組值
- key 無序不可重複 [set的特點][ps: map和set關係密切]
- value 無序可重複
- key 與 value 單向一一對應
- 只要找到key 就可以更具key按圖索驥找到對應的value;
2. map與set的相似之處
- Map裡的 key集與Set集合裡元素的儲存形式也很像;
- Map與Set的子類在名字上也驚人的相似
- Set
- HashSet
- LinkedHashSet
- SortedSet(介面)
- TreeSet
- EnumSet
- ..
- Map
- HashMap
- LinkedHashMap
- SortedMap(介面)
- TreeMap
- EnumMap
- ...
- Set
3. Map中常用的API方法;[其實無非就是增刪查改][推薦大家直接看程式碼塊]
- void clear(): 清空Map,刪除該Map物件中的所有Key-value
- boolean containsKey(Object key): 查詢map中是否包含某個key ,包含返回true,不包含返回false;
- Boolean containsValue(Object value) : 查詢map中是否包含該value .包含返回true,不包含返回false;
- Set entrySet(): 返回Map中包含的key-value 鍵值對做主組成的Set集合,每個集合元素都是Map.Entry(Entry 是 Map的內部類)物件
- Object get(Object key): 返回只對key所對應的Value;如果此Map中不包含該key.則返回null.
- Boolean isEmpty(): 查詢該Map是否為空(即不包含任何Key-value對),如果為空則返回true;
- Set keySet(): 返回該Map中所有key組成的Set集合.
- Object put(Object key,Object value): 新增一個key-value對,如果當前map中已存在該key.則value 覆蓋原來的value;
- void putAll(Map map) : 將制定Map中的key-value對複製到map中
- Object remove(Object key) : 刪除指定的key_value對,返回指定key的value;如果key不存在則返回null;
- int size(); 返回map鍵值對的個數
- Collection values(): 返回該map中value所組成的Collection.
- .... 詳見JDK api
4. map常見的3中遍歷方式[詳見下面附的程式碼塊----在最後最後最後]
- keySet keySet集合
- entryMap map內部類-
- forEach() 方法 java 8 新增的
注意map 3 種遍歷的小小區別!!!
1. java8 為Map新增的方法[推薦大家直接看程式碼塊,程式碼塊中的註解有描述與情景]
- Object compute(Object key,BiFunction fm): 該方法使用 fm 根據原來的key-value計算一個新的value值
- 假如新的value 不為null 則替換掉舊的value;
- 假如新的value 和舊的的value 都為null ,則對本條鍵值對不做任何改變
- 假如舊的value 不為null 但是計算得出的新的value為null, 則刪除本條鍵值對
- Object computeIfAbsent(Object key,Function mf): 如果傳給該方法的key引數在Map中對應的value為null[前置條件],則使用mf 根據key計算一個新的value:
- 如果新的value不為null, 則覆蓋原來的value,如果為null也就沒變化,也沒意義;
- 如果map中不包含該Key 則會新增一組新的鍵值對;
- Object computeIfPresent(Object key,BiFunction rf) : 如果傳給該方法的key引數在Map中對應Value不為null[前置條件],則該方法使用rf根據原key,value計算一個新的value,
- 如果新的value不為null.則覆蓋原來value
- 如果新的value為null.則刪除該鍵值對
- void forEach(BiConsumer action); 該方法是java 8 為Map新增一個遍歷key-value對的方法.
- Object getOrDefault(Object key.V dValue) : 獲取指定key對應的value,如果該key不存在.則返回dValue;
- Object merge(Object key,Object value,BiFunction rf) : 該方法會先根據Key引數獲取該Map中對應的value,
- 如果獲取的value為null,則直接用傳入的value覆蓋原有的value(在這種情況下如果傳入的value也為null則刪除該key);
- 如果獲取的value不為null,則使用rf函式根據原value.新value計算一個新的結果,並用得到的結果去覆蓋原有的value;
- Object putIfAbsent(Object key,object value): 該方法會自動檢測指定的key對應的value是否為null,如果該key對應的value為null,該方法將會用新的value代替換來的null值;
- Object replace(Object key,Object value): 將Map中指定的key對應的value替換成新的value.與傳統的put()方法不同的是,該方法不可能新增新的key-value對.如果嘗試替換的key在原map中不存在.該方法不會新增key-value對,而是返回null.
- boolean replace(K key, V oldValue,V new Value) : 將Map中指定的key_value 對的源value替換成新value.如果在Map 中找到指定的key-value對.則執行替換並返回true,否則返回false.
- replaceAll(BiFunction f) 該方法使用BiFunction對原key-value 對進行計算,並將計算結果作為該key-value對的value值.
請copy下來跑一下...一切OK,看是沒有用的.跑跑.自己寫寫.測試一下
/**
* map 回顧 與 java8 新增的API的學習
*/
public class MapTest {
static Map<String, Object> map = new HashMap<>();
/**
* map 中的key 不可以重複; value可以重複
*/
@Before
public void before() {
map.put("牛頓", 1000);
map.put("愛因斯坦", 999);
map.put("愛迪生", "電");
map.put("特斯拉", "交流電");
}
@Test
public void apiTest() {
System.out.println("-----------apiTest Start---------------");
System.out.println();
/*
假如放入對某個key進行覆蓋.會返回原本的key
*/
Object o = map.put("愛迪生", "發明電燈泡");
System.out.println(Objects.toString(o));
System.out.println();
System.out.println("--------------美麗的分割線-----------");
System.out.println("是否包含某個key.包含返回true,反之false : " + map.containsKey("愛迪生"));
System.out.println("是否包含某個value.包含返回true,反之false: " + map.containsValue("愛迪生"));
System.out.println();
System.out.println("--------------美麗的分割線-----------");
System.out.println("根據指定key,返回對應的value.如果不存在該key,返回null: " + map.get("adb"));
System.out.println("根據指定key,返回對應的value.如果不存在該key,返回null: " + map.get("愛迪生"));
System.out.println();
System.out.println("--------------美麗的分割線-----------");
System.out.println("判斷map是否為空: " + map.isEmpty());
/*
putAll 的前提是 泛型一致,否則編譯出錯
*/
HashMap<String, Object> mmap = new HashMap<>();
mmap.put("998", "只要998 買不了吃虧買不了上當");
mmap.put("111", "110 120 119");
System.out.println();
System.out.println("--------------美麗的分割線-----------");
System.out.println("原始map key_value 對數 : " + map.size());
map.putAll(mmap);
System.out.println("putAll後 key_value 對數 : " + map.size());
System.out.println();
System.out.println("--------------美麗的分割線-----------");
System.out.println(" ---------remove 返回的性質類似於get ---------");
System.out.println("remove 刪除指定key的value 如果key不存在 返回null : " + map.remove("111"));
System.out.println("remove 刪除指定key的value 如果key不存在 返回null : " + map.remove("9999"));
System.out.println();
System.out.println("--------------美麗的分割線-----------");
System.out.println(" remove key_value 對 成功 true, 反之 false : " + map.remove("111", 999));
System.out.println();
System.out.println("-----------apiTest End---------------");
}
/**
*
*/
@Test
public void java8ApiTest() {
/*
Object compute(Object key,BiFunction fm): 該方法使用 fm 根據原來的key-value計算一個新的value值
假如新的value 不為null 則替換掉舊的value;
假如新的value 和舊的的value 都為null ,則對本條鍵值對不做任何改變,其實改變也沒有任何意義,反正都一樣
假如舊的value 不為null 但是計算得出的新的value為null, 則刪除本條鍵值對
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("compute:");
System.out.println("--------------------------------------");
System.out.println(" 假如新的value 不為null 則替換掉舊的value: ");
Object o = map.compute("愛迪生", (key, value) -> key + value);
System.out.println(Objects.toString(o));
System.out.println(map.get("愛迪生"));
System.out.println(" 假如舊的value 不為null 但是計算得出的新的value為null, 則刪除本條鍵值對: ");
Object a = map.compute("愛迪生", (key, value) -> null);
System.out.println(map.get("愛迪生"));
/*
Object computeIfAbsent(Object key,Function mf): 如果傳給該方法的key引數在Map中對應的value為null,
則使用mf 根據key計算一個新的value:
如果新的value不為null, 則覆蓋原來的value
如果map中不包含該Key 則會新增一組新的鍵值對;
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("computeIfAbsent:");
System.out.println("--------------------------------------");
System.out.println("如果map中不包含該Key 則會新增一組新的鍵值對;");
map.computeIfAbsent("愛迪生", key -> key.length()
);
System.out.println(map.get("愛迪生"));
//前提是傳給該方法的key引數的value為null
map.put("aaa", null);
System.out.println("如果新的value不為null, 則覆蓋原來的value");
map.computeIfAbsent("aaa", key -> (key.length() + key)
);
System.out.println(map.get("aaa"));
/*
Object computeIfPresent(Object key,BiFunction rf) :
如果傳給該方法的key引數在Map中對應Value不為null,
則該方法使用rf根據原key,value計算一個新的value,
如果新的value不為null.則覆蓋原來value
如果新的value為null.則刪除該鍵值對
前提是傳入key的value不為null
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("computeIfPresent: ");
System.out.println("--------------------------------------");
System.out.println("如果新的value不為null.則覆蓋原來value");
Object aaa = map.computeIfPresent("aaa", (key, value) -> {
return key.length() + ((String) value).length() + "";
});
System.out.println(map);
System.out.println("如果新的value為null.則刪除該鍵值對");
map.computeIfPresent("aaa", (key, value) -> {
return null;
});
System.out.println(map);
/*
Object getOrDefault(Object key,V dValue) : 獲取指定key對應的value,如果該key不存在.則返回DValue;
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("getOrDefault:");
System.out.println("--------------------------------------");
Object ads = map.getOrDefault("愛迪生", 998);
System.out.println(ads);
/*
Object merge(Object key,Object value,BiFunction rf) :
該方法會先根據Key引數獲取該Map中對應的value,
如果key對應的value為null,
則直接用傳入的value覆蓋原有的value
(在這種情況下如果傳入的value也為null則刪除該key);
如果key對應的value不為null,
則使用rf函式根據原value與
新value計算一個新的結果,並用得到的結果去覆蓋原有的value;
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("merge:");
System.out.println("--------------------------------------");
map.put("勞力士", null);
map.merge("勞力士", "998", (oldValue, newValue) -> {
return oldValue + "" + newValue;
});
System.out.println(map);
/*
注意雖然,方法沒有要求 value的值不可以傳入null,如果傳入了null就會丟擲空指標異常
檢視原始碼.merge 預設方法 中第一步就是對傳入的引數進行非空校驗.
--
以下為原始碼片段
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
值得一提的是key 可以傳入null
*/
// map.merge("勞力士",null,(oldValue,newValue)->{
// return oldValue+""+newValue;
// });
// System.out.println(map);
map.merge("勞力士", "998", (oldValue, newValue) -> {
return null;
});
System.out.println(map);
map.merge("愛因斯坦", "998", (oldValue, newValue) -> {
return oldValue + "" + newValue;
});
System.out.println(map);
}
@Test
public void java8ApiTest2() {
/*
Object putIfAbsent(Object key,object value):
該方法會自動檢測指定的key對應的value是否為null,
如果該key對應的value為null,
該方法將會用新的value代替換來的null值;
*/
//情景1: 假如 key 不存在. 它就和put方法沒有區別
//情景2: 假如key存在.就會自動檢測key對應的value是否為null,如果為null,則用引數中的value替代,反之沒變化
System.out.println(map);
map.putIfAbsent("name", null);
System.out.println(map);
map.putIfAbsent("name", "詹姆斯.高斯林");
System.out.println(map);
map.putIfAbsent("name", "name is flag");
System.out.println(map);
/*
Object replace(Object key,Object value):
將Map中指定的key對應的value替換成新的value.
與傳統的put()方法不同的是,該方法不可能新增新的key-value對.
如果嘗試替換的key在原map中不存在.該方法不會新增key-value對,而是返回null.
*/
// 前提是key值存在.然後新value替換舊value
// 假如 key不存在.不好意思.返回null map無變化sout
System.out.println();
System.out.println("----------------------------");
System.out.println("---------replace------------");
System.out.println("----------------------------");
map.replace("name", "妹大爺");
System.out.println(map);
map.replace("abc", "字元"); // key不存在, map無變化
System.out.println(map);
/*
boolean replace(K key, V oldValue,V new Value) :
將Map中指定的key_value 對的源value替換成新value.
如果在Map 中找到指定的key-value對.
則執行替換並返回true,否則返回false.
*/
System.out.println();
System.out.println("----------------------------");
System.out.println("---------replace2------------");
System.out.println("----------------------------");
System.out.println(map);
// 情景1: 假如key-value對存在.則新的value替換舊的value,並返回true
System.out.println(map.replace("name", "妹大爺", "梅蘭芳"));
System.out.println(map);
// 情景2: 假如 key-value對不存在,則map不會發生變化,並返回false
System.out.println(map.replace("name", "你大爺", "你二大爺"));
System.out.println(map);
/*
replaceAll(BiFunction f)
該方法使用BiFunction對原key-value對進行計算,
並將計算結果作為該key-value對的value值.
*/
System.out.println();
System.out.println("----------------------------");
System.out.println("---------replaceAll------------");
System.out.println("----------------------------");
System.out.println(map);
map.replaceAll((k, v) -> {
return k + "-" + v;
});
System.out.println(map);
}
/**
* map 的3中遍歷方式
* 有小小的區別
*/
@Test
public void mapTest() {
Map<String, Object> map = new HashMap<>();
map.put("西遊記", 112);
map.put("水滸傳", 993);
map.put("紅樓夢", 322);
map.put("三國演義", 998);
System.out.println("--------------------map的原始遍歷方式 1-----------------------");
Set<String> keySet = map.keySet();
for (String key : keySet) {
if("西遊記".equals(key)){
map.put("西遊記","吳承恩");
}
System.out.println(key + " : " + map.get(key));
}
System.out.println("--------------------map的原始遍歷方式 2-----------------------");
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String, Object> mp : entries) {
String key = mp.getKey();
Object value = mp.getValue();
if("西遊記".equals(key)){
map.put("西遊記",998998989);
}
System.out.println(key + " : " + value);
}
System.out.println("--------------------map的Lamdba遍歷方式 3-----------------------");
map.forEach((key, value) -> {
if("西遊記".equals(key)){
map.put("西遊記","吳承恩");
}
System.out.println(key + " : " + value);
});
/*
值得一提的java8 提供的forEach方法 操作的map集合,其實是取出entry物件在操作,也就是所有的key-value...
所以在修改過後再去遍歷.還是原來的entry[key-value]
*/
System.out.println("--------------------------再遍歷一次map--------------------------------");
map.forEach((key,value) ->{
System.out.println(key + " : " + value);
});
}
}