平時寫代碼時,經常有一些這樣的處理:
例如:如果key存在,則在原來的基礎之上+1,或其他操作,如果key不存在,那麼賦一個初始值,假設爲1。
JDK8之前寫法
每次都需要判斷下map.containsKey(),真的好煩啊!
public void jdk7Access(int[] nums, Map<Integer, Integer> map) {
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(i)) {
map.put(i, map.get(i)+1);
} else {
map.put(i, 1);
}
}
//統計map中key對應的value總值,僅爲了展示,其實可以直接用map.values去遍歷
int count = 0;
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(i)) {
count += map.get(i);
}
}
System.out.println(count);
}
JDK8真是簡單啊
public void jdk8Access(int[] nums, Map<Integer, Integer> map) {
for (int i = 0; i < nums.length; i++) {
map.compute(i, (k,v) -> v == null ? 1 : v+1);
}
int count = 0;
for (int i = 0; i < nums.length; i++) {
count += map.getOrDefault(i, 0);
}
System.out.println(count);
}
map.compute到底幹了啥
沒有什麼比源碼中講的更清楚的了,總體來說就是,如果賦值的newValue==null,那麼將原來的key刪掉,否則的話,將map中的value用newValue替代。api的返回值可能是null(newValue爲null)或newValue。
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key);
V newValue = remappingFunction.apply(key, oldValue);
if (newValue == null) {
// delete mapping
if (oldValue != null || containsKey(key)) {
// something to remove
remove(key);
return null;
} else {
// nothing to do. Leave things as they were.
return null;
}
} else {
// add or replace old mapping
put(key, newValue);
return newValue;
}
}
函數註釋中也有具體的用法
map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}
只用一行代碼就搞定了我們之前用四行代碼可以搞定的事情,世界真是清淨了許多啊。
map.getOrDefault你更值得擁有
有時候,我們從map中可能拿不到值,這時候經常需要去做一些null或空指針的判斷,徒增代碼量,顯得代碼一點也不優雅,這裏可以使用這個api,這個api其實很簡單,如果指定的key不存在value,則返回你指定的默認值。
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
要注意,這個api傳入的key不可以爲null,不然會拋空指針異常。
建議
要多看源碼,擁抱變化,JDK8增加了很多語法糖,lamada表達式,stream流處理,在平時的編寫代碼中,可以大大的減少代碼量。
真是活到老,學到老,不然很容易就會被小年輕們超越。
程序員之道,在無止境,掃碼關注,一起無止境學習吧!