Bug 167304 - [hashcode/equals] Suggestion for shorter Equals
Summary: [hashcode/equals] Suggestion for shorter Equals
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.2.1   Edit
Hardware: PC Linux
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-12-08 18:13 EST by William Voorsluys CLA
Modified: 2007-06-14 10:43 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description William Voorsluys CLA 2006-12-08 18:13:08 EST
I've been using the "Generate equals and hashCode" feature of Eclipse. I consider it very usefull except for the fact that it generates a too long equals method.
On some of my code, I've changed some comparisons to get shorter equals  methods with same functionality. On a class with 3 Object fields, it is possible to generate a 20 lines shorter equals, using comparison expressions. Like this:

public class AnyClass {

    private Object field1;
    private Object field2;
    private Object field3;

    public boolean equals( Object obj ) {

        if ( this == obj )
            return true;
        if ( obj == null )
            return false;
        if ( getClass() != obj.getClass() )
            return false;
        final AnyClass other = (AnyClass) obj;
        if ( !(this.field1 == null ? other.field1 == null : this.field1.equals( other.field1 )) )
            return false;
        if ( !(this.field2 == null ? other.field2 == null : this.field2.equals( other.field2 )) )
            return false;
        if ( !(this.field3 == null ? other.field3 == null : this.field3.equals( other.field3 )) )
            return false;
        return true;
    }
}

In constrast to the equals generated by Eclipse:


    public boolean equals( Object obj ) {

        if ( this == obj )
            return true;
        if ( obj == null )
            return false;
        if ( getClass() != obj.getClass() )
            return false;
        final AnyClass other = (AnyClass) obj;
        if ( this.field1 == null ) {
            if ( other.field1 != null )
                return false;
        } else if ( !this.field1.equals( other.field1 ) )
            return false;
        if ( this.field2 == null ) {
            if ( other.field2 != null )
                return false;
        } else if ( !this.field2.equals( other.field2 ) )
            return false;
        if ( this.field3 == null ) {
            if ( other.field3 != null )
                return false;
        } else if ( !this.field3.equals( other.field3 ) )
            return false;
        return true;
    }

Certainly, some programmers do not like those expressions, as it may make the code harder to read. So, even this enhancement could be a "Clean Up" or an option when generating Equals, not necessarily the default implementation.
Comment 1 Olivier Thomann CLA 2006-12-08 23:16:42 EST
Moving to JDT/UI
Comment 2 Alex Blewitt CLA 2006-12-10 04:54:03 EST
You can make it even shorter than that using a collection of 'and' combinators:

AnyClass other = (obj instanceof AnyClass ? (AnyClass)obj : null );
return
  this == obj ||
  (
    obj != null &&
    getClass() == obj.getClass() &&
    !(this.field1 == null ? other.field1 == null : this.field1(equals(other.field1)) &&
    !(this.field2 == null ? other.field2 == null : this.field2(equals(other.field2)) &&
  );

i'm not sure how either the formatter would handle this, or the average programmer reading it, either. It would also be interesting to see (from a compiled approach) which one is better, or whether it makes any significant difference..

Alex.