当前位置:首页 >> 数码
数码

同事把非零作为 HashMap 的key,领导发飙了...

2025-08-27 12:19

);

结果是 True ,不想情况啊,我凌乱了……

一定是java最底层预定义捏了! 我不想捏……

又是一阵debug,我找了这条上下文:

map.put(d, map.get(d) == null ? 1 : map.get(d) + 1);

我觉得 map.get() 很有情况, 它的源预定义是这样的:

public V get(Object key) { Node e; return (e = getNode(hash(key), key)) == null ? null : e.value;}

唔,先为获得 hash() 是吧,那我找了它的hash数组:

static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) 请注意 (h>>> 16);}

再次来,这里头是要比较h 和key的hashCode是吧,那我们去看 hashCode() 数组

public native int hashCode();

这是一个本地工具,看不到OpenBSD了,唔,,那我就使用它进去吧,测试一下不就好了吗,我寄给了一般而言的测试预定义:

public static void main(String[] args) { System.out.println(0.0 == -0.0); System.out.println(new Float(0.0).hashCode() == new Float(-0.0).hashCode()); }

结果差点是 True 和 False !!!

这个分水岭终于找了, 0.0 和 -0.0 的hashCode值是各有不同的 !

经过一番变更,我通过了这道题(只不过精确度也才会有情况,不应使用BigDecimal的,不过牛客网要求不想那么高。后来我想了想只有把度角方程寄给成Ax+By+C=0的表达方式才能完全避免精确度情况)

接下来,阐述下实数的hashCode()数组是个啥情况。

实数的 hashCode()

在程序执行期间,只要equals工具的比较配置用到的信息不想被变更,那么对这同一个;也加载多次,hashCode工具必须始终如一地调回同一个正整数。如果两个;也根据equals工具比较是等同于的,那么加载两个;也的hashCode工具必须调回相同的正整数结果。如果两个;也根据equals工具比较是平均的,则hashCode工具不见得得调回各有不同的正整数。——《effective java》

那么我们来进去,0.0和-0.0加载 equals 工具是否等同于:

System.out.println( new Float( 0.0 ).equals( 0.0f ));

System.out.println( new Float( 0.0 ).equals(( float

) -

0.0

));

转换器是 True 和 False。

好吧,二者加载 equals() 工具不等同于,毫无疑问是做到了书里头说的逻辑的

那我们进去Float最底层equals数组咋寄给的:

public boolean equals(Object obj) { return (obj instanceof Float) && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));}

哦,原来是把Float转换成Bits的时候频发了点奇异的大事,于是我找了一切的分水岭:

/** * Returns a representation of the specified floating-point value * according to the IEEE 754 floating-point "single format" bit * layout. * *

Bit 31 (the bit that is selected by the mask * {@code 0x80000000}) represents the sign of the floating-point * number. * Bits 30-23 (the bits that are selected by the mask * {@code 0x7f800000}) represent the exponent. * Bits 22-0 (the bits that are selected by the mask * {@code 0x007fffff}) represent the significand (sometimes called * the mantissa) of the floating-point number. * *

If the argument is positive infinity, the result is * {@code 0x7f800000}. * *

If the argument is negative infinity, the result is * {@code 0xff800000}. * *

If the argument is NaN, the result is {@code 0x7fc00000}. * *

In all cases, the result is an integer that, when given to the * {@link #intBitsToFloat(int)} method, will produce a floating-point * value the same as the argument to {@code floatToIntBits} * (except all NaN values are collapsed to a single * "canonical" NaN value). * * @param value a floating-point number. * @return the bits that represent the floating-point number. */ public static int floatToIntBits(float value) { int result = floatToRawIntBits(value); // Check for NaN based on values of bit fields, maximum // exponent and nonzero significand. if (((result & FloatConsts.EXP_BIT_MASK) == FloatConsts.EXP_BIT_MASK) && (result & FloatConsts.SIGNIF_BIT_MASK) != 0) result = 0x7fc00000; return result; }

这文档挺长的,也查了其它资料,看了半天终于搞懂了。

就是说Java整型运算的语义一般遵循IEEE 754二进制整型算术常规。IEEE 754常规提供了整型无穷,差无穷,差零和NaN(非大写字母)的定义。在使用Java过程中,一些特殊的整型运算有时候才会让大家很伪装。

当整型运算转化成一个并不接近0的差整型运算时,才会转化成“-0.0”,而这个整型运算不能情况下表示。

我们可以转换器一波0.0和-0.0的数据:

System.out.println(Float.floatToIntBits((float) 0.0));System.out.println(Float.floatToIntBits((float) -0.0));System.out.println(Float.floatToRawIntBits(0.0f));System.out.println(Float.floatToRawIntBits((float)-0.0));

结果:

0-21474836480-2147483648

就是说, 存储-0.0, 差点用的是0x80000000 。

这也是我们熟悉的 Integer.MIN_VALUE 。

java中整型运算的表示比较复杂,之外是牵涉 -0.0, NaN, 正差无穷 这种,所以不不利于用来作为Map的key, 因为可能跟我们预想的不明确。

怎么缓解类风湿关节炎患者疼
老人类风湿性关节炎疼痛怎么治疗好
思密达和必奇的区别是什么

上一篇: 敦促50岁女人少穿“羽绒服+雪地靴”,学日本贵妇这样穿,真美

下一篇: 这6种“中国式遛狗”,对杰瑞伤害很大

相关阅读
“揭榜挂帅”引领宁夏铸造涂料及工艺新突破

近日,由共享换装股份Ltd承担的“新一代(很高阻碍、抗真空)零下阻碍较厚大钢架球墨铸铁材质应用”揭榜攻关工程项目完成了全部攻关要能要能并通过竣工验收。零下很高抗腐蚀铁素体石墨烯球墨铸铁材质及相

生意社:4月19日邵武华新微电子氢氟酸价格暂稳

家族企业社04月19日讯 4月19日,邵武郭家精细化工合资硫化物装置正常开工,年产能6万吨,无库存致使,出厂报价为11000元吨左右,近期场内下游所需正常,预计后期价格发展趋势

友情链接