Java中Map接口的默认方法computerIfAbsent、computeIfPresent、getOrDefault、merge、putIfAbsent、replaceAll以及常用示例

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 Java中Map接口的默认方法computerIfAbsent、computeIfPresent、getOrDefault、merge、putIfAbsent、replaceAll以及常用示例,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

场景

Java8新特性-Stream对集合进行操作的常用API:

Java8新特性-Stream对集合进行操作的常用API_霸道流氓气质的博客-CSDN博客_streamapi对集合修改

如果 Map 中包含元素,用户希望替换元素;如果 Map 中没有元素,用户希望添加元素;

此外,用户还希望执行其他相关操作。

Java 8 为 Map 接口引入了不少新方法,某些方法能为开发提供极大的便利。

注:

博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主

实现

1、computerIfAbsent

如果键存在,返回对应的值,否则通过提供的函数计算新的值并保存

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

以经典的斐波那契数递归计算为例进行讨论。

    //效率极低的算法
    int fib(int n){
        if (n<2) {
            return n;
        } else {
            return fib(n-1) + fib(n-2);
        }
    }

代码的问题在于需要进行大量重复的计算,(如 fib(5) =fib(4) + fib(3) = fib(3) + fib(2) + fib(2)+fib(1) = …),

导致程序效率极低。可以利用缓存解决这个问题,函数式编程将这种技术称为记忆化。

    BigInteger fibCache(long i){
        if(i == 0) return  BigInteger.ZERO;
        if(i == 1) return  BigInteger.ONE;
        return cache.computeIfAbsent(i,n ->fibCache(n-2).add(fibCache(n-1)));
    }

computeIfAbsent 方法在缓存中搜索给定的数字,存在则返回对应的值,

否则使用提供的 Function 计算新的值,将其保存在缓存中并返回。

2、computeIfPresent

仅当与某个值关联的键在 Map 中存在时,computeIfPresent才会更新该值

V computeIfPresent(K key,    BiFunction<? super K, ? super V, ? extends V>remappingFunction)

统计一段文本中特定单次的出现次数

    public Map<String,Integer> countWords(String passage,String... strings){
        Map<String,Integer> wordCounts = new HashMap<>();
        //将特定单词置于映射中,并将计数器设置为 0
        Arrays.stream(strings).forEach(s->wordCounts.put(s,0));
        //读取文本,仅更新特定单词的出现次数
        Arrays.stream(passage.split(" ")).forEach(word -> wordCounts.computeIfPresent(word,(key,value)->value+1));
        return wordCounts;
    }

方法调用

        String passage = "gong zhonghao badao de cheng xv yuan, badao de cheng xv yuan, badao de cheng xv yuan";
        Map<String, Integer> stringIntegerMap = countWords(passage, "badao", "de");
        System.out.println(stringIntegerMap);//{badao=3, de= 3}

3、replace

将现有键的值替换为新的值 前提是键已经存在。如果键不存在,replace 不会执行任何操作

        Map<String,Integer> map = new HashMap<>();
        map.put("a",1);
        System.out.println(map);//{a=1}
        map.replace("b",2);
        System.out.println(map);//{a=1}
        map.replace("a",3);
        System.out.println(map);//{a= 3}

4、getOrDefault

如果键在 Map 中存在,返回对应的值,否则返回默认值 但不会将这个键添加到映射中。

        System.out.println(map);//{a=3}
        System.out.println(map.getOrDefault("c",0));//0
        System.out.println(map);//{a= 3}

5、merge

如果键在 Map 中不存在,返回提供的值,否则计算新的值

        System.out.println(map);//{a=3}
        //a存在,对a的值进行累加
        map.merge("a",1,(old,new_)->old+new_);
        System.out.println(map);//{a=4}
        //b不存在,返回默认值1,并put
        map.merge("b",1,(old,new_)->old+new_);
        System.out.println(map);//{a=4, b=1}
        //b已经存在,按照function 此时为乘法
        map.merge("b",2,(old,new_)->old*new_);
        System.out.println(map);//{a=4, b= 2}

给定一段文本,统计所有单次的出现次数

    public Map<String,Integer> fullWordCounts(String passage){
        Map<String,Integer> wordCounts = new HashMap<>();
        //将逗号替换成空格
        String testString = passage.toLowerCase().replaceAll("\\W"," ");
        //split("\\s+")  \\s表示空格 +表示一个或多个
        Arrays.stream(testString.split("\\s+")).forEach(word ->wordCounts.merge(word,1,Integer::sum));
        return wordCounts;
    }

首先将逗号替换成空格,然后按照一个或者多个空格进行spilit。

方法调用:

        String passage1 = "gong zhonghao badao de cheng xv yuan, badao de cheng xv yuan, badao de cheng xv yuan";
        Map<String, Integer> stringIntegerMap1 = fullWordCounts(passage1);
        System.out.println(stringIntegerMap1);//{yuan=3, de=3, badao=3, gong=1, zhonghao=1, cheng=3, xv=3}

 6、Compute

根据现有的键和值计算新的值

        System.out.println(map);//{a=4, b=2}
        map.compute("a",(key,value)->value + 2);
        System.out.println(map);//{a=6, b=2}

7、putIfAbsent

如果键在 Map 中不存在,将其关联到给定的值

        System.out.println(map);//{a=6, b=2}
        map.putIfAbsent("b",3);
        map.putIfAbsent("c",8);
        System.out.println(map);//{a=6, b=2, c=8}

8、replaceAll

将 Map 中每个条目的值替换为对当前条目调用给定函数后的结果

        System.out.println(map);//{a=6, b=2, c=8}
        map.replaceAll((key,value)-> value +1);
        System.out.println(map);//{a=7, b=3, c=9}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/135831.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!