得益于 Java 8 的 default 方法特性,Java 8 对 Map 增加了不少实用的默认方法。
putIfAbsent 方法
其实简单的说:
传统的put方法,只要key存在,value值就会被覆盖,注意put方法返回的是put之前的值,如果无put之前的值返回null
putIfAbsent方法,只有在key不存在或者key为null的时候,value值才会被覆盖
源码如下:
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
map.putIfAbsent("t1", "aa");的的等价代码如下:
if(map.containsKey("t1")&&map.get("t1")!=null) {
map.put("t1", "aa");
}
使用场景:如果我们要变更某个key的值,我们又不知道key是否存在的情况下,而又不希望增加key的情况使用。
computeIfAbsent 方法
和putIfAbsent类似但是,在返回值上不一样,value值不存在的时候,返回的是新的value值,同时可以通过自定义一些条件进行过滤。
List list = Arrays.asList(
new People("大仙",2),
new People("朱半仙",15),
new People("半仙",8),
new People("大神",10),
new People("超神",8),
new People("大仙仙",2));
public void testcomputeIfAbsent () {
//声明接收结果的 map
Map> resultMap = new HashMap>();
//对所有的人按年龄进行分组
for (People people : list) {
//putIfAbsent方法,只有在key不存在或者key为null的时候,value值才会被覆盖 ,
List s = resultMap.putIfAbsent(people.getAge(), new ArrayList());
if(s==null) {//如果value值不存在,返回的是null,重新获取一遍
s = resultMap.putIfAbsent(people.getAge(), new ArrayList());
}
s.add(people);
}
System.out.println(resultMap);
resultMap = new HashMap>();
//对5岁以上的人进行分组
for (People people : list) {
//如果value值不存在,返回的是新的value值
List s = resultMap.computeIfAbsent(people.getAge(), k ->{
if(k>5) {
return new ArrayList();
}
return null;
});
if(s!=null) {
s.add(people);
}
}
System.out.println(resultMap);
}
computeIfPresent 方法
和computeIfAbsent方法正好相反,只有当key存在的时候才执行操作,那么我们把上面的需求变更下,对5岁以上的人进行分组,并且对8岁的人进行年龄加1操作。
//对5岁以上的人进行分组,并且设置所有的8岁的年龄增加1
resultMap = new HashMap>();
for (People people : list) {
List s = resultMap.computeIfAbsent(people.getAge(), k ->{
if(k>5) {
return new ArrayList();
}
return null;
});
if(s!=null) {
s.add(people);
}
}
//如果value值不存在,返回的是新的value值
resultMap.computeIfPresent(8, (k,v)->{
for(People people:v) {
people.setAge(people.getAge()+1);
}
return v;
});
System.out.println(resultMap);