java - 为什么 HashMap 不能有不同的 NaN 值作为键?

标签 java data-structures hashmap

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());
    }
}

为什么上面的代码返回1作为m的大小? 0x7f8000010x7f800002 都是 NaN 浮点值,但由于 NaN != NaN 根据定义,这不应导致冲突。

该行为类似于 Java Hashmap 中记录的对 null 键的处理,但我找不到任何表明 NaN 被处理为 的内容由 HashMap 为 null

最佳答案

Float.equals(Object) 记录为:

Compares this object against the specified object. The result is true if and only if the argument is not null and is a Float object that represents a float with the same value as the float represented by this object. For this purpose, two float values are considered to be the same if and only if the method floatToIntBits(float) returns the identical int value when applied to each.

现在听起来不同的 NaN 值应该被视为不相等,但是 floatToIntBits 文档包括(强调我的):

If the argument is NaN, the result is 0x7fc00000.

In all cases, the result is an integer that, when given to the intBitsToFloat(int) method, will produce a floating-point value the same as the argument to floatToIntBits (except all NaN values are collapsed to a single "canonical" NaN value).

所以基本上,Float.equals(和 Float.hashCode,它也使用 floatToIntBits(float))将所有 NaN 值视为相等.

关于java - 为什么 HashMap 不能有不同的 NaN 值作为键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73647347/

相关文章:

java - 表单输入文件的 Spring 注释验证

java从/到asn1日期时间的转换

java - 使用 JSP 迭代 Multimap

c# - 如何处理这种树遍历

java - 如何将 Java 断言和 (JUnit) 测试结合起来进行公共(public)后置条件?

java - 用于响应元素进入的数据结构?

data-structures - RabbitmQ 使用什么算法进行主题交换的模式匹配

java - Java 中 HashTable 的自定义实现?

java - 计算 Arraylist 中书籍的数量

java - hashmap如何保证再次使用的key是相同的 `index`?