Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing two instances of class having big number of attributes

Tags:

java

hash

equals

I have a class having more than 30 attributes.

I want to override the equals method in order to compare two instance of my class.

However I want to avoid re-write all the 30 attributes in my method as this

@Override
public boolean equals(java.lang.Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    Address address = (Address) o;
    return Objects.equals(this.attr1, address.attr1) &&
            Objects.equals(this.attr2, address.attr2) &&
            Objects.equals(this.attr3, address.attr3) &&
            ......
            Objects.equals(this.attr30, address.attr30);

}

Have you a more simple and proper way ?

like image 571
Mohamed Taboubi Avatar asked Jan 03 '23 13:01

Mohamed Taboubi


1 Answers

Well, this is basically the type of boilerplate code that is necessary. Luckily, there are lots of developers just as annoyed of writing such code as you are. For reasons like that, Project Lombok was founded.

Please see this link.

As an example, see the following two code snippets extracted from the page that I linked above:

Lombok

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(exclude={"id", "shape"})
public class EqualsAndHashCodeExample {
  private transient int transientVar = 10;
  private String name;
  private double score;
  private Shape shape = new Square(5, 10);
  private String[] tags;
  private int id;

  public String getName() {
    return this.name;
  }

  @EqualsAndHashCode(callSuper=true)
  public static class Square extends Shape {
    private final int width, height;

    public Square(int width, int height) {
      this.width = width;
      this.height = height;
    }
  }
}

Vanilla Java

import java.util.Arrays;

public class EqualsAndHashCodeExample {
  private transient int transientVar = 10;
  private String name;
  private double score;
  private Shape shape = new Square(5, 10);
  private String[] tags;
  private int id;

  public String getName() {
    return this.name;
  }

  @Override public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof EqualsAndHashCodeExample)) return false;
    EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;
    if (!other.canEqual((Object)this)) return false;
    if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
    if (Double.compare(this.score, other.score) != 0) return false;
    if (!Arrays.deepEquals(this.tags, other.tags)) return false;
    return true;
  }

  @Override public int hashCode() {
    final int PRIME = 59;
    int result = 1;
    final long temp1 = Double.doubleToLongBits(this.score);
    result = (result*PRIME) + (this.name == null ? 43 : this.name.hashCode());
    result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
    result = (result*PRIME) + Arrays.deepHashCode(this.tags);
    return result;
  }

  protected boolean canEqual(Object other) {
    return other instanceof EqualsAndHashCodeExample;
  }

  public static class Square extends Shape {
    private final int width, height;

    public Square(int width, int height) {
      this.width = width;
      this.height = height;
    }

    @Override public boolean equals(Object o) {
      if (o == this) return true;
      if (!(o instanceof Square)) return false;
      Square other = (Square) o;
      if (!other.canEqual((Object)this)) return false;
      if (!super.equals(o)) return false;
      if (this.width != other.width) return false;
      if (this.height != other.height) return false;
      return true;
    }

    @Override public int hashCode() {
      final int PRIME = 59;
      int result = 1;
      result = (result*PRIME) + super.hashCode();
      result = (result*PRIME) + this.width;
      result = (result*PRIME) + this.height;
      return result;
    }

    protected boolean canEqual(Object other) {
      return other instanceof Square;
    }
  }
}

If you like this approach, I'd recommend checking out Project Lombok in its entirety. It really helps cleaning up your code!

!!! Beware !!! In order to be able to actually use methods generated by Lombok, you need to install the Lombok plugin into your IDE! Otherwise, your IDE won't know of the automatically generated methods.

like image 80
Archivar Avatar answered Jan 13 '23 11:01

Archivar