07 August, 2011

How to generate equals(), hashCode(), toString() and compareTo() using Apache Commons Lang in Eclipse

Apache Commons project represents a set of reusable Java components. Apache Commons Lang is one of the Apache Commons components. It provides much needed additions to the standard JDK's java.lang package. One of its packages, org.apache.commons.lang3.builder contains a set of very useful builders that helps in creating consistent equals(), hashCode(), toString() and compareTo() methods.

In this post, I will show how to generate equals(), hashCode(), toString() and compareTo() methods using Apache Commons Lang builders in Eclipse. For demonstrations I will use the latest stable release - Apache Commons Lang 3.0. Note that Lang 3.0 uses a different package (org.apache.commons.lang3) than its predecessors (org.apache.commons.lang). All the examples presented in this post will work also with the previous Apache Commons Lang releases; just change the package name from lang3 to lang.

Native Support

Eclipse supports out of the box generation of equals(), hashCode() and toString() methods. But only the generation of toString() can be configured to use different builders. Below is shown how to configure Eclipse to use ToStringBuilder to generate toString() methods.

Prerequisites: Eclipse project is configured to include Apache Commons Lang jar in classpath. We have a class with 2 fields named string and number.

  1. Open Generate toString() wizard (from menu select Source -> Generate toString()…).
  2. Choose Custom toString() builder option from Code Style drop down and press Configure… button as it is shown below.
    Eclipse generate toString()
  3. Using Browse… button select org.apache.commons.lang3.builder.ToStringBuilder as Builder Class and press OK.
    Eclipse generate toString() with custom builder
  4. Press OK.
  5. Eclipse will generate the toString() method. It should look similar to this one:
    @Override
    public String toString() {
        ToStringBuilder builder = new ToStringBuilder(this);
        builder.append("string", string);
        builder.append("number", number);
        return builder.toString();
    }
    
  6. Eclipse will save your settings, so next time you will not have to repeat these steps again. Just open Generate toString() wizard and hit OK.

Custom Templates

As I mentioned earlier, only toString() generation can be customized in Eclipse. Still, we can configure Eclipse to generate equals(), hashCode() and compareTo() using Apache Commons Lang builders by using Eclipse templates.

Templates are little pieces of code with defined placeholders. Each template has a name, which serves as a shortcut to the template itself. You type the name, press CTRL + SPACE and it will be expanded. In order to access Eclipse templates open Window -> Preferences and select Java -> Editor -> Templates. Now you can create new templates, edit existing ones or import directly ready templates.

Eclipse Preferences - Java Templates

Following is a list of templates that will allow you to generate equals(), hashCode(), compareTo() and even toString() using Apache Commons Lang builders.

  • hashCode() template
    @Override
    public int hashCode() {
        ${builderType:newType(org.apache.commons.lang3.builder.HashCodeBuilder)}
            ${builder:newName(builderType)} = new ${builderType}();
        ${builder}.append(${field});${cursor}
        return ${builder}.toHashCode();
    }
    
    This is how it will look like in Eclipse:
    Eclipse Preferences - Java hashCode() template
  • equals() template
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof ${enclosing_type})) {
            return false;
        }
        ${enclosing_type} other = (${enclosing_type}) obj;
        ${builderType:newType(org.apache.commons.lang3.builder.EqualsBuilder)}
            ${builder:newName(builderType)} = new ${builderType}();
        ${builder}.append(${field}, other.${field});${cursor}
        return ${builder}.isEquals();
    }
    
  • compareTo() template
    @Override
    public int compareTo(${enclosing_type} o) {
        ${builderType:newType(org.apache.commons.lang3.builder.CompareToBuilder)}
            ${builder:newName(builderType)} = new ${builderType}();
        ${builder}.append(${field}, o.${field});${cursor}
        return ${builder}.toComparison();
    }
    
  • toString() template
    @Override
    public String toString() {
      ${builderType:newType(org.apache.commons.lang3.builder.ToStringBuilder)}
        ${builder:newName(builderType)} = new ${builderType}(this,
          ${:newType(org.apache.commons.lang3.builder.ToStringStyle)}.${DEFAULT_STYLE});
      ${builder}.append("${field}", ${field});${cursor}
      return ${builder}.toString();
    }
    

Also you can easily import all the above templates using Import… button from the following file eclipse-templates-apache-commons.xml.

After you defined the templates, you can start using them through Content Assist (CTRL + SPACE). Start typing the name of template in editor and then press CTRL + SPACE. Choose the required template and press ENTER.

Eclipse Content Assist with hashCode() template

Customize the variables names and fields that should be included in the builder. Append more fields if it’s required. You have to get at the end something like this:

@Override
public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();
    builder.append(number);
    builder.append(string);
    return builder.toHashCode();
}

End.

3 comments:

  1. Help! I followed your pattern, but the field is not automatically populated, why?
    Thanks!

    ReplyDelete
  2. บริการ สล็อต slot ด้วยระบบเกมใหม่ปัจจุบันของพวกเรา ได้ปรับปรุงแก้ไขให้มีความเสถียรภาพมากยิ่งขึ้น PG SLOT เล่นสล็อตผ่านมือถือ ก็ไม่มีหลุด เล่นได้ทุกระบบปฏิบัติการ จะเล่นโทรศัพท์มือถือเครื่องไหน คอมจำพวกใด

    ReplyDelete