为何HashMap不能将不同NaN值作为键?代码示例解析
HashMap存储两个NaN键后size为1的原因解析
你提到的代码中,两个通过Float.intBitsToFloat()生成的NaN值作为HashMap的键,最终map的size返回1,这看起来和“NaN不等于自身”的数学定义矛盾,具体原因如下:
代码复现
import java.util.*; public class MyClass { public static void main(String args[]) { Map<Float, Integer> m = new HashMap<>(); m.put(Float.intBitsToFloat(0x7f800001), 1); m.put(Float.intBitsToFloat(0x7f800002), 2); System.out.println(m.size()); } }
核心原因
- 哈希码一致:所有Float类型的NaN,通过
Float.hashCode()计算得到的哈希码完全相同。Java中Float的哈希码逻辑里,NaN被统一映射为固定值,导致两个NaN键会被分配到HashMap的同一个桶中。 - equals方法的特殊判定:虽然数学上
NaN != NaN,但Java的Float.equals(Object)方法做了特殊处理——只要两个Float对象表示的都是NaN,equals()就会返回true。这是Java语言规范明确规定的行为,目的是让NaN在集合框架中能被正确识别为相等的键。
HashMap判断两个键是否相同的逻辑是:先比较哈希码是否一致,再通过equals()方法确认相等。由于两个NaN键同时满足这两个条件,HashMap会认为它们是同一个键,第二次put操作会覆盖第一次的value,最终map的size为1。
内容的提问来源于stack exchange,提问作者Vegard
相关产品推荐
相关产品推荐

