Java中 Map集合 compute 、computeIfAbsent 、 computeIfPresent、putIfAbsent 、getOrDefault 方法的区别

Java中 Map集合 compute 、computeIfAbsent 、 computeIfPresent、putIfAbsent 、getOrDefault 方法的区别

一、概述

最近在写代码过程中,发现java map中增加一些方法:compute 、computeIfAbsent 、 computeIfPresent、putIfAbsent 、getOrDefault , 在平时开发中要到一些,但是没有仔细对比各个方法之间的区别。 本文将系统性的整理 几个重要的方法区别:

  • compute 3个方法之间的区别;
  • putIfAbsent 和computeIfAbsent 方法的异同点 ;
  • put 和 putIfAbsent方法的区别。

二、代码演示

        1、 get 和 getOrDefault 方法演示

@Test
public void getAndgetOrDefaultTest() throws Exception {
    final HashMap<Object, Object> map = Maps.newHashMap();
    map.put("name", "名字");
    System.out.println("get 获取存在: " + map.get("name"));
    System.out.println("get 获取不存在: " + map.get("hh"));
    System.out.println("getOrDefault 获取存在: " + map.getOrDefault("name", " 不存在值"));
    System.out.println("getOrDefault 获取不存在: " + map.getOrDefault("hh", " 不存在值"));

}

        1.1、get 和 getOrDefault 方法 输出结果

get 获取存在: 名字
get 获取不存在: null
getOrDefault 获取存在: 名字
getOrDefault 获取不存在:  不存在值

        2、 compute / computeIfAbsent / computeIfPresent 方法演示

/**
 * Description: compute / computeIfAbsent / computeIfPresent
 * <br> 1、compute : 输入原有key,value 作为参数,可通过逻辑处理,决定返回的value
 * <br> 2、computeIfAbsent : key对应的value,为空,则添加(覆盖); 不为空,则不处理
 * <br> 3、computeIfPresent : key对应的value,不为空,则添加(覆盖); 为空,则不处理
 * @return void
 * @version v1.0
 * @author wu
 * @date 2023/10/17 10:29
 */
@Test
public void computeAndcomputeIfAbsentTest() throws Exception{
    final HashMap<Object, Object> map = Maps.newHashMap();
    map.put("name","小明");

    System.out.println("compute 存在的 :" + map.compute("name",(k,v)->{
        System.out.println("compute -> key ="+k + " ; value="+v);
        return "小红";
    }));
    System.out.println("compute 输出结果 key=name :" + map.get("name"));
    System.out.println();
    System.out.println("compute 不存在的 :" + map.compute("hh",(k,v)->{
        System.out.println("compute -> key ="+k + " ; value="+v);
        return "小红hh";
    }));
    System.out.println("compute 输出结果 key=hh :" + map.get("hh"));

    System.out.println();
    System.out.println("computeIfAbsent 存在的 :" + map.computeIfAbsent("name",k->{
        System.out.println("computeIfAbsent -> key ="+k );
        return "雷丘";
    }));
    System.out.println("computeIfAbsent 输出结果 key=name :" + map.get("name"));

    System.out.println("computeIfAbsent 不存在的 :" + map.computeIfAbsent("qq",k->{
        System.out.println("computeIfAbsent -> key ="+k );
        return "雷丘";
    }));
    System.out.println("computeIfAbsent 输出结果 key=qq :" + map.get("qq"));

    System.out.println();
    System.out.println("computeIfPresent 存在的 :" + map.computeIfPresent("name",(k,v)->{
        System.out.println("computeIfPresent -> key ="+k + "; value ="+v );
        return "杰尼龟";
    }));
    System.out.println("computeIfPresent 输出结果 key=name :" + map.get("name"));

    System.out.println("computeIfPresent 不存在的 :" + map.computeIfPresent("tt",(k,v)->{
        System.out.println("computeIfPresent -> key ="+k + "; value ="+v );
        return "杰尼龟";
    }));
    System.out.println("computeIfPresent 输出结果 key=tt :" + map.get("tt"));
}

        2.1、 compute / computeIfAbsent / computeIfPresent 方法 输出结果

compute -> key =name ; value=小明
compute 存在的 :小红
compute 输出结果 key=name :小红

compute -> key =hh ; value=null
compute 不存在的 :小红hh
compute 输出结果 key=hh :小红hh

computeIfAbsent 存在的 :小红
computeIfAbsent 输出结果 key=name :小红
computeIfAbsent -> key =qq
computeIfAbsent 不存在的 :雷丘
computeIfAbsent 输出结果 key=qq :雷丘

computeIfPresent -> key =name; value =小红
computeIfPresent 存在的 :杰尼龟
computeIfPresent 输出结果 key=name :杰尼龟
computeIfPresent 不存在的 :null
computeIfPresent 输出结果 key=tt :null

        3、 put 和 putIfAbsent 方法演示

@Test
public void putAndPutIfAbsentTest() throws Exception {
    final HashMap<Object, Object> map = Maps.newHashMap();
    map.put("name", "小明");
    System.out.println("put 存在的: " + map.put("name","雷丘"));
    System.out.println("put 不存在的: " + map.put("hh","小红"));
    System.out.println("put 方法后,map集合: " + map);

    System.out.println();
    System.out.println("putIfAbsent 存在的: " + map.putIfAbsent("name","安琪拉"));
    System.out.println("putIfAbsent 不存在的: " + map.putIfAbsent("qq","坤哥"));
    System.out.println("putIfAbsent 方法后,map集合: " + map);
}

        3.1、put 和 putIfAbsent 方法 输出结果

put 存在的: 小明
put 不存在的: null
put 方法后,map集合: {hh=小红, name=雷丘}

putIfAbsent 存在的: 雷丘
putIfAbsent 不存在的: null
putIfAbsent 方法后,map集合: {hh=小红, qq=坤哥, name=雷丘}

三、总结

        1、get 和 getOrDefault 方法区别:

        当map中key不存在是,get方法返回null ; getOrDefault方法,返回的是 default默认值 

        2、compute / computeIfAbsent / computeIfPresent 方法区别:

    • compute : 输入原有key,value 作为参数,可通过逻辑处理,决定返回的value
    • computeIfAbsent : key对应的value,为空,则添加(覆盖); 不为空,则不处理 【不存在,添加】
    • computeIfPresent : key对应的value,不为空,则添加(覆盖); 为空,则不处理。【存在,覆盖】
    • computeIfAbsent 和 computeIfPresent 刚好相反

        2.1、compute 方法应用: key转换为value

@Test
public void computeTest() throws Exception {
    final HashMap<Object, Object> map = Maps.newHashMap();
    map.put("name", "小明");

    System.out.println(map.get("name"));
    System.out.println(map.compute("name",(k,v)->k));
    System.out.println(map.get("name"));
}

        3、put 和 putIfAbsent 方法区别:

    • put : key存在,覆盖value值;返回 之前的value
    • put : key不存在,添加value值;返回 null
    • putIfAbsent : key存在,不覆盖value值;返回 存在的value
    • putIfAbsent : key不存在,添加value值;返回 null
    • put 和 putIfAbsent 区别:key存在,put方法会覆盖;putIfAbsent 不覆盖。【不存在,添加】

        4、computeIfAbsent 和 putIfAbsent 方法:

        我们可以看到 computeIfAbsent 和 putIfAbsent 方法的作用都是,key不存在时,则添加;key存在时,则不处理,那么 这2个方法的作用是一样的吗? 请看下面代码:

@Test
public void putIfAbsentAndComputeIfAbsentTest() throws Exception{
    final HashMap<Object, Object> map = Maps.newHashMap();
    map.put("name", "小明");
    System.out.println("computeIfAbsent key存在:  " + map.computeIfAbsent("name",(k)->"小红"));
    System.out.println("computeIfAbsent key存在操作后输出 :" + map.get("name"));

    System.out.println();
    System.out.println("putIfAbsent key存在:  " + map.putIfAbsent("name","雷丘"));
    System.out.println("putIfAbsent key存在操作后输出 :" + map.get("name"));

    System.out.println();
    System.out.println("computeIfAbsent key不存在:  " + map.computeIfAbsent("age",(k)->"18"));
    System.out.println("computeIfAbsent key不存在操作后输出 :" + map.get("age"));

    System.out.println();
    System.out.println("putIfAbsent key不存在:  " + map.putIfAbsent("addr","北京市"));
    System.out.println("putIfAbsent key不存在操作后输出 :" + map.get("addr"));
}

        4.1、输出结果

computeIfAbsent key存在:  小明
computeIfAbsent key存在操作后输出 :小明

putIfAbsent key存在:  小明
putIfAbsent key存在操作后输出 :小明

computeIfAbsent key不存在:  18
computeIfAbsent key不存在操作后输出 :18

putIfAbsent key不存在:  null
putIfAbsent key不存在操作后输出 :北京市

        4.2、computeIfAbsent 和 putIfAbsent 方法区别

  • 相同点: key 存在时,不能添加成功 ; key 不存在时,才能添加成功
  • 不同点: key不存在时,putIfAbsent 添加成功后返回 null ; computeIfAbsent 添加成功后,返回添加的value
  • computeIfAbsent 方法: 返回的是最终添加的value