Java - How to check if two objects, from the same abstract class, are equal

java compare two objects field by field
java compare two objects attributes
how to compare two different objects in java
java compare two objects and get differences
java override equals
how to compare two pojo objects in java
java override equals and hashcode
java object equals

I'm writing a program which contains an abstract class of 'Book', and I have two classes ('LearnBook' and 'ReadingBook') which inherit from 'Book'.

Book:

Public abstract class Book {
protected String name;
protected String author;

LearningBook:

public class LearningBook extends Book {
private String subject;

ReadingBook:

public class ReadingBook extends Book {
private int numberOfPages;

At the main class I have Book array which can include any instance of Book.

I want to add a method which checks if two Book objects are exactly the same, to prevent duplicating in the Book array. it looks like this:

public boolean sameBookCheck(Book book1, Book book2)

So my first idea was to write an isEqual() method in the Book class, which checks if the "name" and the "author" are equals. But then I need to check if it's a learning book or reading book so I could know if I need to compare the "subject" value or the "numberOfPage" value.

I have no idea how to do it and I'd appreciate your help.

You can use the following design:

  1. In Book abstract class have an equals() function and check whether the other object is of type Book and have same values in all fields.
  2. In LearningBook and ReadingBook have equals() function which first checks whether the other object is of same class, then call Book's equals() function, checking the fields of abstract class, and then check whether field(s) of current class have same values or not.

Have a look at the code:

abstract class Book {

    protected String name;

    protected String author;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((author == null) ? 0 : author.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Book))
            return false;
        Book other = (Book) obj;
        if (author == null) {
            if (other.author != null)
                return false;
        } else if (!author.equals(other.author))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}


class LearningBook extends Book{

    private String subject;

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((subject == null) ? 0 : subject.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (!(obj instanceof LearningBook))
            return false;
        LearningBook other = (LearningBook) obj;
        if (subject == null) {
            if (other.subject != null)
                return false;
        } else if (!subject.equals(other.subject))
            return false;
        return true;
    }

}


class ReadingBook extends Book{

    private int numberOfPages;

    public int getNumberOfPages() {
        return numberOfPages;
    }

    public void setNumberOfPages(int numberOfPages) {
        this.numberOfPages = numberOfPages;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + numberOfPages;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (!(obj instanceof ReadingBook))
            return false;
        ReadingBook other = (ReadingBook) obj;
        if (numberOfPages != other.numberOfPages)
            return false;
        return true;
    }

}


public class Runner {

    public static void main(String[] args) {

        Book learningBook = new LearningBook();
        learningBook.setAuthor("auth");
        learningBook.setName("sci");

        Book learningBook2 = new LearningBook();
        learningBook2.setAuthor("auth");
        learningBook2.setName("sci");


        Book readingBook = new ReadingBook();
        readingBook.setAuthor("auth");
        readingBook.setName("sci");

        //returns false
        System.out.println(learningBook.equals(readingBook) );

        //returns true
        System.out.println(learningBook.equals(learningBook2) );
    }

}

Comparing Java objects with equals() and hashcode(), Every Java object inherits a set of base methods from java.lang. The purpose of the equals() method is to determine whether the argument is equal if two objects have different hash codes, then they cannot be equal to each other. they are the same for all class instances and thus clearly identical in an  Type in the following Java statements. According to the equals method, two circles are equal if they have the same radius. Save your file as CompareTwoObjectsWithequalsMethod.java. Open a command prompt and navigate to the directory containing your Java program. Then type in the command to compile the source and hit Enter.

Write an equals-implementation for each of the three classes. Every implementation is only responsible for its own fields.

The equals-implementations from the sub-classes ReadingBook and LearningBook should somewhere call super.equals() - the equals-implementation of Book.

Object equality, Any class that contains an abstract method must be declared abstract. We have seen the need to use the equals method to compare two objects. two variables of the same primitive type, it is easy for Java to decide whether they are equal:  The java.lang.Object.equals(Object obj) indicates whether some other object is "equal to" this one. The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).

You can ask the book instance for its class and check class equality.

book1.getClass().equals(book2.getClass())

Object-Oriented Analysis, Design and Implementation: An Integrated , Any class that contains an abstract method must be declared abstract. We have seen the need to use the equals method to compare two objects. Given any two variables of the same primitive type, it is easy for Java to decide The language specifies that two objects are equal if they occupy the same physical storage. If the two objects have the same values, equals() will return true. In the second comparison, equals()checks to see whether the passed object is null, or if it’s typed as a different class. If it’s a different class then the objects are not equal. Finally, equals() compares the objects’ fields. If two objects have the same field values, then the objects are the same.

You can use instanceof method to compare the type of the Object. To check if it is a type of LearningBook or ReadingBook example

Answer for your comment,

Lets say when you check the two instance it says they are different, then there is no issue you can return false. But if the instances are also same then you can check it with something like this after that

if (both instances are same) {
  if (yourObjectIs instanceof LearningBook) {
    you can check the two values of LearningBook here and return true if the are equals
  } else {
    you can check the two values of ReadingBook here and return true if the are equals
  }
}

Object-Oriented Analysis and Design, the same values for its instance variables. For example, you might consider two Person objects equal if their social security number is the same. Depending on the class, there might be different possible ways to check for equality, so the purposes of Abstract Classes and Methods Abstract classes cannot be instantiated. Same-value equality is provided by the Object.is method. Same-value-zero equality. Similar to same-value equality, but +0 and -0 are considered equal. Abstract equality, strict equality, and same value in the specification. In ES5, the comparison performed by == is described in Section 11.9.3, The Abstract Equality Algorithm.

As it was mentioned you should overwrite equals(Object object) method. In your example you can do it like this:

    public abstract class Book{
    @NonNull protected String name;
    @NonNull protected String author;

    public Book(String name, String author) {
        this.name = name;
        this.author = author;
    }

    @Override
    public boolean equals(Object object) {
        if (object instanceof Book) {
            var book = (Book) object;
            return this.name.equals(book.name) && this.author.equals(book.author);
        } else
            return false;
    }
}

public class LearningBook extends Book{
    @NonNull private String subject;

    public LearningBook(String name, String author,String subject) {
        super(name, author);
        this.subject = subject;
    }

    @Override
    public boolean equals(Object object) {
        if (object instanceof LearningBook) {
            var book = (LearningBook) object;
            return this.subject.equals(book.subject) && super.equals(book);
        } else
            return false;
    }
}

public class ReadingBook extends Book{
    @NonNull private int numberOfPages;

    public ReadingBook(String name, String author,int numberOfPages) {
        super(name, author);
        this.numberOfPages = numberOfPages;
    }

    @Override
    public boolean equals(Object object) {
        if (object instanceof ReadingBook) {
            var book = (ReadingBook) object;
            return super.equals(book) && this.numberOfPages == book.numberOfPages;
        } else
            return false;
    }
}

I've used @NonNull annotation to avoid NPE in equals method.

Beginning Java Programming: The Object-Oriented Approach, We can override the equals method in our class to check whether two objects have same data or not. filter_none. edit close. play_arrow. link brightness_4 code​  For example java.lang.String class overrides the equals() and hashcode method and in the overridden method, it will check that two string contains same value or character if yes then they are equals otherwise not equal.

Overriding equals method in Java, For example, java.util.Random could have overridden equals to check whether two Random instances would produce the same sequence of random numbers Note that you can add an aspect to a subclass of an abstract class without vio-. Here's an example of two items that implement our own IWeapon<T> interface, which in turn extends the IEquatable<T> interface. Implement the one, and you get the other for free. public class Sword : IWeapon<Sword> { public enum SwordLevel { Fighter, Master, Tempered, Golden } public SwordLevel Strength { get; set; } public bool Equals(Sword other) { return Strength == other ?.

[PDF] Chapter 3: Methods Common to All Objects, FunSuite class PersonTests extends FunSuite { // these first two instances The first thing to know about Scala and the equals method is that, unlike Java, you This code uses the same approach to the canEqual , equals , and hashCode  In simple words, == checks if both objects point to the same memory location whereas .equals() evaluates to the comparison of values in the objects. If a class does not override the equals method , then by default it uses equals(Object o) method of the closest parent class that has overridden this method.

4.15. Defining an equals Method (Object Equality), public abstract class Expression; extends java.lang. Two different expressions can have exactly the same expression string but Overrides: equals in class java.lang.Object. Parameters: obj - the Object to test for equality. Object) method on how two expressions can be equal if their expression Strings are different. Do you want to check that these two things are the exact same instance? Then you can use JavaScript's built-in equality operators. Or do you want to check that these two objects are the "same value?" If that's the case, then you'll need to do a bit more work. Here is a very basic approach to checking an object's "value equality".

Comments
  • I'd firstly suggest reading on object equality in Java (see here for API, but you probably want to broaden the search to concepts/tutorials). Also note that if you correctly override hashCode and equals, you can use Sets to automatically maintain duplicate-free collections.
  • You can add obj1.getClass().equals(obj2.getClass()) to the method that checks the books for equality. This condition is true only if both books are instances of the same subclass. May be a dupe of this.
  • Try using something like: if(book instanceof ReadingBook ) condition in your eqauls method, then cast it to the appropriate type if its true.
  • I've tried it, but since the "sameBookCheck" method gets 'Book' objects, the isEqual method runs from the 'Book' class and not from the LearningBook or ReadingBook
  • But I also need to compare between the specific variable of the subclasses ('subject' for LearningBook and 'numberOfPages' for ReadingBook).
  • You are writing a method for this correct? Then if the type of those two objects are not equals you can return fasle. Else if the types are same, you can extend your methods to check the specific variables also. I'll add a example to my answer