DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
11 Monitoring and Observability Tools for 2023
Learn more
  1. DZone
  2. Coding
  3. Languages
  4. Guava's Objects Class: Equals, HashCode, and ToString

Guava's Objects Class: Equals, HashCode, and ToString

Dustin Marx user avatar by
Dustin Marx
·
Jan. 04, 12 · Interview
Like (1)
Save
Tweet
Share
7.96K Views

Join the DZone community and get the full member experience.

Join For Free

If you are fortunate enough to be using JDK 7, the newly available Objects class is the obvious (at least to me) choice for implementing the "common" Java object methods such as equals(Object) [with Objects.equals(Object,Object)], hashCode() [with Objects.hashCode(Object) or Objects.hash(Object...)], and toString() [with Objects.toString(Object)] to appropriately override the default Object implementations. I have written posts about using Objects class: JDK 7: The New Objects Class and Java 7 Objects-Powered Compact Equals.

If you're not yet using Java 7, your best choices might be the Apache Commons builders ToStringBuilder and EqualsBuilder and HashCodeBuilder (if you're using a version of Java prior to J2SE 5) or Guava (if you're using J2SE 5 or later). In this post, I look at using Guava's Objects class to implement the three common methods equals, hashCode, and toString().

Without Guava or other library to help, the three common methods discussed in this post are often highlighted as shown in the next code listing. These methods were generated with NetBeans 7.1 beta.

TraditionalEmployee
package dustin.examples;

import java.util.Calendar;

/**
 * Simple employee class using NetBeans-generated 'common' methods
 * implementations that are typical of many such implementations created
 * without Guava or other library.
 * 
 * @author Dustin
 */
public class TraditionalEmployee
{
   public enum Gender{ FEMALE, MALE };

   private final String lastName;
   private final String firstName;
   private final String employerName;
   private final Gender gender;

   /**
    * Create an instance of me.
    * 
    * @param newLastName The new last name my instance will have.
    * @param newFirstName The new first name my instance will have.
    * @param newEmployerName The employer name my instance will have.
    * @param newGender The gender of my instance.
    */
   public TraditionalEmployee(
      final String newLastName, final String newFirstName,
      final String newEmployerName, final Gender newGender)
   {
      this.lastName = newLastName;
      this.firstName = newFirstName;
      this.employerName = newEmployerName;
      this.gender = newGender;
   }

   public String getEmployerName()
   {
      return this.employerName;
   }

   public String getFirstName()
   {
      return this.firstName;
   }

   public Gender getGender()
   {
      return this.gender;
   }

   public String getLastName()
   {
      return this.lastName;
   }

   /**
    * NetBeans-generated method that compares provided object to me for equality.
    * 
    * @param obj Object to be compared to me for equality.
    * @return {@code true} if provided object is considered equal to me or
    *    {@code false} if provided object is not considered equal to me.
    */
   @Override
   public boolean equals(Object obj)
   {
      if (obj == null)
      {
         return false;
      }
      if (getClass() != obj.getClass())
      {
         return false;
      }
      final TraditionalEmployee other = (TraditionalEmployee) obj;
      if ((this.lastName == null) ? (other.lastName != null) : !this.lastName.equals(other.lastName))
      {
         return false;
      }
      if ((this.firstName == null) ? (other.firstName != null) : !this.firstName.equals(other.firstName))
      {
         return false;
      }
      if ((this.employerName == null) ? (other.employerName != null) : !this.employerName.equals(other.employerName))
      {
         return false;
      }
      if (this.gender != other.gender)
      {
         return false;
      }
      return true;
   }

   /**
    * NetBeans-generated method that provides hash code of this employee instance.
    * 
    * @return My hash code.
    */
   @Override
   public int hashCode()
   {
      int hash = 3;
      hash = 19 * hash + (this.lastName != null ? this.lastName.hashCode() : 0);
      hash = 19 * hash + (this.firstName != null ? this.firstName.hashCode() : 0);
      hash = 19 * hash + (this.employerName != null ? this.employerName.hashCode() : 0);
      hash = 19 * hash + (this.gender != null ? this.gender.hashCode() : 0);
      return hash;
   }

   /**
    * NetBeans-generated method that provides String representation of employee
    * instance.
    * 
    * @return My String representation.
    */
   @Override
   public String toString()
   {
      return  "TraditionalEmployee{" + "lastName=" + lastName + ", firstName=" + firstName
            + ", employerName=" + employerName + ", gender=" + gender +  '}';
   }
}

Although NetBeans 7.1 beta did the heavy lifting here, this code still must be maintained and can be made more readable. The next class is the same class, but with Guava-powered common methods instead of the NetBeans-generated 'typical' implementations shown above.

GuavaEmployee
package dustin.examples;

/**
 * Simple employee class using Guava-powered 'common' methods implementations.
 * 
 * I explicitly scope the com.google.common.base.Objects class here to avoid the
 * inherent name collision with the java.util.Objects class.
 * 
 * @author Dustin
 */
public class GuavaEmployee
{
   public enum Gender{ FEMALE, MALE };

   private final String lastName;
   private final String firstName;
   private final String employerName;
   private final TraditionalEmployee.Gender gender;

   /**
    * Create an instance of me.
    * 
    * @param newLastName The new last name my instance will have.
    * @param newFirstName The new first name my instance will have.
    * @param newEmployerName The employer name my instance will have.
    * @param newGender The gender of my instance.
    */
   public GuavaEmployee(
      final String newLastName, final String newFirstName,
      final String newEmployerName, final TraditionalEmployee.Gender newGender)
   {
      this.lastName = newLastName;
      this.firstName = newFirstName;
      this.employerName = newEmployerName;
      this.gender = newGender;
   }

   public String getEmployerName()
   {
      return this.employerName;
   }

   public String getFirstName()
   {
      return this.firstName;
   }

   public TraditionalEmployee.Gender getGender()
   {
      return this.gender;
   }

   public String getLastName()
   {
      return this.lastName;
   }

   /**
    * Using Guava to compare provided object to me for equality.
    * 
    * @param obj Object to be compared to me for equality.
    * @return {@code true} if provided object is considered equal to me or
    *    {@code false} if provided object is not considered equal to me.
    */
   @Override
   public boolean equals(Object obj)
   {
      if (obj == null)
      {
         return false;
      }
      if (getClass() != obj.getClass())
      {
         return false;
      }
      final GuavaEmployee other = (GuavaEmployee) obj;
      
      return   com.google.common.base.Objects.equal(this.lastName, other.lastName)
            && com.google.common.base.Objects.equal(this.firstName, other.firstName)
            && com.google.common.base.Objects.equal(this.employerName, other.employerName)
            && com.google.common.base.Objects.equal(this.gender, other.gender);
   }

   /**
    * Uses Guava to assist in providing hash code of this employee instance.
    * 
    * @return My hash code.
    */
   @Override
   public int hashCode()
   {
      return com.google.common.base.Objects.hashCode(
                this.lastName, this.firstName, this.employerName, this.gender);
   }

   /**
    * Method using Guava to provide String representation of this employee
    * instance.
    * 
    * @return My String representation.
    */
   @Override
   public String toString()
   {
      return com.google.common.base.Objects.toStringHelper(this)
                .addValue(this.lastName)
                .addValue(this.firstName)
                .addValue(this.employerName)
                .addValue(this.gender)
                .toString();
   }
}

As the code above proves, the use of Guava improves the readability of the implementations of the three common methods. The only thing that's not so nice is the need to explicitly scope Guava's Objects class in the code to avoid a naming collision with Java SE 7's Objects class. Of course, if one is not using Java 7, then this is not an issue and if one is using Java 7, it's most likely that the standard version should be used instead anyway.

Conclusion

Guava provides a nice approach for building safer and more readable common methods via its Objects class. Although I'll use the new java.util.Objects class instead for JDK 7 projects, Guava's com.google.common.base.Objects class provides a nice alternative for working in versions of Java prior to JDK 7.

 

From http://marxsoftware.blogspot.com/2011/10/guavas-objects-class-equals-hashcode.html

Object (computer science) Java (programming language)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Java Code Review Solution
  • Important Data Structures and Algorithms for Data Engineers
  • Understanding and Solving the AWS Lambda Cold Start Problem
  • Java REST API Frameworks

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: