cancel
Showing results for 
Search instead for 
Did you mean: 

Override java.lang.Object.equals in this class what happens

Former Member
0 Kudos

Hi friends,

below is the class :

public class Simple {

private int digits;

private String text;

public Simple(int i, String s) {

digits = i;

text = s;

}

let me know the answer , urgent.

rgards,

roberts.k

Accepted Solutions (0)

Answers (2)

Answers (2)

Vlado
Advisor
Advisor
0 Kudos

Hi Roberts,

Are you asking how to implement the <b>equals</b> method for this class? If that is your question, consider the following:

public boolean equals(Object another) {
  if (another == null || !(another instanceof Simple)) {
    return false;
  }
  
  Simple s = (Simple) another;
  
  if (this.digits != s.digits) {
    return false;
  }
  
  if (this.date == null) {
    if (s.date != null) {
      return false;
    } else {
      return true;
    }
  } else {
    return this.date.equals(s.date);
  }
}

Best regards,

Vladimir

Former Member
0 Kudos

Sorry Vladimir,

but it's quite weak implementation that breaks number of Java contracts, for details see

http://www.javaworld.com/javaworld/jw-01-1999/jw-01-object-p2.html or "Effective Java Programming" by Joshua Bloch.

Also check

if (another == null || !(another instanceof Simple))

is redundant while

another instanceof Simple

cover NULL case.

VS

Vlado
Advisor
Advisor
0 Kudos

Sorry VS,

but I cannot agree with you here. Considered Roberts' class and my suggestion for the <b>equals</b> method implementation, I still affirm that it <u><b>does not break any of the contracts!</b></u> Could you please be so kind to tell me precisely which of the contracts are broken?

The only possible pitfall is if this <b>Simple</b> class is subclassed. Then <b>getClass()</b> should be used instead of <b>instanceof</b> to prevent equality of parent and child class objects and also provide for symmetric and transitive implementation.

And finally, there's one more optimization that could be added, namely to check <b>if (another == this)</b> in the very first step.

So, in conclusion the code should look like this:

public boolean equals(Object another) {
  if (another == this) {
    return true;
  }
  
  if (another == null || !(another.getClass().equals(this.getClass()))) {
    return false;
  }
  
  Simple s = (Simple) another;
  
  if (this.digits != s.digits) {
    return false;
  }
  
  if (this.date == null) {
    if (s.date != null) {
      return false;
    } else {
      return true;
    }
  } else {
    return this.date.equals(s.date);
  }
}

Best regards,

Vladimir

Former Member
0 Kudos

Vladimir,

sub-classing is exactly what I mean: it high risk to break symmetry with sub-class if equals implemented as you originally suggested.

Also, I cann't help but provide yet another optimization :

instead !(o1.getClass().equals(o2.getClass())) it is safe to use o1.getClass() != o2.getClass() while there is only one instance of particular Class per ClassLoader.

VS

Vlado
Advisor
Advisor
0 Kudos

> Vladimir,

> sub-classing is exactly what I mean: it high risk to

> break symmetry with sub-class if equals implemented

> as you originally suggested.

OK, then there's no need for you to exaggerate with "quite weak" and "breaks number of contracts".

> Also, I cann't help but provide yet another

> optimization :

> instead !(o1.getClass().equals(o2.getClass())) it is

> safe to use o1.getClass() != o2.getClass() while

> there is only one instance of particular Class per

> ClassLoader.

Since java.lang.Class doesn't override the equals method and o1.getClass().equals(o2.getClass()) merely returns o1.getClass() == o2.getClass(), this couldn't be quite an optimization.

Best regards,

Vladimir

Former Member
0 Kudos

Well,

1. A bit exaggerated, but if you break symmetry, you break transitivity as well. So at least 2 rules.

2. I do not mean performance optimization in any way, just amount of code to type and readability.

VS

P.S. Heck, the first flame war on SDN??? ))

Former Member
0 Kudos

Hi Roberts,

In this class you have defined 2 private instance variables and you defined a constructor which takes 2 parameters and initializes those 2 instance variables by assigning the parameter of same data type.

When you will create a instance, you will call the constructor and then you have to pass 2 parameters and then the instance variables will be initialized.

Since you have written the constructor , and you have not written the default constructor, you can not call the default constructor to initialize an instance.