Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

equals/hashCode for IJExpressions #20

Closed
leventov opened this issue Sep 19, 2014 · 5 comments
Closed

equals/hashCode for IJExpressions #20

leventov opened this issue Sep 19, 2014 · 5 comments

Comments

@leventov
Copy link
Contributor

Seems that implementing equals() and hashCode() methods for IJExpression subclasses is an absolute requirement for starting any analysis (#18). What way of implementing this do you prefer for the lib? Some particular auto generation utility, such as from Apache Commons, or Lombok, or Google's auto-value? Generating from Eclipse/Intellij? Or writing by hand?

(Of cause I would be very grateful if you implement this, but if don't want to, I will be forced to do it myself, and will try to accout your advice.)

@phax
Copy link
Owner

phax commented Sep 19, 2014

This is a very good question - I would not like to add additional libraries for this, so we will stick with "write by hand" :)
But I do have a simple "HashCodeGenerator" in one of my other projects, which I would like to reuse. It is checked into the "util" package.

Example for a class with base class Object:

@Override
 public int hashCode ()
 {
   return new HashCodeGenerator (this).append (member1).append (member2).getHashCode ();
 }

Example for a class which is derived from a class different than Object:

@Override
 public int hashCode ()
 {
   return HashCodeGenerator.getDerived (super.hashCode ()).append (member3).append (member4).getHashCode ();
 }

Concerning equals, I don't have a real helper because there are four different versions of equals required, depending on the scope of the class:

  1. class is not final and it's base class is Object
  2. class is final and it's base class is Object
  3. class who's base class is NOT Object

Here are the examples for all cases:

public class Case1 {
  private String s;
  private int i;
  public boolean equals (Object o) {
    // always the first clause
    if (o == this)
     return true;
    // Parameter is null or from a different implementation class
    if (o == null || !getClass ().equals (o.getClass ()))
      return false;
    // Same class and parameter not null - start comparing
    Case1 rhs = (Case1) o;
    return EqualsUtils.equals (s, rhs.s) && EqualsUtils.equals(i, rhs.i);
  }
}
public final class Case2 {
  String s;
  int i;
  public boolean equals (Object o) {
    // always the first clause
    if (o == this)
     return true;
    // Parameter is null or from a different implementation class
    // Theoretically the line from Case1 could also be used here, but I think this is more readable
    if (!(o instanceof Case2))
      return false;
    // Same class and parameter not null - start comparing
    Case2 rhs = (Case2) o;
    return EqualsUtils.equals (s, rhs.s) && EqualsUtils.equals(i, rhs.i);
  }
}
public class Case3 extends Case1 {
  private int x;
  public boolean equals (Object o) {
    // always the first clause
    if (o == this)
     return true;
    // Parameter is null or from a different implementation class
    if (!super.equals (o))
      return false;
    // Same class and parameter not null - start comparing
    Case3 rhs = (Case3) o;
    return EqualsUtils.equals (s, rhs.s) && EqualsUtils.equals(i, rhs.i);
  }
}

So it can be drilled down to Case1 and Case3 if you want.
Btw. EqualsUtils is a small utility class in the util package, that performs null-safe-equals.

Do you think this is reasonable?

@leventov
Copy link
Contributor Author

equals static methods would better have a different name, not colliding with Object.equals() to allow static import.

Could you also provide a method accepting varargs to compute hashCode? For example HashCodeGenerator.hashCode(Object srcObject, Object... members) and HashCodeGenerator.hashCode(int superHashCode, Object... members)

@phax
Copy link
Owner

phax commented Sep 20, 2014

I would go for isEqual - does that sound reasonable?

Concerning hashCode: I personally totally dislike the boxing concept, but I see the added value on this. So I will do it on Monday as you suggested.

On 20. September 2014 08:06:15 MESZ, Roman Leventov notifications@github.com wrote:

equals static methods would better have a different name, not
colliding with Object.equals() to allow static import.

Could you also provide a method accepting varargs to compute hashCode?
For example HashCodeGenerator.hashCode(Object srcObject, Object... members) and HashCodeGenerator.hashCode(int superHashCode, Object... members)


Reply to this email directly or view it on GitHub:
#20 (comment)

Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail gesendet.

@leventov
Copy link
Contributor Author

Yes, that's ok.

Thank you, I won't start implementing anything until monday, too.

@phax
Copy link
Owner

phax commented Sep 22, 2014

All done. Additionally the isEqual(Object,Object) method was extended for arrays :)

leventov added a commit to leventov/jcodemodel that referenced this issue Oct 6, 2014
leventov added a commit to leventov/jcodemodel that referenced this issue Oct 6, 2014
@phax phax closed this as completed Aug 29, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants