【问题标题】:equals() method for classes with bidirectional association具有双向关联的类的 equals() 方法
【发布时间】:2011-05-26 18:34:47
【问题描述】:

我正在尝试在我的应用程序中为 Java 类 BookChapter 实现 equals 方法。 Book 有一组Chapters,而Chapter 有一个关联的Book。双向关联如下图:

class Book{
    private String isbn;
    private String name;
    private Date publishDate;
    private Set<Chapter> chapters;
    ...

    public boolean equals(Object o){
        if(o == this){
            return true;
        }
        if (!(o instanceof Book)){
            return false;
        }
        Book book = (Book)o;
        if( (this.isbn.equals(book.getIsbn()) ) && (this.name.equals(book.getName())) &&(this.publishDate.equals(book.getPublishDate())) &&(this.chapters.equals(book.getChapters())) ){
            return true;
        }else{
            return false;
        }

    }
}

现在我尝试为Chapter 实现equals

public class Chapter {
    private String title;
    private Integer noOfPages;
    private Book book;
    ...

    public boolean equals(Object o){
         if(o == this){
            return true;
        }
        if (!(o instanceof Chapter)){
            return false;
        }
        Chapter ch = (Chapter)o;
        if((this.title.equals(book.getTitle())) && (this.noOfPages.intValue()== book.getNoOfPages().intValue())  ){
            return true;
        }else{
            return false;
        }
    }

}

在这里,我想知道是否还需要比较 book 字段。那不会开始无限循环吗?对于这种双向关联,实现equals 方法的正确方法是什么?

【问题讨论】:

    标签: java equals bidirectional


    【解决方案1】:

    只有在 ISBN 相同的情况下,一本书才应该与另一本书相同。因此,仅基于该字段实现 book equals。

    对于章节-比较章节号和拥有Book

    【讨论】:

      【解决方案2】:

      (我假设这是 Java) 在 Chapter 类的 equals 方法中,您可以只比较参考书目(即使用 ==,而不是 equals)。这仅比较引用,因此可以避免无限循环。但是,如果您有时克隆书籍,这种方法会失败。

      解决此特定情况的更好方法不是比较书籍,而是比较它们的 ISBN,因为这是书籍的唯一标识符。

      一般来说,最好避免这样的双向依赖。一种方法是让两个类之一实现一个接口,以免直接使用它。

      【讨论】:

      • 即使使用接口可以防止类之间的双向依赖,但在运行时实例之间仍然存在双向依赖。所以我建议人们不应该比较书籍(通过==equals()),而要么简单地忽略书籍(来自不同书籍的两章相同或不同吗?),或者比较书籍标识符,如国际标准书号。
      • 我完全同意,我只是评论了循环依赖,因为我被教导要尽可能避免它们。
      【解决方案3】:

      从建模的角度来看,这一章是本书的一部分。因此,尽管您在两个方向都有参考,但这本书比章节“更强大”。

      当您与 Book 和 Chapter 有部分关系时,在定义 equals() 时,部分(Chapter)有时会考虑整个(Book)。但反之则不然。

      很明显,本书不会使用其章节来定义equals()。本章可能会使用本书。这取决于型号。

      【讨论】:

        【解决方案4】:

        您必须选择 Book 字段作为 ID(如 ISBN)。然后,在Chapter 等于,你可以做类似的事情

        book.getISBN().equals(other.book.getISBN())
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-05-12
          • 1970-01-01
          • 2018-08-24
          • 1970-01-01
          • 1970-01-01
          • 2021-03-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多