【java代码之美】---Java8 Map中的computeIfAbsent方法

Map中的computeIfAbsent方法

Map接口的实现类如HashMap,ConcurrentHashMap,HashTable等继承了此方法,通过此方法可以在特定需求下,让你的代码更加简洁。

一、案例说明

1、概述

在JAVA8的Map接口中,增加了一个方法computeIfAbsent,此方法签名如下:

public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) 

此方法首先判断缓存MAP中是否存在指定key的值,如果不存在,会自动调用mappingFunction(key)计算key的value,然后将key = value放入到缓存Map。

如果mappingFunction(key)返回的值为null或抛出异常,则不会有记录存入map

2、代码说明

public class Java8Map {

    public Map<String,Object>  map1= Maps.newHashMap();

    public Map<String,AtomicInteger>  map2=Maps.newHashMap();

    public Map<String,List<String>>  map3=Maps.newHashMap();

    List<String> list = Lists.newArrayList("1", "2", "3","2","3","2");

    /**
     * 1、业务逻辑:如果key的value值为null,则在map中放入该key和设置相应的value值
     */
    @Test
    public  void  map1(){

        // java8之前,从map中根据key获取value操作可能会有下面的操作
        Object key = map1.get("key");
        if (key == null) {
            key = new Object();
            map1.put("key", key);
        }else{
            //如果key对应的value值存在,进行相应的操作
        }

        // java8之后,上面的操作可以简化为一行,若key对应的value为空,会将第二个参数的返回值存入并返回
        Object key2 = map1.computeIfAbsent("key1", k -> new Object());
        System.out.println(map1);
        //输出:{[email protected], [email protected]}
    }

    /**
     * 2、统计List出现相同字符串的个数
     */
    @Test
    public void  map2() {

        //这里虽然只有一行代码但信息量很大,首先它采用量java的新特性lambda表达式来遍历list集合
        //这里表示如果map中的key对应的value值为null,则该key对应value值为new AtomicInteger()并执行自增加1,如果key已经存在,则直接value值自增1
        list.forEach( str-> map2.computeIfAbsent(str, k -> new AtomicInteger()).incrementAndGet());
        System.out.println(map2);
        //输出:{1=1, 2=3, 3=2}

    }

    /**
     * 3、如果key对应的value不存在,则创建新List并放入数据,存在则往直接往list放入数据
     */
    @Test
    public void  map3() {

        map3.computeIfAbsent("zhangsan", k -> genValue(k)).add("apple");
        map3.computeIfAbsent("zhangsan", k -> genValue(k)).add("orange");
        map3.computeIfAbsent("zhangsan", k -> genValue(k)).add("pear");
        map3.computeIfAbsent("zhangsan", k -> genValue(k)).add("banana");
        map3.computeIfAbsent("lisi", k -> genValue(k)).add("water");

        System.out.println(map3);
        //输出结果:{lisi=[water], zhangsan=[apple, orange, pear, banana]}

    }

    static List<String> genValue(String str) {
        return new ArrayList<String>();
    }

}

总结:computeIfAbsent在一些实际开发场景中,能让我们代码看去更加简洁,代码质量看去也更高。

有关下面这步确实很优秀。它知道我map里的value是什么类型从而可以调相应的方法,比如这里是AtomicInteger对象,那就可以调incrementAndGet()方法

如果你放的是集合就可以调集合相关方法。

list.forEach( str-> map2.computeIfAbsent(str, k -> new AtomicInteger()).incrementAndGet());

我只是偶尔安静下来,对过去的种种思忖一番。那些曾经的旧时光里即便有过天真愚钝,也不值得谴责。毕竟,往后的日子,还很长。不断鼓励自己,

天一亮,又是崭新的起点,又是未知的征程(上校1)

原文地址:https://www.cnblogs.com/qdhxhz/p/9478942.html

时间: 2024-11-05 00:43:00

【java代码之美】---Java8 Map中的computeIfAbsent方法的相关文章

java代码之美(14)---Java8 函数式接口

Java8 函数式接口 之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加简洁. 一.概念 1.什么是函数式接口 概念 所谓的函数式接口, 当然首先是一个接口, 然后就是在这个接口里面 只能有一个抽象方法. 有关函数式接口,有个专门的注解叫:@FunctionalInterface.该注解主要特点有: 1.该注解只能标记在"有且仅有一个抽象方法"的接口上,表示函

Java代码实现向Oracle数据库中导入已备份的数据库文件

今天将很早就实现的一个Oracle数据库备份功能粘贴出来,这个功能是在大学做阶段设计时写的: import java.io.IOException; /** * Java代码实现向Oracle数据库中导入已备份的数据库文件 * * @author:Gaohuanjie */ public class OracleImportDatabase { /** * 向Oracle数据库中导入已备份的数据库文件 * * @author:Gaohuanjie * @param userName 进入数据库所

Java线程状态及Thread类中的主要方法

要想实现多线程,就必须在主线程中创建新的线程对象. 任何线程一般具有5种状态,即创建,就绪,运行,阻塞,终止. 创建状态: 在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此时,他已经有了相应的内存空间和其他资源,但还处于不可运行状态. 就绪状态: 新建线程对象后,调用该线程的start()方法可以启动线程.当线程启动时,线程进入就绪状态.此时,线程将进入线程队列排队,等待CPU服务,这表明它已经具备了运行条件.-------(运行start()方法只是进入就绪状态,并没有开

ubuntu中出现:程序 &#39;java&#39; 已包含在下列软件包中的解决方法

已经安装sun java 在终端中输入java,出现以下提示: 程序 'java' 已包含在下列软件包中: * default-jre * gcj-4.8-jre-headless * gcj-4.9-jre-headless * openjdk-7-jre-headless * openjdk-6-jre-headless * openjdk-8-jre-headless请尝试:apt-get install <选定的软件包> 在终端中输入javac 出现以下提示:程序 'javac' 已包

java代码之美(16) ---Java8 Optional

摘自:https://www.cnblogs.com/qdhxhz/p/12056745.html Java8 Optional 一句话介绍Optional类:使用JDK8的Optional类来防止NullPointerException(空指针异常)问题. 一.前言 在我们开放过程中,碰到的异常中NullPointerException必然是排行第一的.所以在平时编码中,我们会时时的判断null. public void saveCity(City city) { if (city != nu

【转】【java源码分析】Map中的hash算法分析

全网把Map中的hash()分析的最透彻的文章,别无二家. 2018年05月09日 09:08:08 阅读数:957 你知道HashMap中hash方法的具体实现吗?你知道HashTable.ConcurrentHashMap中hash方法的实现以及原因吗?你知道为什么要这么实现吗?你知道为什么JDK 7和JDK 8中hash方法实现的不同以及区别吗?如果你不能很好的回答这些问题,那么你需要好好看看这篇文章.文中涉及到大量代码和计算机底层原理知识.绝对的干货满满.整个互联网,把hash()分析的

Java集合篇六:Map中key值不可重复的测试

package com.test.collection; import java.util.HashMap; import java.util.Map; //Map中key值不可重复的测试 public class TestEquals { public static void main(String[] args) { String s1=new String("abc"); String s2=new String("abc"); Map map=new Has

学 Java的第30天 Map中嵌套Map

package cn.aaa; import java.util.Iterator;import java.util.Map.Entry;import java.util.HashMap;import java.util.Set; //Map中嵌套存储Map//aaa//java班//  001 周一//  002 周二//hoodp班//  001 周三//  002 周四////java班 :存学号和名字//hoodp班:存学号和名字//aaa:存的是班级//  java班<学号,姓名>/

Java8接口中的默认方法

Java8新增特性,可以为接口中添加默认方法,实现这个接口的所有类都会继承这个方法,这样看起来,接口和类的界限就有点不明显了,同时也会带来多继承,菱形问题.这样设计的初衷是什么? 重所周知,java8开始支持lambda表达式,可以把函数当做参数传递,最明显的lambda表达式应用场景莫过于对collection的每一个元素应用lambda.如果想为Collection实现lambda表达式:list.forEach(…); // 这就是lambda代码 首先想到的是为Collection的父接