资讯专栏INFORMATION COLUMN

Map 的 getOrDefault(),putIfAbsent() 和 computeIfAbse

李义 / 1664人阅读

摘要:如果不小心把它们搞混用错了,可能会带来大问题。这个方法会检查中的,如果发现不存在或者对应的值是,则调用来产生一个值,然后将其放入,最后返回这个值否则的话返回已经存在的值。要注意,这个默认值不会放入。

假设我们定义下面一个 Map:

Map> map = new HashMap<>();

如果我们要放一个元素进去,很多人会这么写:

List list = map.get("list1");
if (list == null) {
  list = new ArrayList<>();
  map.put("list1", list);
}
list.add("A");

实际上从 Java 8 开始,Map 提供了 computeIfAbsent() 方法,我们可以写成一行即可:

map.computeIfAbsent("list1", k -> new ArrayList<>()).add("A");

其中变量 k 是 Map 的 key。

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

▶ V computeIfAbsent(K, Function)

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

▶ V getOrDefault(Object, V)

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

Map> map = new HashMap<>();
map.getOrDefault("list1", new ArrayList<>()).add("A");

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

▶ V putIfAbsent(K, V)

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73420.html

相关文章

  • Java8(3):Java8 中 Map 接口新方法

    摘要:我们提一个需求给定一个,统计每个元素出现的所有位置。而且因为方法会返回新的此时便是与相关联的所以我们可以直接调用其方法。在本文类似需求的情况下,就适用性和简洁性而言,要优于。 我们提一个需求:给定一个 List,统计每个元素出现的所有位置。 比如,给定 list:[a, b, b, c, c, c, d, d, d, f, f, g] ,那么应该返回:a : [0]b : [1, 2]...

    Youngs 评论0 收藏0
  • Java 8 并发教程:原子变量 ConcurrentMa

    摘要:并发教程原子变量和原文译者飞龙协议欢迎阅读我的多线程编程系列教程的第三部分。如果你能够在多线程中同时且安全地执行某个操作,而不需要关键字或上一章中的锁,那么这个操作就是原子的。当多线程的更新比读取更频繁时,这个类通常比原子数值类性能更好。 Java 8 并发教程:原子变量和 ConcurrentMap 原文:Java 8 Concurrency Tutorial: Synchroni...

    bitkylin 评论0 收藏0
  • 聊聊redissonRMapcomputeIfAbsent操作

    序 本文主要研究一下redisson的RMap的computeIfAbsent操作 实例 @Test public void testRMapComputeIfAbsent(){ Config config = new Config(); config.useSingleServer() .setAddress(red...

    Cristalven 评论0 收藏0
  • Java实战之Java8指南

    摘要:首先我们定义一个有两个不同控制器的然后,我们创建一个特定的工厂接口来创建新的对象不需要手动的去继承实现该工厂接口,我们只需要将控制器的引用传递给该接口对象就好了的控制器会自动选择合适的构造器方法。这种指向时间轴的对象即是类。 本文为翻译文章,原文地址 这里 欢迎来到本人对于Java 8的系列介绍教程,本教程会引导你一步步领略最新的语法特性。通过一些简单的代码示例你即可以学到默认的接口方...

    nemo 评论0 收藏0
  • Java多线程进阶(二三)—— J.U.C之collections框架:ConcurrentHash

    摘要:需要注意的是所链接的是一颗红黑树,红黑树的结点用表示,所以中实际上一共有五种不同类型的结点。时不再延续,转而直接对每个桶加锁,并用红黑树链接冲突结点。 showImg(https://segmentfault.com/img/bVbfTCY?w=1920&h=1080); 本文首发于一世流云专栏:https://segmentfault.com/blog... 一、Concurren...

    Jason_Geng 评论0 收藏0

发表评论

0条评论

李义

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<