我什么时候应该覆盖Java中的equal方法

时间:2014-12-06 17:44:55

标签: java

所以在学校我们第一次学习Java,我们想要模拟一个Java libray应用程序,其中我们有两个名为“Book”的类,另一个名称为“并且在同一个ISBN中没有相同的ISBN所以我所做的就像下面的货架类一样,工作正常。

private boolean checkIsbnNumber(Book book){
        boolean isbnTaken = false;
        for(Book bList : this.bookList){
            if(bList.getIsbn().equals(book.getIsbn())){
                System.out.println("The books isbn number is taken");
                isbnTaken = true;
            }
        }
        return isbnTaken;
    }

但是我们的lecturue告诉我们的是以下内容,继续使用book类并将hash和equals方法覆盖到以下内容。

@Override
    public boolean equals(Object obj) { 
        if (obj instanceof Book) 
            return isbn.equals(((Book)obj).isbn); 
        else 
            return false; 
    } 

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 53 * hash + Objects.hashCode(this.isbn);
        return hash;
    }

然后再次在shelf类中执行以下操作。

public boolean checkISBN(Book b){
        boolean isbnExists = false;
        for (Book bList : bookList)
        {
            if(bList.getIsbn().equals(b.getIsbn())){
                System.out.println("Book ISBN already exist");
                isbnExists = true;
            }
        }
        return isbnExists;  
    }

我想知道的是这样做有什么意义?它有什么好处吗?为什么我们再次在equals方法中调用equals方法?一些帮助将不胜感激。

3 个答案:

答案 0 :(得分:3)

如果你真的想使用equals方法,那么你的比较应该是这样的: -

public boolean checkISBN(Book b){
    boolean isbnExists = false;
    for (Book bList : bookList)
    {
        if(**bList.equals(b)**){
            System.out.println("Book ISBN already exist");
            isbnExists = true;
        }
    }
    return isbnExists;  
}

注意高度重要的部分。

你的讲师想要这样做以明白equals方法的用法。 让我来解释一下你的方法和他的方法之间的区别。那么这样做的好处是: - 1.没有使用equals: - 在这种方法中,你比较书的ISBN,而你不是把书中有相同ISBN的书。

  1. 等于覆盖: -          首先,你是最重要的平等,这意味着你说两本书具有相同的ISBN是相同的。第二步,你比较书籍是否相等。
  2. 那么什么是优势,假设您需要在程序中基于相同的相等性进行其他操作,那么您最终不会在任何地方编写ISBN逻辑,只需要编写等于。 优势1: - 在现实世界中,软件的不同部分是由不同的人编写的,因此如果您正在写书,其他人将不需要知道是什么使两本书相等。他的设计或要求是基于平等的两个写代码。

    优势2: - Tommarrow,你决定书的平等不仅仅基于ISBN号。作者,你只需要更新equals方法,每个人的代码都可以正常工作,无需改变所有人。

    在真实的编程世界中,面向对象的编码为真实对象完成,有时由于现实世界中的业务变化而导致对象发生变化

答案 1 :(得分:2)

  

我想知道的是这样做有什么意义?

你的条件是没有两个ISBN可以是相同的。您正在更改equals方法,以便在ISBN相同时考虑两个Book个对象。

  

为什么我们再次在equals方法中调用equals方法?

您的ISBN是Object。当你比较两个对象时,如果你这样做..

Object1 == Object2

然后,您正在测试它们是否是相同的对象。如果它们具有相同的,则不会。当您致电equals时,您正在测试其他一些条件。例如,在String ..

的情况下
String s = new String("Hello");
String s2 = new String("Hello");

s == s2; // Returns false.
s.equals(s2); // Returns true.

这是因为ss2不是同一个对象,但它具有相同的值。

额外阅读

  • Here是对为什么的深入分析,您需要覆盖hashCode方法。

  • Here详细说明了您需要将equals与对象一起使用而不是==的原因。

答案 2 :(得分:1)

通常,您覆盖equals()有两个原因:

  • 您希望为对象设置自定义等式语义,或
  • 您希望在哈希容器中使用您的对象。

在这两种情况下,您都必须覆盖hashCode

例如,如果您想在不修改图书对象本身的情况下为每本图书添加评论,那么使用正确的equalshashCode可以让您这样做:

Map<Book,String> comments = new HashMap<Book,String>();
comments.put(myBook, "This is a good book");

虽然您可以通过检查书籍外部类来确定书籍对象的相等性,但最好在课程中使用此功能,因为不了解您的特定课程的人会是能够理解他们看到equals时发生了什么。他们也可以在没有深入学习的情况下使用你的课程,因为写这个

if (book1.equals(book2)) ...

比写这个

更容易
if (book1.getIsbn().equals(book2.getIsbn())) ...