0

I have little problem with java. i am not able to get accurate result. what's wrong with this code please help me out from this code your own objects as keys in Maps or in Sets. To use your own objects as keys in Maps or in Sets.code not executing correctly..

what is use of hashcode and equals in java.

Code:

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

class Person {
    private int id;
    private String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public String toString() {
        return "{ID is: " + id + "; name is: " + name + "}";
    }
}

public class App {
    public static void main(String[] args) {
        //creating person object
        Person p1 = new Person(0, "Bob");
        Person p2 = new Person(1, "Sue");
        Person p3 = new Person(2, "Mike");
        Person p4 = new Person(1, "Sue");

        Map<Person, Integer> map = new LinkedHashMap<Person, Integer>();
        //putting on map
        map.put(p1, 1);
        map.put(p2, 2);
        map.put(p3, 3);
        map.put(p4, 1);

        //displaying the result
        for(Person key: map.keySet()) {
            System.out.println(key + ": " + map.get(key));
        }

        //using set
        Set<Person> set = new LinkedHashSet<Person>();

        //adding on set
        set.add(p1);
        set.add(p2);
        set.add(p3);
        set.add(p4);

        //displaying the result
        System.out.println(set);
    }
}

Expected Output:

{ID is: 0; name is: Bob}: 1
    {ID is: 1; name is: Sue}: 1
    {ID is: 2; name is: Mike}: 3
    [{ID is: 0; name is: Bob}, {ID is: 1; name is: Sue}, {ID is: 2; name is: Mike}]

3 Answers3

1

Cfr the general contract for hashCode:

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

robermann
  • 1,682
  • 10
  • 19
1

The equals() and hashCode() methods are both implemented in the superclass Object. In real worl applications, you may incounter the need to override both of these methods but don't do unless you understand their utility. I'll try to give the best in short:

equals() method is used for equivalence relations. hashCode() is used to provide, as it reveals, a hash code which is a 32-byte representation of the object.

Imagine that you have a class Person with below declaration:

public class Person {
  public int nationalIdentityNumber;
  public String firstName;
  public String secondName;
  public Person (int nationalIdentityNumber, String firstName, String secondName) {
    this.nationalIdentityNumber = nationalIdentityNumber;
    this.firstName = firstName;
    this.secondName = secondName;
  }
}

When not overriding the equals() methods:

Person p1 = new Person(1234,"Jhon","Legend");
Person p1 = new Person(1234,"Mary","Richard");

When we call p1.equals(p2) this will result in a false result thus the default method from Object class compares the objects references. But what I actually you may need is that two Persons are considered equals when their nationalIdentityNumber instance variable is equal so you need to override the equals() implementation as below:

@Override
public boolean equals(Object object) {
  boolean result = false;
  if (object == null || object.getClass() != getClass()) {
    result = false;
  } else {
    Person person = (Person) object;
    if (this.nationalIdentityNumber == person.nationalIdentityNumber) {
      result = true;
    }
  }
  return result;
}

So p1.equals(p2) will now return a true result.

Now back to hashCode, imagine you are registering your Person objects in a HashSet

HashSet<Person> personsHS = new HashSet<Person>();
    personsHS.add(p1);
    personsHS.add(p2);

When invoquing

System.out.println("personsHS.contains( new Person(1234,Jhon,Legend))--->>>"+personsHS.contains(new Person(1234,"Jhon","Legend")));

it will result in personsHS.contains( new Person(1234,"Jhon","Legend"))--->>>false statement because the HashSet is using the default Object#hashCode() method to determine the equality of keys thus we need to override it to ensure the Person uniqueness (based on your requirements) inside the hashtables:

@Override
public int hashCode() {
  return this.nationalIdentityNumber;
}

So that

System.out.println("personsHS.contains(new Person(1234,Jhon,Legend))--->>>"+personsHS.contains(new Person(1234,"Jhon","Legend")));

will result in personsHS.contains( new Person(1234,"Jhon","Legend"))--->>>true

This is a simplest that it could be but note that it will always depend on your application and your own objects to wether or not to override this methods and which fashion to do so.

BR.

tmarwen
  • 11,491
  • 4
  • 35
  • 54
0

In java, to use your own objects in some fonctionnalities you sometimes need to create some "generic" fonctions. HashCode and Equals for instance.

To use your objects in a hashmap like you are doing, java needs those. So you have to implement them in your "person" class. Here is an article explaining why in some case we need to override these methods and what exactly they are doing:

http://javarevisited.blogspot.ca/2011/02/how-to-write-equals-method-in-java.html

Normally you can auto-generate them withing your IDE, in NetBeans you can go to: Source - Insert Code - Equals and Hashcode.

Then it should work.

alex
  • 293
  • 1
  • 2
  • 8
  • please elaborate i am not able to understand >>some "generic" fonctions – sanjaybrandtest1 Mar 04 '14 at 16:07
  • In order to use your person class in an hashMap, Java needs to be able to be able to compare 2 "person" objects. This is done with the methods equals() and hashCode(), hashCode produces a hash and equals() makes a comparaison between 2 hashCode() results of 2 "persons". In other words: Java need to be able to use these 2 fonctions in your person class in order to make them work in a hashMap, so you need them. But you can actually auto-generate them in both Eclipse and NetBeans, depending on what you are using. I used the term generic for these 2 fonctions because they can be auto-generated. – alex Mar 04 '14 at 16:13
  • can i see the how comparion doing in java – sanjaybrandtest1 Mar 04 '14 at 16:16
  • I found you an example similar with your code. This is also a good article explaining why you need to override those functions. [Here's the link](http://javarevisited.blogspot.ca/2011/02/how-to-write-equals-method-in-java.html) – alex Mar 04 '14 at 16:19