平时写代码时,经常有一些这样的处理:
例如:如果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流处理,在平时的编写代码中,可以大大的减少代码量。
真是活到老,学到老,不然很容易就会被小年轻们超越。
程序员之道,在无止境,扫码关注,一起无止境学习吧!