关于computeIfAbsent更新重复Key-List值对的原理疑问
HashMap的computeIfAbsent()执行逻辑解析
问题场景
如下代码执行后,key1对应的列表会包含两个元素,这和很多人对computeIfAbsent()的初始认知不符:
Map<String, List<String>> map = new HashMap<>(); map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value1"); map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value2"); assertThat(map.get("key1").get(0)).isEqualTo("value1"); assertThat(map.get("key1").get(1)).isEqualTo("value2");
核心原理拆解
computeIfAbsent()的核心行为分两步:
- 检查键是否存在:如果传入的key在Map中不存在,执行传入的函数生成新值并存入Map;如果key已存在,跳过新值生成逻辑。
- 返回对应的值:不管key是否存在,最终返回Map中该key对应的值对象引用——要么是刚创建的新对象,要么是已存在的旧对象。
你看到列表被追加元素的原因是:
第二次调用computeIfAbsent()时,key1已存在,直接返回了之前创建的ArrayList引用;紧接着调用的.add("value2")是对这个返回的列表对象进行修改,而这个列表正是Map中存储的对象(Java中对象是引用传递),所以修改会直接反映在Map里。
常见误区澄清
误区:认为key存在时,computeIfAbsent()会阻止对值的修改
真相:computeIfAbsent()只负责确保key对应的值存在,不会限制你对返回值的后续操作。它不会替换已有的值,但返回的引用允许你直接修改值对象的内部状态。
内容的提问来源于stack exchange,提问作者Travis Zhang
相关产品推荐
相关产品推荐

