首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

有没有更好的方法来确定computeIfAbsent是否返回了一个新值?

在Java中,我们可以使用computeIfAbsent方法来在Map中根据指定的键获取对应的值,如果该键不存在,则会根据提供的函数生成一个新值并将其放入Map中。但是,我们如何确定computeIfAbsent是否返回了一个新值呢?

一种方法是使用一个辅助变量来判断是否返回了新值。我们可以在computeIfAbsent方法调用之前先获取Map中对应键的值,并将其保存在一个变量中。然后,在computeIfAbsent方法调用之后,再次获取该键的值,并与之前保存的值进行比较。如果两个值相等,则说明computeIfAbsent没有生成新值;如果两个值不相等,则说明computeIfAbsent生成了一个新值。

另一种方法是使用原子变量来判断是否返回了新值。我们可以使用AtomicReference类来保存Map中对应键的值。在computeIfAbsent方法调用之前,我们可以使用get方法获取并保存原始值。然后,在computeIfAbsent方法调用之后,我们可以使用compareAndSet方法将原始值与新值进行比较。如果compareAndSet返回true,则说明computeIfAbsent生成了一个新值;如果返回false,则说明computeIfAbsent没有生成新值。

这些方法可以帮助我们确定computeIfAbsent是否返回了一个新值,从而更好地控制程序的逻辑和流程。

参考链接:

  • computeIfAbsent方法文档:https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Java 基础篇】深入理解Java HashMap:使用注意事项和性能优化

判断是否包含键或值 您可以使用containsKey方法来检查HashMap是否包含特定键: boolean containsKey = hashMap.containsKey("apple"); //...); 这将创建一个与hashMap相同的新HashMap。...您可以使用computeIfAbsent方法来实现这一点: hashMap.computeIfAbsent("orange", key -> { // 在键"orange"不存在时,执行此操作并返回默认值...这些是一些更多操作HashMap的方法和概念,它们可以帮助您更好地使用和管理HashMap集合。根据您的需求,选择适当的方法来操作和处理HashMap中的数据。...如果尝试将相同的键插入HashMap中,新值将覆盖旧值。 值可以重复: HashMap中的值可以重复。多个键可以映射到相同的值。

1.8K40
  • Lambda表达式你会用吗?

    函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。...可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。 // 1. 不需要参数,返回值为 5 () -> 5 // 2....批量迭代可以降低迭代的开销。 Spliterator是可拆分的,一个Spliterator可以通过调用Spliterator trySplit()方法来尝试分成两个。...一个是this,另一个是新返回的那个,这两个迭代器代表的元素没有重叠。 可通过(多次)调用Spliterator.trySplit()方法来分解负载,以便多线程处理。...Function是一个函数接口,里面有一个待实现方法R apply(T t). computeIfAbsent()常用来对Map的某个key值建立初始化映射.比如我们要实现一个多值映射,Map的定义可能是

    90730

    Redis如何删除数量过万以上Key而不影响业务

    那大家会问,有没有更好的方法来解决这个问题?答案是当然用,请接着看下文。...命令是一个基于游标的迭代器,SCAN命令每次被调用之后,都会向用户返回一个新的游标,用户在下次迭代时需要使用这个新游标作为SCAN命令的游标参数,以此来延续之前的迭代过程,直到服务器向用户返回值为0的游标时...上面这个例子的意思是扫描所有前缀为testkey-的key。第一次迭代使用0作为游标,表示开始一次新的迭代,同时使用了MATCH匹配前缀为testkey-的key,返回了游标值34以及遍历到的数据。...当SCAN命令的游标参数被设置为0时,服务器将开始一次新的迭代,而当redis服务器向用户返回值为0的游标时,表示迭代已结束,这是唯一迭代结束的判定方式,而不能通过返回结果集是否为空判断迭代结束。...遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的。 单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零。

    4.6K30

    「硬核JS」图解Promise迷惑行为|运行机制补充

    then方法的返回值来生成新 Promise 对象,这块逻辑复杂些,规范中可以抽离出一个方法来做这件事,我们来照做。.../** * 解析then返回值与新Promise对象 * @param {Object} 新的Promise对象,就是我们创建的promise2实例 * @param {*} x 上一个then的返回值...哦,原来 then 方法并不是在上一个 Promise 对象 resolve 后才执行,它在一开始就执行并返回了一个新的 Promise,在返回的新 Promise 中会根据上一个 Promise 的状态来做判断...,和直接 return 一个值一样,都会在上一个 Promise 状态为成功态时调用其返回时内部创建的新 Promise 的 resolve 方法并将值传出。...我们之前的手写实现,当使用 Promise 返回一个新的 Promise 时,内部会调用它的 then 方法从而产生一个新的微任务,其回调入队,后面微任务队列执行到这个回调时,拿到传入的值作处理后再 resolve

    2.2K30

    Java延迟加载的最佳实践应用示例!

    总体而言,使用Eager方式让编码本身更加简单,然而使用Lazy的方式通常而言,即意味着更好的效率。...                return heavyInstance;              }          }                  //第一次调用方法来会将heavy重定向到新的...在方法体中会首先判断当前的heavy是否是HeavyInstance的一个实例。如果不是,就会将heavy对象替换成HeavyFactory类型的实例。...int number) {         return number > 1 &&             // 依次从2到number的平方根判断number是否可以整除该值,即divisor             ...,则直接返回该值             return number + 1;         else // 否则继续从下一个数据的后面继续找到第一个素数返回,递归             return

    79120

    面霸篇:Java 核心集合容器全解(核心卷二)

    集合的特点 对象封装数据,多个对象需要用集合存储; 对象的个数可以确定使用数组更高效,不确定个数的情况下可以使用集合,因为集合是可变长度。 集合与数组的区别 数组是固定长度的;集合可变长度的。...在读操作时不加锁,跟 ArrayList 类似;在写操作时,复制出一个新的数组,在新数组上进行操作,操作完了,将底层数组指针指向新数组。 适合使用在读多写少的场景。...==指引用是否相同, equals() 指的是值是否相同。...用户自定义 Key 类最佳实践是使之为不可变的,这样 hashCode() 值可以被缓存起来,拥有更好的性能。...正确写法: //利用computeIfAbsent()方法来实例化LongAdder,然后利用LongAdder来进行线程安全计数 freqs.computeIfAbsent(key, k -> new

    37421

    Java 并发之线程池学习

    milliseconds,runnableTaskQueue, threadFactory,handler); 参数说明: corePoolSize 线程池中任务的基本个数 新提交一个任务时,若线程池中个数未达到基本个数...,则新建一个线程 到线程池中的线程数达到基本个数时,再提交任务,则看是否有空闲线程,有则只直接使用 若无空闲线程,则新几条的任务放入排队 maximumPoolSize 线程chi池中任务的做多个数...Future 对象,通过调用future.get() 可以获取线程的返回值,其中这个方程是线程阻塞的,直到返回了结果之后,才会继续执行下去 关闭线程 线程池的shutdown或shutdownNow...方法来关闭线程池 shutdown的原理是只是将线程池的状态设置成SHUTDOWN状态,然后中断所有没有正在执行任务的线程 shutdownNow的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt...方法来中断线程,所以无法响应中断的任务可能永远无法终止 调用了这两个关闭方法的其中一个,isShutdown方法就会返回true。

    623100

    不就是书上的 5.6 小节吗?

    看到这个问题的瞬间,不知道你的脑袋里面有没有电光火石般的想起缓存问题三连击:缓存雪崩、缓存击穿、缓存穿透。 毕竟应对缓存击穿的解决方案之一就是只需要一个请求线程去做构建缓存,其他的线程就轮询等着。...所以,我们接着就要关注一下 ConcurrentHashMap 的这个方法是怎么搞得了: 还是通过 synchronized 方法来保证了原子性,当操作的是同一个 key 的时候保证只有一个线程去执行...extends V> mappingFunction) computeIfAbsent,首先它也是一个线程安全的方法,这个方法会检查 Map 中的 Key,如果发现 Key 不存在或者对应的值是 null...,则调用 Function 来产生一个值,然后将其放入 Map,最后返回这个值;否则的话返回 Map 已经存在的值。...但是从程序实现的优雅角度来说,还是 putIfAbsent 方法更好。 坑怎么办? 前面不是说最终的方案有两个坑嘛: 一个是不支持缓存过期机制。 一个是不支持缓存淘汰机制。

    21110

    快来学这几个“新”方法

    图片getOrDefault这个方法名很直观,见名知意:尝试获取key对应的值,如果未获取到,就返回默认值。...看一个使用的例子,新写法会比老写法更加简洁:private static void testGetOrDefault() { Map map = new HashMap...我们要实现的逻辑是,遍历List中的每个元素,如果这个元素在Map中存在,Map中的值+1;如果不存在,则放入Map中,次数(值)为1。...putIfAbsent也是一个见名知意的方法:不存在key或者值为null时,才将键值对放入Map。跟put方法相比,这个方法不会直接覆盖已有的值,在不允许覆盖旧值的场景使用起来会比较简洁。...,让我想起一张远古的图不过在不同的场景使用不同的方法,尽量把代码写的简洁和优雅,才是一个程序猿不断追求的目标吧。

    7810

    别再这么写代码了,这几个方法不香吗?

    不过最近 Review 项目代码的时候发现,虽然很多项目工程已经使用了 JDK8,但是工程代码却很少使用到 JDK8 新特性、新方法。...所以针对这种情况,其实可以使用条件运算符,设置一个默认空值,从而避免后续处理发生空指针。...MapUtils.getString(pojo.getMap(),"支付", ""); 巧用 computeIfAbsent 日常开发中,我们会碰到这类场景,需要一个键需要映射到多个值,这个时候我们可以使用...而 computeIfAbsent将会返回 mappingFunction计算之后的值,像上面的场景直接返回就是 new ArrayList。 这一点需要注意一下,切勿用错方法,导致空指针。...最后针对上面这种一个键需要映射到多个值,其实还有一个更优秀的解决办法,使用 Google Guava 提供的新集合类型 Multiset,以此快速完成一个键需要映射到多个值的场景。

    85421

    ConcurrentHashMap里面也有死循环,作者留的“彩蛋”?

    接着调用 computeIfAbsent 方法,获取到 null 后调用 getValue 方法,将该方法的返回值和当前的 key 关联起来。 所以,第二次获取的时候拿到了 “why技术”。...但是目前而言,这种机制就算做出来,工作效率也是非常低下的,比如在当前的这个案例下。但是现在我们至少清楚的知道,是否要实现这种机制是不能确定的。...问题在于我们在进行 computeIfAbsent 的时候,里面还有一个 computeIfAbsent。...现在 “AaAa” 就等着这个 computeIfAbsent 操作的返回值,然后进行下一步操作,也就是进行标号为 ③ 的操作了。 接着 “BBBB” 就来了。 ?...接下来到标号为 ③ 的地方,里面有一个 MOVED,这个 MOVED 是干啥的呢? ? 表示当前的 ConcurrentHashMap 是否是在进行扩容。

    46931

    干货 | Java8 新特性指导手册

    Sorted 排序 Sorted 同样是一个中间操作,它的返参是一个 Stream 流。另外,我们可以传入一个 Comparator 用来自定义排序,如果不传,则使用默认的排序规则。...Match 匹配 顾名思义, match 用来做匹配操作,它的返回值是一个 boolean 类型。通过 match, 我们可以方便的验证一个 list 中是否存在某个类型的元素。...: // computeIfPresent(), 当 key 存在时,才会做相关处理 // 如下:对 key 为 3 的值,内部会先判断值是否存在,存在,则做 value + key 的拼接操作 map.computeIfPresent.../ 如下:先判断 key 为 23 的元素是否存在,不存在,则添加 map.computeIfAbsent(23, num -> "val" + num); map.containsKey(23);...// true // 先判断 key 为 3 的元素是否存在,存在,则不做任何处理 map.computeIfAbsent(3, num -> "bam"); map.get(3);

    1.4K20

    ConcurrentHashMap里面也有死循环,作者留下的“彩蛋”了解一下?

    接着调用 computeIfAbsent 方法,获取到 null 后调用 getValue 方法,将该方法的返回值和当前的 key 关联起来。 所以,第二次获取的时候拿到了 “why技术”。...但是目前而言,这种机制就算做出来,工作效率也是非常低下的,比如在当前的这个案例下。但是现在我们至少清楚的知道,是否要实现这种机制是不能确定的。...Bug 的原因 导致这个 Bug 的原因也是一句话就能说清楚,前面的 Pardeep 老哥也说了: 问题在于我们在进行 computeIfAbsent 的时候,里面还有一个 computeIfAbsent...现在 “AaAa” 就等着这个 computeIfAbsent 操作的返回值,然后进行下一步操作,也就是进行标号为 ③ 的操作了。 接着 “BBBB” 就来了。...标号为 ⑦ 的地方,判断 f 节点是否是红黑树存储。当然不是的。所以,不会进入这个分支。 标号为 ⑧ 的地方,binCount 代表的是该下标里面,有几个 node 节点。很明显,现在一个都没有。

    1.4K00

    面试阿里被P8质问:ConcurrentHashMap真的线程安全吗?

    显然,利用size方法计算差异值,是一个流程控制 诸如putAll这样的聚合方法也不能确保原子性,在putAll的过程中去获取数据可能会获取到部分数据 2.3 解决方案 整段逻辑加锁: [em987s6z7r.png...这就引申出代码中常见的另一个问题:在使用一些类库提供的高级工具类时,开发人员可能还是按照旧的方式去使用这些新类,因为没有使用其真实特性,所以无法发挥其威力。...的性能,优化后: [45niism1jb.png] ConcurrentHashMap的原子性方法computeIfAbsent做复合逻辑操作,判断K是否存在V,若不存在,则把Lambda运行后结果存入...Map作为V,即新创建一个LongAdder对象,最后返回V 因为computeIfAbsent返回的V是LongAdder,是个线程安全的累加器,可直接调用其increment累加。...不存在的时候,putIfAbsent返回null,小心空指针,而computeIfAbsent返回计算后的值 当Key不存在的时候,putIfAbsent允许put null进去,而computeIfAbsent

    1.4K32

    【小家java】Java中集合List、Set、Map删除元素的方法大总结(避免ConcurrentModificationException异常)

    因此我们平时使用中少不了对List的增删改查,本文就针对于对List的“删”操作进行一个分析,顺便说几个坑,希望能帮助到大家以后可以避免踩坑 2、栗子 有一个List,如果我们要删除其中的一个元素,怎么办呢...,是不是以后我们以后就可以用这种方法来删除了呢?...map.put("1", 2)); //null 如果是添加成功,返回null System.out.println(map.put("1", 3)); //2 如果已经存在此key了 会用新值覆盖旧值...返回新值 public static void main(String[] args) { Map map = new HashMap();...可以这样写 这样若已存在,返回值oldValue,若不存在就执行计算,也是返回一个可用的List // 这样对null非常友好,特别好用~~~~~~~~~~ list

    2.1K30

    Map在Java 8中增加非常实用哪些函数接口?

    使用该方法程序员可以省去查询指定键值是否存在的麻烦....V value)方法实现,该方法总是会用新值替换原来的值.为了更精确的控制替换行为,Java8在Map中加入了两个replace()方法,分别如下: replace(K key, V value),只有在当前...参数中BiFunction函数接口前面已经介绍过,里面有一个待实现方法R apply(T t, U u). merge()方法虽然语义有些复杂,但该方法的用方式很明确,一个比较常见的场景是将新的错误信息拼接到原来的信息上...Function是一个函数接口,里面有一个待实现方法R apply(T t). computeIfAbsent()常用来对Map的某个key值建立初始化映射.比如我们要实现一个多值映射,Map的定义可能是...Map,要向Map中放入新值,可通过如下代码实现: Map> map = new HashMap(); // Java7及以前的实现方式 if

    2K50
    领券