可以添加equals()和hashCode()方法会破坏某些东西

问题描述 投票:0回答:4

添加equals()hashCode()方法是否有可能破坏已经存在的代码?

我有一个包含3个字段,getter和setter的类:

public class Person {
private final String name;
private final List<Friend> friends;
private final Integer age;

为了测试此类,我使用了:isEqualToComparingFieldByField()方法比较两个Person对象,而不是添加equals()hashCode()。其他解决方案是重写equals()hashCode()并使用assertEquals()比较这些对象,但是我可以完全确定它不会破坏任何对象吗?

java equals hashcode
4个回答
7
投票

我可以完全确定它不会破坏任何东西吗?

没有您正在将相等的含义从引用标识更改为一种值相等。您将打破依赖于当前行为的所有内容。例如,这是一些有效的代码:

Person person1 = new Person("Foo", 100);
Person person2 = new Person("Foo", 100);
// This is fine. Two distinct Person objects will never be equal...
if (person1.equals(person2)) {
    launchNuclearMissiles();
}

您建议的更改将打破这一点。

实际上是否具有类似的代码?很难说。

[更有可能,如果您想更改hashCode以包括来自List<Friend>的哈希,除非类型实际上是不可变的,否则您很容易破坏代码。例如:

Map<Person, String> map = new HashMap<>();
Person person = new Person("Foo", 100);
map.put(person, "Some value");

// If this changes the result of hashCode()...
person.addFriend(new Friend("Bar"));
// ... then you may not be able to find even the same object in the map.
System.out.println(map.get(person));

根本上,您需要知道其他代码使用Person,因此您知道它所依赖的内容。如果Person是不可变的,这将使生活变得更简单,因为您无需担心第二种问题。 (为可变类型覆盖equals()hashCode()是一项根本危险的工作。)


0
投票
这取决于您在何处以及如何使用person对象。例如,如果将人员存储在HashSet,HashMap等数据结构中,则其行为可能会有所不同。但是,如果您正在使用任何使用哈希和等于的数据结构,则始终建议覆盖这些方法。

0
投票
创建自定义类时,您应始终覆盖这些方法。如果您不这样做,则使用Object类的实现,并且这些实现依赖于引用-而不是您的自定义类的对象中字段的值。

0
投票
不,您不能确定没有任何问题。如果您的代码中使用了Person,例如在地图,集合等中,则覆盖equals()hashCode()显然可以更改某些操作的结果。
© www.soinside.com 2019 - 2024. All rights reserved.