聊一聊Java8中map的putIfAbsent,computeIfAbsent 方法

1.

//具体用法
// putIfAbsent 和 computeIfAbsent 都是针对map里没有key对应的元素进行操作,
// putIfAbsent(Object key ,Object value ) ;computeIfAbsent(Object key , Function) Function是可以code的
// key有对应的value值不进行操作,并返回这个旧值
// key没有有对应的value值 进行操作 操作 :putIfAbsent 放入newValue ;computeIfAbsent 放入newValue

先上才艺:

/java 8 map (并发map和普通hashMap 都有) 的 常用方法
        //说明:假设有这么一个容器 Map<String, List> concurrentHashMap = new ConcurrentHashMap<>()
        //有一些学生,年龄介于20到22之间,要根据年龄对这些学生分组
        // java
        List<Student> studentList = Arrays.asList(
                new Student("xiaoming20","20"),new Student("lihua20","20"),new Student("wumei20","20"),
                new Student("xiaoming21","21"),new Student("lihua21","21"),new Student("wumei21","21"),
                new Student("xiaoming22","22"),new Student("lihua22","22"),new Student("wumei22","22")
        );
        //法① list.stream().collect(Collectors.groupingBy(User::getType));
        Map<String,List<Student>> studentGroupMap1 = studentList.stream().collect(Collectors.groupingBy(Student::getAge));
        //java 8 之前
        Map<String, List> before8Map = new ConcurrentHashMap<String, List>();
        for (Student student : studentList) {
           if(CollectionUtils.isEmpty(before8Map.get(student.getAge()))){
              List stuList =  new ArrayList<Student>();
               stuList.add(student);
               before8Map.put(student.getAge(),stuList);
           }else{
               List stuList =  before8Map.get(student.getAge());
               stuList.add(student);
           };
        }
        //java 8 之后,除了法① ,还可以用 putIfAbsent key没有value就创建,有的话直接拿出来,不用自己判断
        Map<String, List> after8Map = new ConcurrentHashMap<String, List>();
        studentList.stream().forEach(student ->{
          List<Student> groupList = after8Map.computeIfAbsent(student.getAge() , value->{
               return new ArrayList<Student>();
           });
          //对拿出来的集合操作,不进行这一步,after8Map 拿出来的三个集合都是空的
            groupList.add(student);
       });
        System.out.println(studentGroupMap1.toString());
        System.out.println(before8Map.toString());
        System.out.println(after8Map.toString());

       
        Map<String, List> concurrentHashMap = new ConcurrentHashMap<>();
        //判断容器里 list 的value ,value 为null 就创建一个,否则拿出来
        List list = concurrentHashMap.computeIfAbsent("list", k -> {
            return new ArrayList<String>();
        });
        list.add("hello");
        // list.add("hello") 是在数组里的 List集合进行操作,根据list再次找到这个list ,发现list1 也是有值的
        List list1 = concurrentHashMap.get("list");
        //在map中已经存在的key的value进行操作。只对已经存在key的进行操作,其他不操作,下面的操作没用
        // list2 为 null
        List list2 = concurrentHashMap.computeIfPresent("list2" ,(k,v) -> {
            return new ArrayList(10);
        });
        // list3 有个元素:hello
        List list3 = concurrentHashMap.computeIfAbsent("list", k -> {
            return new ArrayList<String>();
        });
        list3.add("word");
        //"list" 有对应的value,则返回旧的value,不继续执行  new ArrayList<String>() 这个操作
        List list4 = concurrentHashMap.computeIfAbsent("list", k -> {
            return new ArrayList<String>();
        });
        //list4 有两个元素
        //System.out.println(list4.size());
        //
        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
        map.put("1","1");
        String result = map.putIfAbsent("1","2");
        String result2 = map.get("1");
        map.putIfAbsent("2","2");
        String result3 = map.get("2");

打印结果如下:

{22=[Student{name='xiaoming22', age='22'}, Student{name='lihua22', age='22'}, Student{name='wumei22', age='22'}], 20=[Student{name='xiaoming20', age='20'}, Student{name='lihua20', age='20'}, Student{name='wumei20', age='20'}], 21=[Student{name='xiaoming21', age='21'}, Student{name='lihua21', age='21'}, Student{name='wumei21', age='21'}]}
{22=[Student{name='xiaoming22', age='22'}, Student{name='lihua22', age='22'}, Student{name='wumei22', age='22'}], 20=[Student{name='xiaoming20', age='20'}, Student{name='lihua20', age='20'}, Student{name='wumei20', age='20'}], 21=[Student{name='xiaoming21', age='21'}, Student{name='lihua21', age='21'}, Student{name='wumei21', age='21'}]}
{22=[Student{name='xiaoming22', age='22'}, Student{name='lihua22', age='22'}, Student{name='wumei22', age='22'}], 20=[Student{name='xiaoming20', age='20'}, Student{name='lihua20', age='20'}, Student{name='wumei20', age='20'}], 21=[Student{name='xiaoming21', age='21'}, Student{name='lihua21', age='21'}, Student{name='wumei21', age='21'}]}

 

 

所以函数式表达式的用处:

作为方法A中形参参数:将函数式接口作为形参;实际上调用方法A的时候用lamda表达式的方法体 去实现函数式接口 里的抽象方法(ps:貌似就是 一个函数式接口 有很多实现)

例子:

自定义一个函数式接口:

@FunctionalInterface
public interface MyFunctionInterface<Integer> {
    java.lang.Integer apply(java.lang.Integer t);
}

 

该接口定义一个抽象方法,没有方法体(方法体是在 作为实参的时候 lamda表达式 的 方法体中实现的)

public int getAndIncrement(MyFunctionInterface<Integer> functionInterface ,int a ) {
        return functionInterface.apply(a);
    }

 

函数接口对  a 进行操作

 // 调用 getAndIncrement方法
        System.out.println("---------");
        MyTest myTest = new MyTest();
        int b = myTest.getAndIncrement(e ->{
            //10
            System.out.println(e);
            return e+100;
        },10);
        //110
        System.out.println(b);

 

例子2:

定义一个函数式接口,这个函数接口的作用是对两个形参求和

@FunctionalInterface
public interface SumFunctionInterface {
    java.lang.Integer getSum(java.lang.Integer t1,java.lang.Integer t2);
}

 

public int getSum(int a , int b,SumFunctionInterface functionInterface ) {
        return functionInterface.getSum(a,b);
    }
// 调用 getSum 方法
        System.out.println("---------");
        MyTest myTest = new MyTest();
        int c = myTest.getSum(100,1000,(a,b) ->{
            //100
            System.out.println(a);
            //1000
            System.out.println(b);
            return a+b;
        });
        //1100
        System.out.println(c);

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值