java map.get返回null_Java HashMap在get()调用时返回null

在尝试使用HashMap中的给定键获取值时,我们观察到了NullPointerException.

以下是我将用于说明问题的示例代码.

public class Test {

private Map employeeNameToAgeMap = new HashMap();

public int getAge(String employeeName) {

if (!employeeNameToAgeMap.containsKey(employeeName)) {

int age = getAgeFromSomeCustomAPI(employeeName);

employeeNameToAgeMap.put(employeeName,age);

}

return employeeNameToAgeMap.get(employeeName);

}

}

在方法的最后一行获取NullPointerException,即“return employeeNameToAgeMap.get(employeeName);”

正如我们所看到的,employeeNameToAgeMap不是null,并且调用者也没有将employeeName作为null传递(这是我们已经接受了调用代码本身).

这个方法将从不同的线程以非常快的速度调用(来自一些计划运行的计时器任务,每100ms左右)

这个NullPointerException的原因似乎是为给定员工提供的值(年龄)为空,但事实并非如此,因为保证自定义API方法(getAgeFromSomeCustomAPI())返回给定员工的某个年龄,即使它返回null,那么异常stacktrace应该显示日志中的对应行而不是最后一行.

我唯一的假设是,当一个线程T1试图填充该缓存时,T2出现了,由于某种原因,它能够发现缓存已经拥有了employeeName,但是当它试图获得年龄时,它就抛出了一个NPE.但是我并不是100%确信当put()操作正在进行给定的键和值时,相同键的containsKey()返回true.

我知道需要增强此代码以满足同步问题(通过使用ConcurrentHashMap或锁),但期待知道此问题的真正原因.

我真的很感激帮助.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
帮我审查一下下带private Map<String, ItemsCustomTargetResult> getItemsCustomTargetResult(BidNodeViewDto bidNodeViewDto, Map<String, String> targetCodeMap) { Map<String, ItemsCustomTargetResult> itemsCustomTargetResultMap = new HashMap<>(); List<String> colName = new ArrayList<>(); colName.add(Constants.ProjectView.COL_NAME_EXPRESSION); colName.add(Constants.ProjectView.COL_NAME_EXPERSSION_VALUE); colName.add(Constants.ProjectView.COL_NAME_TOTAL); colName.add(Constants.ProjectView.COL_NAME_PERCENT); colName.add(Constants.ProjectView.COL_NAME_UNIT); for(String name : colName) { String value = null; if (Constants.ProjectView.COL_NAME_EXPRESSION.equals(name)) { value = bidNodeViewDto.getExpressionName() + ""; }else if(Constants.ProjectView.COL_NAME_EXPERSSION_VALUE.equals(name)) { value = bidNodeViewDto.getExpressionVal() + ""; }else if(Constants.ProjectView.COL_NAME_PERCENT.equals(name)) { value = bidNodeViewDto.getPercentTotal() + ""; }else if(Constants.ProjectView.COL_NAME_TOTAL.equals(name)) { value = bidNodeViewDto.getAmount() + ""; }else if(Constants.ProjectView.COL_NAME_UNIT.equals(name)) { value = bidNodeViewDto.getUnitIndex() + ""; } String targetCode = targetCodeMap.get(name); if(Strings.isBlank(targetCode)) { continue; } ItemsCustomTargetResult itemsCustomTargetResult = new ItemsCustomTargetResult(); itemsCustomTargetResultMap.put(targetCode,itemsCustomTargetResult.obtainItemsCustomTargetResult(targetCode, null, value, null)); } return itemsCustomTargetResultMap; }
06-10
这段代码的主要作用是根据传入的参数`bidNodeViewDto`和`targetCodeMap`生成一个`Map`,其中`Map`的键值为`targetCode`,值为`ItemsCustomTargetResult`对象。 这个方法看起来没有太大问题,但是有一些可以改进的地方: 1. 在循环中,每次迭代都会新建一个`String`类型的变量`value`并初始化为`null`,这个可以放到循环外部先声明再初始化,避免每次都进行声明和初始化。 2. `if...else`嵌套语句比较多,可以考虑使用`switch`语句来代替。 3. 在循环中,如果`targetCode`为空字符串,则直接跳过当前迭代,没有任何处理。这个可以添加一个日志输出或者抛出异常来提醒调用者传入的参数有误。 下面是一种改进后的代码: ``` private Map<String, ItemsCustomTargetResult> getItemsCustomTargetResult(BidNodeViewDto bidNodeViewDto, Map<String, String> targetCodeMap) { Map<String, ItemsCustomTargetResult> itemsCustomTargetResultMap = new HashMap<>(); List<String> colName = Arrays.asList(Constants.ProjectView.COL_NAME_EXPRESSION, Constants.ProjectView.COL_NAME_EXPERSSION_VALUE, Constants.ProjectView.COL_NAME_TOTAL, Constants.ProjectView.COL_NAME_PERCENT, Constants.ProjectView.COL_NAME_UNIT); for (String name : colName) { String value = null; switch (name) { case Constants.ProjectView.COL_NAME_EXPRESSION: value = String.valueOf(bidNodeViewDto.getExpressionName()); break; case Constants.ProjectView.COL_NAME_EXPERSSION_VALUE: value = String.valueOf(bidNodeViewDto.getExpressionVal()); break; case Constants.ProjectView.COL_NAME_TOTAL: value = String.valueOf(bidNodeViewDto.getAmount()); break; case Constants.ProjectView.COL_NAME_PERCENT: value = String.valueOf(bidNodeViewDto.getPercentTotal()); break; case Constants.ProjectView.COL_NAME_UNIT: value = String.valueOf(bidNodeViewDto.getUnitIndex()); break; default: throw new IllegalArgumentException("Invalid column name: " + name); } String targetCode = targetCodeMap.get(name); if (targetCode == null || targetCode.isEmpty()) { // 日志输出或者抛出异常 continue; } ItemsCustomTargetResult itemsCustomTargetResult = new ItemsCustomTargetResult(); itemsCustomTargetResultMap.put(targetCode, itemsCustomTargetResult.obtainItemsCustomTargetResult(targetCode, null, value, null)); } return itemsCustomTargetResultMap; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值