Why do I need to override the hashcode method to override the equals method?

Source: Internet
Author: User

In this article, I will show you my understanding of the hashcode and equals methods. I will discuss their default implementations and how to rewrite them correctly. I will also use the Toolkit provided by Apache commons for implementation.

Directory:

  1. Hashcode () and equals () Usage
  2. Override default implementation
  3. Use the Apache commons lang package to override hashcode () and equals ()
  4. Things to remember
  5. Note the following when Using ORM:

Hashcode () and equals () are defined in the object class. This class is the base class of all Java classes, so all Java classes inherit these two methods.


Use hashcode () and equals ()

The hashcode () method is used to obtain the unique integer of a given object. This integer is used to determine the position where the object is stored in a structure similar to hashtable. By default, the hashcode () method of the object class returns the number of the memory address of the Object Storage.

Override the default implementation

If you do not override these two methods, there will be almost no problem, but sometimes the program requires us to change the default implementation of some objects.

Let's take a look at this example. Let's create a simple class employee

public class Employee{    private Integer id;    private String firstname;    private String lastName;    private String department;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getFirstname() {        return firstname;    }    public void setFirstname(String firstname) {        this.firstname = firstname;    }    public String getLastName() {        return lastName;    }    public void setLastName(String lastName) {        this.lastName = lastName;    }    public String getDepartment() {        return department;    }    public void setDepartment(String department) {        this.department = department;    }}

The above employee class only has some basic attributes and getter and setter. Now we will consider a situation where you need to compare two employees.


public class EqualsTest {    public static void main(String[] args) {        Employee e1 = new Employee();        Employee e2 = new Employee();        e1.setId(100);        e2.setId(100);        //Prints false in console        System.out.println(e1.equals(e2));    }}

There is no doubt that the above program will output false, but, in fact, the above two objects represent through an employee. The true business logic is expected to return true.
To achieve this, we need to override the equals method.

public boolean equals(Object o) {        if(o == null)        {            return false;        }        if (o == this)        {           return true;        }        if (getClass() != o.getClass())        {            return false;        }        Employee e = (Employee) o;        return (this.getId() == e.getId());}

Add this method to the class above, and eauqlstest will output true.
So are we done? No. Let's take a test.

import java.util.HashSet;import java.util.Set;public class EqualsTest{    public static void main(String[] args)    {        Employee e1 = new Employee();        Employee e2 = new Employee();        e1.setId(100);        e2.setId(100);        //Prints 'true'        System.out.println(e1.equals(e2));        Set<Employee> employees = new HashSet<Employee>();        employees.add(e1);        employees.add(e2);        //Prints two objects        System.out.println(employees);    }

The above program outputs two results. If two employee objects equals return true, only one object should be stored in the set. What is the problem?
We forgot the second important method hashcode (). As mentioned in JDK javadoc, If you override the equals () method, you must override the hashcode () method. We add the following method, and the program will be executed correctly.

@Override public int hashCode() {    final int PRIME = 31;    int result = 1;    result = PRIME * result + getId();    return result; }

Use the Apache commons lang package to override the hashcode () and equals () Methods
The Apache commons package provides two excellent classes to generate the hashcode () and equals () methods. See the following program.


import org.apache.commons.lang3.builder.EqualsBuilder;import org.apache.commons.lang3.builder.HashCodeBuilder;public class Employee{ private Integer id; private String firstname; private String lastName; private String department;public Integer getId() {    return id; } public void setId(Integer id) {    this.id = id; } public String getFirstname() {    return firstname; } public void setFirstname(String firstname) {    this.firstname = firstname; } public String getLastName() {    return lastName; } public void setLastName(String lastName) {    this.lastName = lastName; } public String getDepartment() {    return department; } public void setDepartment(String department) {    this.department = department; }@Override public int hashCode() {    final int PRIME = 31;    return new HashCodeBuilder(getId()%2==0?getId()+1:getId(), PRIME).           toHashCode(); }@Override public boolean equals(Object o) {    if (o == null)       return false;    if (o == this)       return true;    if (o.getClass() != getClass())       return false;    Employee e = (Employee) o;       return new EqualsBuilder().              append(getId(), e.getId()).              isEquals();    } }

If you use eclipse or other ides, IDE may also generate good hashcode () and equals () methods.

Things to remember

  • Make sure that the same attribute of the object is used to generate the hashcode () and equals () methods. In our case, we use employee ID.
  • The eqauls method must be consistent (if the object is not modified, equals should return the same value)
  • Whenever a. Equals (B) is required, A. hashcode () must be equal to B. hashcode.
  • Both must be rewritten at the same time.

Note the following when Using ORM:

  • If you use ORM to process some objects, make sure to use getter and Setter in hashcode () and equals () objects instead of directly referencing member variables. In Orm, sometimes the member variables are loaded at a delay. These variables are only available when the getter method is called.
  • For example, in our example, this problem may occur if we use e1.id = e2.id, but we use e1.getid () = e2.getid.
Reprinted: http://www.oschina.net/question/82993_75533

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.