26

How should I implement hashCode() and equals() for the following class in Java?

class Emp 
{
  int empid ; // unique across all the departments 
  String name;
  String dept_name ;
  String code ; // unique for the department 
}
Vidya
  • 7,717
  • 12
  • 48
  • 75
  • That is no Java source code. Or did you create your own class called `string`? And you really should have a look at this: http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html – Bart Kiers Jan 25 '10 at 12:57
  • I see Joachim changed a couple of the errors in your code sample. Nevertheless, I recommend looking at the link I posted in my previous comment. – Bart Kiers Jan 25 '10 at 13:01
  • i am using java's String class – Vidya Jan 25 '10 at 13:02
  • 1
    Also see:http://www.artima.com/lejava/articles/equality.html, that explains how to write am Equality method. – sateesh Jan 25 '10 at 13:23
  • http://marxsoftware.blogspot.in/2011/10/guavas-objects-class-equals-hashcode.html – Emil Apr 16 '12 at 04:52
  • Use Eclipse or IntelliJ IDEA to generate `equals()` and `hashCode()` for you. All you have to do is to select a fields it should depends on. – Jiri Kremser Jun 27 '13 at 11:04
  • check Effective Java item 8 for a through treatment of writing an `equals` method. – Paul Rooney Aug 19 '16 at 00:51

6 Answers6

34

in Eclipse right mouse click-> source -> generate hashCode() and equals() gives this:

/* (non-Javadoc)
 * @see java.lang.Object#hashCode()
 */
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (code == null ? 0 : code.hashCode());
    return result;
}
/* (non-Javadoc)
 * @see java.lang.Object#equals(java.lang.Object)
 */
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (!(obj instanceof Emp))
        return false;
    Emp other = (Emp) obj;
    return code == null ? other.code == null : code.equals(other.code);
}

I've selected code as a unique field

kapandron
  • 3,546
  • 2
  • 25
  • 38
jutky
  • 3,895
  • 6
  • 31
  • 45
  • 1
    Hmmm... I would usually compare all fields in the equals() method unless you really have a strong reason not to... – Neil Coffey Jan 25 '10 at 13:04
  • 1
    So if two `Emp` from different departments have the same code, they are equal? You need at least to add the `dept_name` in this implementation. – Pascal Thivent Jan 25 '10 at 13:21
  • I am accepting this answer as I got the idea what needs to be done . jutky has assumed code as the unique identifier. – Vidya Jan 25 '10 at 13:24
  • 6
    Code **if (obj == null) return false;** is redundant because **instanceof** checks for null – Alex Kucherenko Mar 13 '15 at 22:31
  • checking with instanceof results in Sonar critical issue. So better use if (getClass()!=other.getClass()) {return false;} – ACV Jun 26 '17 at 16:24
4

try this code, use org.apache.commons.lang3.builder

public int hashCode() {
    return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
        append(empid).
        append(name).
        append(dept_name ).
        append(code ).
        toHashCode();
}

public boolean equals(Object obj) {

    if (obj == this)
        return true;
    if (!(obj instanceof Person))
        return false;

    Emp rhs = (Emp) obj;
    return new EqualsBuilder().
        // if deriving: appendSuper(super.equals(obj)).
        append(name, rhs.name).
        isEquals();
}
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
xingfe123
  • 79
  • 3
2

Guava has helper methods for creating them. You tell it which fields to take in consideration and it will handle nulls for you and do the prime number calculation for hashcode.

IDEs can also generate them based on the fields you choose.

The advantage of delegating it to a tool like that is you get a standard solution and will worry less about bugs and maintenance of varied implementations spread all over your project.

Here's an example of using Guava and generated by an IntelliJ plugin: https://plugins.jetbrains.com/plugin/7244?pr=

Victor Basso
  • 5,556
  • 5
  • 42
  • 60
0

If code is unique (i.e. your business key), it's best to only use the code for equals and hashCode - it's good practice to seperate business key (code) from object id (id).

Here's a nice read: Hibernate Documentation: Equals and HashCode (valid not only for Hibernate itself)

sfussenegger
  • 35,575
  • 15
  • 95
  • 119
  • 1
    It seems to be unique for a department, so that suggests that departments can share the same "code". Anyway, a rather vague question if you ask me. – Bart Kiers Jan 25 '10 at 12:59
-1

what ever values you use in equals to determine if two objects are the same, are the the values that you need to use to create a hash code.

public boolean equals(Object o) {

    boolean result = false;

    if(o instanceof CategoryEnum) {

        CategoryEnum ce = (CategoryEnum) o;
        result = ce.toString().equals(name);

    }       
    return result;

}


public int hashCode()
{
  int hash = 6;
  hash += 32 * name.hashCode();
  return hash;
}   
jeff porter
  • 6,560
  • 13
  • 65
  • 123
  • 3
    (no -1 from me) That's not completely true. It's perfectly legal to only use a subset for hashCode (e.g. code and name for equals and only code for hashCode). It's even legal to use a constant hashCode (`public int hashCode() {return 42;}`) - it ruins the performance of hashed collections (HashMap, HashSet, ...) but they keep working correctly. So it's better than an invalid hashCode method. The only rule is: if two objects are equal (`a.equals(b)`) they must have the same hash code (`a.hashCode() == b.hashCode()`). If they aren't equal, hash codes may still be equal. – sfussenegger Jan 25 '10 at 14:40
-2

equals()and hashcode(),They have a lot of different places. equals(),if we don't Override it from Object,it represent that whether two variables are pointing to the same object heap?

public  Class Student(){
  private int id;
  private  name;
  public Student(int id,String name){
  this.name=name;
  this.id=id; 
}

public void main(String[] args){
  Student A=new Student(20,'Lily');
  Student B=new Student(20,'Lily');
  boolean flag=A.equals(B)//flag=flase;
/*
 *Although they attribute the same, but they are two different objects, they point to     different memory
 */


@Override
public boolean equals(Object obj) {


  if (obj == null) {
    return false;
  }
  if (this == obj) {
    return true;
  }

  if (this.getClass() != obj.getClass()) {
    return false;
  }
  Student s=(Student)obj;
  return new Integer(this.id).equals(new Integer(s.id))&&this.name.equals(s.name);
  }

/**
  *Sometimes even though we Override  the equals, but we still can not determine whether   the *two objects the same,
  *In the collection object, such as HashSet, this time we have to Override the hashoCode ()
  */

public int hashCode(){
  return id + name.hashCode() ;
}
mmmmmm
  • 32,227
  • 27
  • 88
  • 117