HashMap.computeIfAbsent与computeIfPresent

HashMap.computeIfAbsent
如果需要向Map中push一个键值对,需要判断K key在当前map中是否已经存在,不存在则通过后面的 Function<? super K, ? extends V> mappingFunction 来进行value计算,且将结果当作value同key一起push到Map中。

computeIfAbsent() 方法的用法总结:

只有在当前 Map 中 key 对应的值不存在或为 null 时 ,才调用 mappingFunction,并在 mappingFunction 执行结果非 null 时,将结果跟 key 关联,mappingFunction 为空时 将抛出空指针异常。

公共代码:

Map <String, List<Integer>> map=new HashMap<>();
List<Integer> l1=new ArrayList();List <Integer> l2=new ArrayList<>();
l1.add(1);l1.add(11);l2.add(2);l2.add(22);
map.put("1",l1);
map.put("2",l2);

接下来就是使用了:

写法1:

List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
System.out.println(map.computeIfAbsent("2",v->l3));
System.out.println(map);

结果:如果原来map中有2,那么不会更新原来的值,并且computeIfAbsent方法返回原有的2这条值对于的value

[2, 22]
{1=[1, 11], 2=[2, 22]}

写法2:

List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
System.out.println(map.computeIfAbsent("3",v->l3));
System.out.println(map);

结果:如果原来map中无3那么会向map中新增3这条值,并且computeIfAbsent方法返回新增的3这条值的value

[3, 33]
{1=[1, 11], 2=[2, 22], 3=[3, 33]}

写法3:

System.out.println(map.computeIfAbsent("3",v->null));
System.out.println(map);

结果:如果原来map中无3,并且mappingFunction的返回值为null(新增的value为null),则不会新增这条记录,并且computeIfAbsent方法返回的是null值

null
{1=[1, 11], 2=[2, 22]}

写法4:

System.out.println(map.computeIfAbsent("3",k->{
    List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
    return l3;
}));
System.out.println(map);

或者:


List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
System.out.println(map.computeIfAbsent("3",k->{
    return l3;
}));
System.out.println(map);

结果:和上面写法2是一样的,只不过把返回值写成函数的形式了

[3, 33]
{1=[1, 11], 2=[2, 22], 3=[3, 33]}

写法5:

List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
System.out.println(map.computeIfAbsent("3",k->{
    System.out.println(k);
    List<Integer> l4=new ArrayList<>();l4.add(4);l4.add(44);
    map.put("4",l4);
    return l3;
}));
System.out.println(map);

结果:这么套娃也是可以的,这里为了验证先添加的3还是先添加的4,我们继续试验

3
[3, 33]
{1=[1, 11], 2=[2, 22], 3=[3, 33], 4=[4, 44]}

写法6:

List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
System.out.println(map.computeIfAbsent("3",k->{
    System.out.println(k);
    List<Integer> l4=new ArrayList<>();l4.add(4);l4.add(44);
    map.put("3",l4);
    return l3;
}));
System.out.println(map);

结果:这里明显可以看出来,computeIfAbsent方法先判断3是否存在在map中,判断不存在,则执行mappingFunction方法获得返回值,如果3存在,则不会执行mappingFunction方法,这里执行后先赋值3,最后在替换掉3,当然,正常情况是不会这么用的,这相当于骗了computeIfAbsent方法,哈哈

3
[3, 33]
{1=[1, 11], 2=[2, 22], 3=[3, 33]}

写法7:

System.out.println(map.computeIfAbsent("2",null));
System.out.println(map);

结果:不管key存在不存在,只要mappingFunction为空,则直接报错

Exception in thread "main" java.lang.NullPointerException
at java.util.HashMap.computeIfAbsent(HashMap.java:1098)
at Test1.main(Test1.java:14)

一共这7种写法吧,如果有不足,还需要及时补充;

HashMap.computeIfPresent

computeIfPresent() 方法对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。

computeIfPresent() 方法的语法为:hashmap.computeIfPresent(K key, BiFunction remappingFunction)

公共代码:

Map <String, List<Integer>> map=new HashMap<>();
List<Integer> l1=new ArrayList();List <Integer> l2=new ArrayList<>();
l1.add(1);l1.add(11);l2.add(2);l2.add(22);
map.put("1",l1);
map.put("2",l2);

写法1:

List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
System.out.println(map.computeIfPresent("2",(k,v)->l3));
System.out.println(map);

结果:如果map中2存在,则修改map中2的value值,并且返回新修改的值;

[3, 33]
{1=[1, 11], 2=[3, 33]}

写法2:

List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
System.out.println(map.computeIfPresent("3",(k,v)->l3));
System.out.println(map);

结果:如果要修改的key值不存在,则不修改值,并且返回空值
null
{1=[1, 11], 2=[2, 22]}

写法3:

System.out.println(map.computeIfPresent("2",(k,v)->null));
System.out.println(map);

结果:如果map中存在值,并且要修改的值为空,则会删除掉原来map中的存在的值

null
{1=[1, 11]}

写法4:

List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
System.out.println(map.computeIfPresent("2",(k,v)->{
    return l3;
}));
System.out.println(map);

或者:

System.out.println(map.computeIfPresent("2",(k,v)->{
    List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
    return l3;
}));
System.out.println(map);

结果:和上面的写法1一样,只不过改成了函数的形式

[3, 33]
{1=[1, 11], 2=[3, 33]}

写法5:

System.out.println(map.computeIfPresent("2",(k,v)->{
    System.out.println(k);
    System.out.println(v);
    List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
    List<Integer> l4=new ArrayList<>();l4.add(4);l4.add(44);
    map.put("4",l4);
    return l3;
}));
System.out.println(map);

结果:这么套娃也是可以的,为了验证先添加的4还是先修改的2,我们继续试验

2
[2, 22]
[3, 33]
{1=[1, 11], 2=[3, 33], 4=[4, 44]}

写法6:

System.out.println(map.computeIfPresent("2",(k,v)->{
    System.out.println(k);
    System.out.println(v);
    List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33);
    List<Integer> l4=new ArrayList<>();l4.add(4);l4.add(44);
    map.put("2",l4);
    return l3;
}));
System.out.println(map);

结果:这里明显可以看出来,computeIfPresent方法先判断2是否存在在map中,判断存在,则执行mappingFunction方法获得返回值,如果2不存在,则不会执行mappingFunction方法,这里执行后先赋值2,最后在替换掉2,当然,正常情况是不会这么用的,这相当于骗了computeIfAbsent方法,哈哈

写法7:

System.out.println(map.computeIfPresent("2",null));
System.out.println(map);

结果:不管key存在不存在,只要mappingFunction为空,则直接报错

Exception in thread "main" java.lang.NullPointerException
at java.util.HashMap.computeIfPresent(HashMap.java:1151)
at Test1.main(Test1.java:14)

一共这7种写法吧,如有不足吗,还会及时补充。