如何用Map.computeIfAbsent()替换Map.get()条件判断解决Sonar问题
问题:用computeIfAbsent替代Map条件判断的错误解决
需求:遍历Map列表,当Map中不存在id键时,同时插入id和name对应的空字符串。Sonar要求用computeIfAbsent()替换原有的get()+条件判断写法,但自行尝试后报错。
原代码
Sonar标记错误的原始实现:
public void testMethod(List<Map<String, Object>> restultMapList) { for(Map<String, Object> resultMap : restultMapList) { if(resultMap.get("id")==null) { resultMap.put("id", ""); resultMap.put("name", ""); } } }
错误尝试代码
自行编写的computeIfAbsent()实现(编译报错):
public void testMethod(List<Map<String, Object>> restultMapList) { for(Map<String, Object> resultMap : restultMapList) { resultMap.computeIfAbsent("id", x-> x.put("id","")); } }
报错信息
该行存在多个标记 - Lambda表达式仅在源代码级别1.8或更高版本中允许 - 类型String中未定义方法put(String, String)
错误原因分析
- Lambda参数错误:
computeIfAbsent的第二个参数是Function<K, V>,这里的x代表的是键"id"(String类型),所以调用x.put()必然报错——String类根本没有put方法。我们需要的是返回id对应的值,同时在逻辑里处理name的插入。 - Java版本问题:报错提示Lambda需要Java 8及以上支持,必须确保项目的编译级别设置为1.8或更高。
正确实现方式
方式一:用computeIfAbsent完成多键插入
利用computeIfAbsent的特性——仅当键不存在时执行Lambda逻辑,在逻辑里同时处理name的插入:
public void testMethod(List<Map<String, Object>> resultMapList) { for(Map<String, Object> resultMap : resultMapList) { // 仅当id不存在时执行Lambda内的逻辑 resultMap.computeIfAbsent("id", key -> { resultMap.put("name", ""); return ""; // 返回id对应的空字符串 }); } }
方式二:调整编译级别(必要前提)
如果项目之前是用低于Java 8的版本编译,需要修改构建配置:
- Maven:在
pom.xml中添加或修改配置
<properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>
- IDEA:依次打开
File > Project Structure > Project Settings > Project,将Project SDK和Project language level设置为1.8+
备选方案:用containsKey更直观(Sonar也接受)
如果觉得在computeIfAbsent里操作其他键不够直观,也可以用containsKey替代原有的get()判断,这种写法Sonar同样认可:
public void testMethod(List<Map<String, Object>> resultMapList) { for(Map<String, Object> resultMap : resultMapList) { if(!resultMap.containsKey("id")) { resultMap.put("id", ""); resultMap.put("name", ""); } } }
内容的提问来源于stack exchange,提问作者User27854
相关产品推荐
相关产品推荐

