Java8中Map新增的getOrDefault(),putIfAbsent()和computeIfAbsent()三个方法

JAVA herman 193浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:codedq,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:codedq,之前的微信号好友位已满,备注:返现
饿了么大量招人,我内推!Java 方向!薪资不设上限,工作年龄不限!工作地点限魔都,可电话面试!简历,发我微信:codedq
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

先说一下,在 Java8 中 computeIfAbsent 方法有一个严重的死循环 bug,Java9 中已经修复了,这个后面我们单独列举文章来详细说它是如何产生以及如何被修复的。

实际上从 Java 8 开始,Map 提供了 computeIfAbsent() 方法。为了讲明白它的用法,我们先来看一个代码场景。

Map<String, List<String>> map = new HashMap<>();
List<String> list = map.get("codedq");
if (list == null) {
  list = new ArrayList<>();
  map.put("list1", list);
}
list.add("业余草");

这段代码看起来很多人都写过,所以 Java8 推出了 computeIfAbsent 方法,用来简化整个代码块,使其只需要一行代码就可以搞定。

map.computeIfAbsent("codedq", k -> new ArrayList<>()).add("业余草");

其中变量 k 是 Map 的 key。

是不是很方便?但是除此之外,Map 还有两个方法:getOrDefault() 和 putIfAbsent(),这三个方法都接受 Key 和一个“默认值”作为参数,且返回一个 Value。如果不小心把它们搞混用错了,可能会带来大问题。下面分别介绍下。

computeIfAbsent

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

这个方法有两个参数,Key 和一个根据 Key 来产生 Value 的 Function;然后返回一个 Value。

这个方法会检查 Map 中的 Key,如果发现 Key 不存在或者对应的值是 null,则调用 Function 来产生一个值,然后将其放入 Map,最后返回这个值;否则的话返回 Map 已经存在的值。

补充:在 ConcurrentHashMap 中,这个方法保证线程安全,且多线程并发执行的情况下,Function 参数只会被调用一次。所以这个方法完全可以代替 DCL(Double Check Lock)写法。

getOrDefault

V getOrDefault(Object, V)

这个方法同样检查 Map 中的 Key,如果发现 Key 不存在或者对应的值是 null,则返回第二个参数即默认值。要注意,这个默认值不会放入 Map。所以如果你这样写:

Map<String, List<String>> map = new HashMap<>();
map.getOrDefault("codedq", new ArrayList<>()).add("业余草");

执行完之后 map 仍然是空的!

putIfAbsent

V putIfAbsent(K, V)

这个方法的逻辑完全不同,注意它不是一个 get() 方法,而是 put() 方法的变种!这个方法的逻辑是,如果 Key 不存在或者对应的值是 null,则将 Value 设置进去,然后返回 null;否则只返回 Map 当中对应的值,而不做其他操作。

所以显而易见,在最开始的例子中,如果将 computeIfAbsent() 替换成其他两个方法都是错的。

目前根据我在 codereview 以及面试老程序员的过程中,发现很多人不知道 Map 中新增了方法,也从来没用过。还是建议大家在空闲时间多关注一些 Java 不同版本的新特性,不然在编程的道路上,你会吃亏的!

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号1:xmtxtt(5000人已满),微信号2:xttblog(5000人已满),微信号3:codedq(超3800)。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » Java8中Map新增的getOrDefault(),putIfAbsent()和computeIfAbsent()三个方法