HashMap取值空指针?是否因Cloudlet转Task的hashCode差异导致
核心原因
空指针的直接诱因是averageComputationCosts.get(task)返回null,而hashCode/equals实现不一致是最可能的根源,具体分为两种场景:
未基于唯一标识重写equals/hashCode
如果Cloudlet类没有重写equals和hashCode,默认使用Object类的实现(基于对象内存地址)。即使两个Task实例的cloudletId相同,只要是不同的对象实例,HashMap就会将它们视为不同的Key,导致存储后无法通过另一个实例取出值。父类与子类的equals/hashCode逻辑冲突
若Cloudlet基于cloudletId重写了equals/hashCode,但Task子类又重写这两个方法并加入额外字段,那么即使两个Task实例的cloudletId相同,只要子类字段不一致,就会被HashMap判定为不同Key,最终get操作返回null。
验证与解决方案
统一equals/hashCode实现
在Cloudlet类中基于唯一标识cloudletId重写equals和hashCode,确保只要cloudletId相同,就被视为同一个对象:@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Cloudlet cloudlet = (Cloudlet) o; return cloudletId == cloudlet.cloudletId; } @Override public int hashCode() { return Objects.hash(cloudletId); }若
Task子类没有额外的唯一标识需求,无需重写这两个方法,直接继承父类实现即可。检查实例一致性
确认两次调用getCloudletList()返回的集合中,是否是同一个Task实例(而非相同cloudletId的不同实例)。如果集合每次返回新创建的实例,必须依赖重写后的equals/hashCode才能正确匹配Key。添加空值防护
在调用get操作前先判断Key是否存在,避免空指针异常:if (averageComputationCosts.containsKey(task)) { double max = averageComputationCosts.get(task); // 业务逻辑处理 } else { // 处理Key不存在的场景,如日志记录或默认值赋值 }
内容的提问来源于stack exchange,提问作者Max Gabriel

