当前位置: 首页 > 面试题库 >

Java 实施平等合同的正确方法

池麒
2023-03-14
问题内容

我有一个名为User的域对象。用户的属性包括ssoId,名称,电子邮件,createdBy,createdDate和userRole。其中,ssoId必须是唯一的,因为两个用户不能具有相同的sso id。因此,我的equals方法检查sso id并返回true或false。

@Override public boolean equals(Object o) {
    if (!(o instanceof User))
      return false;
    return user.getSsoId().equals((User)o.getSsoId());
}

我认为这是一个错误的实现,尽管就业务规则而言是正确的。对于具有相同sso id但名称或电子邮件或两者具有不同值的两个对象,以上实现将返回true。我应该更改我的平等合约以检查所有字段的相等性吗?你有什么建议?


问题答案:

这(几乎)对“技术平等”是正确的,但对“自然平等”却不正确。为了达到最高的技术平等,你还应该测试自反性o == this。该对象可能尚未持久存储在数据库中,因此还没有技术ID。例如

public class User {

    private Long id;

    @Override
    public boolean equals(Object object) {
        return (object instanceof User) && (id != null) 
             ? id.equals(((User) object).id) 
             : (object == this);
    }

    @Override
    public int hashCode() {
        return (id != null)
             ? (User.class.hashCode() + id.hashCode())
             : super.hashCode();
    }

}

对于“自然平等”,你应该比较所有非技术属性。对于“现实世界的实体”而言,这毕竟比技术平等更强大(但也更昂贵)。

public class User {

    private String name;
    private Date birth;
    private int housenumber;
    private long phonenumber;

    @Override
    public boolean equals(Object object) {
        // Basic checks.
        if (object == this) return true;
        if (!(object instanceof User)) return false;

        // Property checks.
        User other = (User) object;
        return Objects.equals(name, other.name)
            && Objects.equals(birth, other.birth)
            && (housenumber == other.housenumber)
            && (phonenumber == other.phonenumber);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, birth, housenumber, phonenumber);
    }

}

没错,当有很多属性时,这就是很多代码。有点像样的IDE(Eclipse中,NetBeans中,等),可以只自动生成equals()hashCode()(也toString(),getter和setter)为你服务。充分利用它。在Eclipse中,右键单击代码,然后偷看Source(Alt + Shift + S)菜单选项。



 类似资料:
  • 我有一个结构如下的项目。 是我的主要应用程序,而和是导入到Project中的两个库。使用了的一些类,使用了的一些类。 在的文件中,我使用了。一切正常。但是,如果我用替换,它就不能从导入类。它给出错误。

  • 我正在使用这个库:https://tls.mbed.org/download用ESPRESIF ESP32。目标是使用AES-CTR加密一些数据,然后将密码文本解密回原始纯文本。我解密后得到的结果不正确。 因为我们使用的是CTR模式,所以不需要单独的“解密”功能;我们可以只调用一次encrypt函数进行加密,然后再调用同一个函数一次,它就会解密。至少,大多数消息来源都是这么说的,其他实现也是如此:

  • 我对collection.sort()方法有一些问题。 Java . lang . illegalargumentexception:比较法违反了它的通用契约! 位于Java . util . Tim sort . merge lo(Tim sort . Java:747) at java.util.TimSort.mergeAt(TimSort.java:483) 位于java.util.Tim

  • 问题内容: 我不确定这是否是同步我的的正确方法。 我有一个 从函数传递过来的。 现在,我正在尝试使其同步。这是否正确同步了我的对象? 问题答案: 您要进行两次同步,这是没有意义的,可能会减慢代码的速度:在列表上进行迭代时所做的更改需要整个操作的同步,在这种情况下,使用Using 这样做是多余的(它创建了一个包装程序来同步各个操作)。 但是,由于您要完全清空列表,因此迭代删除第一个元素是最糟糕的方法

  • 问题内容: 我想知道退出程序之前等待go例程完成的正确方法是什么。阅读其他答案,看来bool chan可以解决问题,就像在Playground链接中一样 我在这里有两个问题: 为什么<-完成的作品完全可以? 如果我取消最后一行的注释会怎样?我有一个死锁错误。这是因为通道为空,并且没有其他函数向其发送值吗? 问题答案: 为何一切正常? 之所以有效,是因为运行时检测到您正在向其他地方的通道写入内容。

  • 问题内容: 在讨论Java同步问题时,有人评论说以下片段不是等效的(可能会编译为不同的字节码): 和 它们相等吗? 问题答案: 尽管我测试过的编译器(Java 1.6.0_07和Eclipse 3.4)生成了不同的字节码,但它们在功能上是等效的。第一个生成: 第二个生成: (感谢ASM进行字节码打印)。 因此,它们之间的差异一直保持到字节码级别,并且取决于JVM是否使它们的行为相同。但是,它们确实