-1

I am currently revising for an upcoming exam and I'm confident in saying that I will most likely get a question that will require me to implement equals method, compareTo method and hashCode method. It is open book therefore I want to try and take full advantage of this because I think it could be especially useful for this area. For example, I managed to implement the compareTo method by following someone elses code and then adjusting it, I want this advantage in the exam as others will = )

Anyway, I have a sample exam question given to us and it asks us exactly this. I'm attempting to implement the equals method whilst using other peoples code as examples because I will be taking these in with me as a template in case they do show up, since it is allowed. However, the equals method doesn't seem as easy to implement through a template as the compareTo. I have attempted it but it doesn't seem to be going great =D I was hoping you guys could help me out on where I'm going wrong, I think although I'm not certain it could be possibly my If statement. Finally, if you have any tips for any of the methods above in an open book exam then I'll extremely appreciate it! As I'm really worried/uncertain whether or not I'll pass = )

Anyway I have been given the following code :

public class Books {

  private final String title;
  private final String author;
  private final int edition;

  public Books(String title, String author, int edition)
  {
      this.title = title;
      this.author = author;
      this.edition = edition;
  }

  public String getTitle(){
      return title;
  }
  public String getAuthor(){
      return author;
  }
  public int getEdition(){
      return edition;
  }

With this code I'm to implement the equals method and here's the attempt I made at doing it whilst following someone elses.

public boolean equals(Object obj){
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if(getClass() != obj.getClass())
    return false;
    Books other = (Books) obj;
    if (getTitle() == null){
        if (other.getTitle() != null)
            return false;
    }

    else if
        (!getTitle().equals(other.getTitle()))
    return false;
    return true;

    else if (getAuthor() == null){
        if (other.getAuthor() != null)
            return false;
    }

    else if 
        (!getAuthor().equals(other.getAuthor()))
    return false;
    return true;

    if (getEdition() != other.getEdition())
        return false;


        } 

I know I've pretty much screwed how the if statement flows, I struggled to follow it through nicely as it's grown =/

AstroCB
  • 12,337
  • 20
  • 57
  • 73
  • Not sure why you would implement equals manually. Eclipse can do this for you `Source->Generate hashCode() and equals()...` – Jeff Ward Apr 13 '14 at 20:18
  • It's in an exam so I can't do that = ( – user3443834 Apr 13 '14 at 20:21
  • Seems like an odd exam question since likely every IDE has a similar helper. My recommendation would be to study the equals produced by an IDE like eclipse and understand the logical breakdown of how it is comparing the object. – Jeff Ward Apr 13 '14 at 20:25
  • 1
    Does this answer your question? [How to override equals method in Java](https://stackoverflow.com/questions/8180430/how-to-override-equals-method-in-java) – Petter Friberg Dec 16 '20 at 20:59

3 Answers3

1

Assuming we are using Java 15 (with all the preview stuff activated), my implementation would look like this:

public boolean equals( Object obj )
{
    var retValue = this == obj;
    if( !retValue && (obj instanceof Book other) && (getClass() == obj.getClass()) )
    {
        retValue = Objects.equals( getTitle(), other.getTitle() );
        retValue &= Objects.equals( getAuthor(), other.getAuthor() );
        retValue &= getEdition() == other.getEdition();
     }

    return retValue;
}

If the class Book is final, the check … && (getClass() == obj.getClass()) could be omitted without a different result (until someone changes that and extends Book to Atlas – without that check, an Atlas could be equal to a Book, but no Book could be equal to any Atlas. This would hurt the requirement that any implementation of Object.equals() needs to be symmetric).

And of course, the retValue &= … constructs could be replaced by mere … && ….


Funny thing: the Java Collection Classes do not check the class:

List<String> a = new ArrayList<>();
List<String> l = new LinkedList<>();
List<String> e = Collections.emptyList();

out.println( a.equals( l ) ); // true
out.println( a.equals( e ) ); // true
out.println( l.equals( a ) ); // true
out.println( l.equals( e ) ); // true
out.println( e.equals( a ) ); // true
out.println( e.equals( l ) ); // true

e.getClass().getName() will return (for Java 15) java.util.Collections$EmptyList. So symmetry does not necessarily require that both objects do have the same implementation.

For java.util.List this is even mentioned in the documentation: "[…]two lists are defined to be equal if they contain the same elements in the same order."

tquadrat
  • 3,033
  • 1
  • 16
  • 29
0

This is what Eclipse produced for that class:

@Override
public boolean equals(Object obj) {
   if (this == obj)
      return true;
   if (obj == null)
      return false;
   if (getClass() != obj.getClass())
      return false;
   Books other = (Books) obj;
   if (author == null) {
      if (other.author != null)
         return false;
   } else if (!author.equals(other.author))
      return false;
   if (edition != other.edition)
      return false;
   if (title == null) {
      if (other.title != null)
         return false;
   } else if (!title.equals(other.title))
      return false;
   return true;
}
Jeff Ward
  • 1,109
  • 6
  • 17
0

to override user object specific equals method usually we should do following, my comments in line

@Override
    public boolean equals(Object obj) {
        //check if object received is not null
        if (obj == null) {
            return false;
        }
        //check if the object received is of the same class
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Beta other = (Beta) obj;
        //compare all properties of the class and return true based on oure requirement
        if ((this.getSample() == null) && (other.getSample() == null)){
            return true;
        }
        if ((this.getSample().getId().equals(other.getSample().getId())) && (this.getSample().getName().equals(other.getSample().getName()))) {
            return true;
        }
        //if nothing suits well based on our requirement we can directly send false or handle the responsibility of comparison to super class
        return super.equals();
    }
dev2d
  • 4,245
  • 3
  • 31
  • 54
  • There was a [suggested edit](https://stackoverflow.com/review/suggested-edits/27861886) to your post. It was rejected. Kindly check if you agree that this addition to your method should not be part of your code. – Scratte Dec 16 '20 at 20:30