Java 中浮点数的哈希码

dav*_*avs 3 java floating-point hashcode

我有一个带有两个浮点变量和hashCode方法的类(当前代码片段中没有 equals):

public class TestPoint2D {
    private float x;
    private float z;

    public TestPoint2D(float x, float z) {
        this.x = x;
        this.z = z;
    }

    @Override
    public int hashCode() {
        int result = (x != +0.0f ? Float.floatToIntBits(x) : 0);
        result = 31 * result + (z != +0.0f ? Float.floatToIntBits(z) : 0);
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

下面的测试

@Test
public void tempTest() {
    TestPoint2D p1 = new TestPoint2D(3, -1);
    TestPoint2D p2 = new TestPoint2D(-3, 1);

    System.out.println(p1.hashCode());
    System.out.println(p2.hashCode());
}
Run Code Online (Sandbox Code Playgroud)

返回相同的值:

-2025848832

在这种情况下,我不能在 HashSet / HashMap 中使用我的 TestPoint2D

任何人都可以建议如何在这种情况下实现hashCode或与此相关的解决方法吗?

PS 增加了一个测试:

@Test
public void hashCodeTest() {
    for (float a = 5; a < 100000; a += 1.5f) {
        float b = a + 1000 / a; // negative value depends on a
        TestPoint3D p1 = new TestPoint3D(a, -b);
        TestPoint3D p2 = new TestPoint3D(-a, b);
        Assert.assertEquals(p1.hashCode(), p2.hashCode());
    }
}
Run Code Online (Sandbox Code Playgroud)

并且证明通过了

TestPoint2D(a, -b).hashCode() == TestPoint2D(-a, b).hashCode()

dus*_*sch 5

我会用Objects.hash()

public int hashCode() {
   return Objects.hash(x, z);
}
Run Code Online (Sandbox Code Playgroud)

来自 Javadoc:

public static int hash(Object... values)

为输入值序列生成哈希码。生成哈希码就像将所有输入值放入一个数组一样,并且通过调用 Arrays.hashCode(Object[]) 对该数组进行哈希处理。此方法对于在包含多个字段的对象上实现 Object.hashCode() 很有用。例如,如果一个对象具有三个字段 x、y 和 z,则可以这样写: