gpt4 book ai didi

java - 用作哈希键的 java 对象是否需要 'fully' 不可变?

转载 作者:行者123 更新时间:2023-12-02 15:24:07 26 4
gpt4 key购买 nike

如果hashCode()计算使用不可变字段并且equals()使用所有字段,那么会是这样吗?当类用作哈希键时有问题吗?例如

import java.util.Objects;

public class Car {
protected final long vin;
protected String state;
protected String plateNumber;

public Car( long v, String s, String p ) {
vin = v; state = s; plateNumber = p;
}


public void move( String s, String p ) {
state = s; plateNumber = p;
}


public int hashCode() {
return (int)( vin % Integer.MAX_VALUE );
}


public boolean equals( Object other ) {
if (this == other) return true;
else if (!(other instanceof Car)) return false;
Car otherCar = (Car) other;
return vin == otherCar.vin
&& Objects.equals( state, otherCar.state )
&& Objects.equals( plateNumber, otherCar.plateNumber );
}
}

汽车对象被插入到哈希集中后,move() 就会被调用,这可以通过保存在别处的引用来实现。

我不关心这里的性能问题。只有正确性。

我已阅读java hashCode contact ,关于SO的答案很少,包括this作者:可敬的 Jon Skeet 和 this来自大蓝。我觉得最后一个链接给出了最好的解释,并暗示上面的代码是正确的。

编辑

结论:
该类满足 java 中对“equals()”和“hashCode()”的约束。然而,当用作集合中的键(无论是否经过散列)时,它违反了对“equals()”施加的附加要求。
额外的要求是,只要对象是键,“equals()”就需要保持一致。
请参阅下面 Louis Wasserman 的反例和 Douglas 提供的引用资料。

一些说明:

A) 该类满足 java 对象级别约束:

  1. ( carA == carB ) 意味着 ( carA.hashCode() == carB.hashCode() )
  2. ( carA.hashCode() != carB.hashCode() ) 意味着 ( carA != carB )
  3. equals() 需要自反、对称、传递。
  4. hashCode() 需要保持一致。即对象在其生命周期内不能更改。
  5. equals() 需要保持一致,只要两个对象都没有被修改

请注意,“1.”和“2.”的反转不是必需的。并且上面的类满足所有条件。
java 文档还提到“equals() …在对象上实现了最具辨别力的可能等价关系”,但不确定这是否是强制性的。

B) 至于性能,碰撞避免概率的增量随着我们组合的每个连续成员变量而减少。通常,几个精心选择的成员变量就足够了。

最佳答案

如果您在汽车出现在 map 中之后从未调用move,那么这是正确的。否则就错了。在键位于映射中后,hashCode equals 都必须保持一致。

关于java - 用作哈希键的 java 对象是否需要 'fully' 不可变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45966432/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com