Veg*_*ard 2 java hashmap data-structures
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());
}
}
Run Code Online (Sandbox Code Playgroud)
为什么上面的代码返回的1大小是m?0x7f800001和0x7f800002都是 NaN 浮点值,但根据NaN != NaN定义,这不应导致冲突。
该行为类似于nullJava Hashmap 中记录的键处理,但我找不到任何表明该处理NaN是由 HashMap 处理的内容null。
Float.equals(Object)记录为:
将此对象与指定对象进行比较。当且仅当参数不为 null 并且是
Float表示浮点数的对象且其值与该对象所表示的浮点数相同时,结果才为 true。为此,当且仅当该方法在应用于每个浮点值时floatToIntBits(float)返回相同的值时,两个浮点值才被视为相同。int
现在听起来不同的 NaN 值应该被视为不相等,但floatToIntBits文档包括(强调我的):
如果参数为 NaN,则结果为 0x7fc00000。
在所有情况下,结果都是一个整数,当给该
intBitsToFloat(int)方法时,将生成一个与参数相同的浮点值floatToIntBits(除了所有 NaN 值都折叠为单个“规范”NaN 值)。
所以基本上,Float.equals(and Float.hashCode,也使用floatToIntBits(float)) 将所有 NaN 值视为相等。