为具有循环引用Java的类实现equals()

为具有循环引用Java的类实现equals(),java,Java,我想要一种方法来重写具有循环引用的类的equals方法。下面是我的类编辑:删除了getter和setter的代码 class Person implements Serializable{ private String fullName; private Person friend; // Getters and setters @Override public boolean equals(Object obj) { if (this

我想要一种方法来重写具有循环引用的类的equals方法。下面是我的类编辑:删除了getter和setter的代码

class Person implements Serializable{
    private String fullName;
    private Person friend;
    // Getters and setters

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (friend == null) {
            if (other.friend != null)
                return false;
        } else if (!friend.equals(other.friend))
            return false;
        if (fullName == null) {
            if (other.fullName != null)
                return false;
        } else if (!fullName.equals(other.fullName))
            return false;
        return true;
    }
}
在客户端类中,我有以下内容:

Person p1 = new Person();
Person p2 = new Person();
Person p3 = new Person();
p1.setFullName("nkuruza");
p2.setFullName("Another");
p3.setFullName("nkuruza");
p3.setFriend(p2);
p1.setFriend(p2);
p2.setFriend(p1);
问题是在这种情况下调用equals方法,例如p1.equalsp3产生StackOverflowException

如何实现equals方法而不必遇到此问题

我提前向您表示感谢。

由于p1的friend设置为p2,p2的friend设置为p1,因此您的equals方法最终在两个Person实例之间的无限调用循环中结束:

p1.equalsp2调用p2.equalsp1永远调用p1.equalsp2,或者直到JVM当前配置的堆栈大小限制达到为止,此时它将抛出StackOverflowException

目前的解决方案可能是直接测试好友的唯一属性,fullname是目前为止唯一的其他属性:

else if(!friend.fullName.equals(other.friend.fullName)

…确保更新代码以防止任何可能的空值当然

真正的答案是根据实际情况对类进行建模

事实上,定义一个人的真正方面是什么?! 这就是身份,比如名字

你的朋友明天可以改变,但你仍然是你


因此,换句话说:从比较中排除friends字段。甚至更好:考虑不要把这个关系写为该类中的字段,如果有的话,它应该是一个列表,而不是一个实例。但正如所说,理想情况下,这些信息不属于person类

为什么首先要覆盖等于?对于这样的类,默认实现可能是最好的。@JBNizet我试过了,结果是错误的,而对于p1,它应该是正确的。equalsp3@Nkuruza您如何定义具有非编程术语的Person对象的相等性?什么时候两个不同的Person对象应该是相等的?@Progman如果全名相同,friendPerson根据这个定义与其他friendPerson相等,那就应该是一样的。非常感谢你的回答,这肯定会解决我循环引用的问题,但是在阅读了@GhostCat的回答之后,我认为我的模型课实际上并不符合现实,这才是真正的问题所在。@Nkuruza也投赞成票;此外,当OP解释为什么它接受另一个答案时,我总是很感激,这是礼貌。干得好D@tryman我对两个答案都投了赞成票,但不幸的是,我没有足够的声誉,但是StackOverflow向我保证,赞成票被重新编码:-Yw!是的,我完全同意@GhostCat,设计当然是这里最基本的关注点。然而,我选择将重点放在机械问题上,您提出了无限调用循环,以帮助确保您首先看到它发生的原因。