what do you need to do to use a custom object as key in collection classes like map or set?

Prerequisite – Equals and Hashcode method
HashMap and HashSet use the hashcode value of an object to notice out how the object would exist stored in the collection, and afterward hashcode is used to help locate the object in the collection. Hashing retrieval involves:

  1. Start, discover out the right saucepan using hashCode().
  2. Secondly, search the bucket for the right element using equals()

Permit us consider all the cases of Overriding in these methods

Case 1: Overriding both equals(Object) and hashCode() method

Yous must override hashCode() in every class that overrides equals(). Failure to do so will event in a violation of the full general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable. (-Joshua Bloch)
Here is the contract, from the java.lang.Object specialization:

  • Whenever it(hashcode) is invoked on the aforementioned object more than once during an execution of a Java application, the hashCode method must consistently return the aforementioned integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If ii objects are equal co-ordinate to the equals(Object) method, so calling the hashCode method on each of the 2 objects must produce the aforementioned integer result.
  • It is non required that if two objects are unequal according to the equals(java.lang.Object) method, so calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may amend the operation of hashtables.

import java.io.*;

import java.util.*;

class Geek

{

String proper noun;

int id;

Geek(String name, int id)

{

this .name = name;

this .id = id;

}

@Override

public boolean equals(Object obj)

{

if ( this == obj)

return true ;

if (obj == goose egg || obj.getClass()!= this .getClass())

return false ;

Geek geek = (Geek) obj;

return (geek.proper name.equals( this .name)  && geek.id == this .id);

}

@Override

public int hashCode()

{

return this .id;

}

}

class GFG

{

public static void chief (String[] args)

{

Geek g1 = new Geek( "aditya" , ane );

Geek g2 = new Geek( "aditya" , 1 );

Map<Geek, String> map = new HashMap<Geek, String>();

map.put(g1, "CSE" );

map.put(g2, "Information technology" );

for (Geek geek : map.keySet())

{

Arrangement.out.println(map.get(geek).toString());

}

}

}

output:

IT        

In this case we override both methods properly.
When we telephone call map.put(g1, "CSE"); it will hash to some bucket location and when nosotros telephone call map.put(g2, "It");, it will generates same hashcode value (same as g1) and supervene upon beginning value by 2d value considering while iterating over same saucepan information technology plant a grand such that k.equals(g2) is true, ways searching central already exist. So, it replaces old value of that key by new value.

Case two : Overriding but the equals(Object) method

If we only override equals(Object) method, when nosotros call map.put(g1, "CSE"); information technology will hash to some saucepan location and when we telephone call map.put(g2, "IT"); it will hash to some other saucepan location because of different hashcode value as hashCode() method has not been overridden.
hashcoe_1
As yous can see conspicuously in image, both values are getting stored into different saucepan locations. Like that every insert into map volition get dissimilar bucket location whether we are using same key objects or different i.due east. state of fundamental objects is same or different.

import java.io.*;

import java.util.*;

class Geek

{

String proper noun;

int id;

Geek(Cord proper name, int id)

{

this .name = name;

this .id = id;

}

@Override

public boolean equals(Object obj)

{

if ( this == obj)

return true ;

if (obj == null || obj.getClass()!= this .getClass())

return faux ;

Geek geek = (Geek) obj;

return (geek.name.equals( this .name) && geek.id == this .id);

}

}

class GFG

{

public static void main (String[] args)

{

Geek g1 = new Geek( "aditya" , 1 );

Geek g2 = new Geek( "aditya" , 1 );

Map<Geek, String> map = new HashMap<Geek, String>();

map.put(g1, "CSE" );

map.put(g2, "Information technology" );

for (Geek geek : map.keySet())

{

System.out.println(map.get(geek).toString());

}

}

}

Output:

CSE It

Example 3: Overriding only hashCode() method

Consider another example of map :

Map map = new HashMap(); map.put("xyz", "CSE"); map.put("xyz", "IT");        

When we telephone call map.put("xyz", "CSE"); it volition generate hashcode value and stores it to the bucket location that is specified with this accost (hashcode value). And when we telephone call map.put("xyz", "It"); it generates same hashcode value as previous entry since cardinal objects are same and hashCode() method has been overridden. So information technology should supplant first with second as per rule. Only it didn't. Reason is, when information technology iterate through that saucepan and seeks to observe k such that k.equals("xyz") i.e. if searching key already be. Only it fails to find because equals(Object ) method has non been overridden. It is violation of dominion of hashing.

import coffee.io.*;

import coffee.util.*;

form Geek

{

String name;

int id;

Geek(String name, int id)

{

this .proper noun = name;

this .id = id;

}

@Override

public int hashCode()

{

return this .id;

}

}

class GFG

{

public static void primary (String[] args)

{

Geek g1 = new Geek( "aditya" , ane );

Geek g2 = new Geek( "aditya" , one );

Map<Geek, String> map = new HashMap<Geek, Cord>();

map.put(g1, "CSE" );

map.put(g2, "It" );

for (Geek geek : map.keySet())

{

System.out.println(map.get(geek).toString());

}

}

}

Output:

CSE Information technology

hashcode_3

In higher up diagram when we call map.put("xyz", "IT"); and then it tried to replace beginning value (CSE) by second value(Information technology) but it was not possible so it insert second pair (key, value) into a new LinkedList node that hashmap internally employ. It it total violation of rule as fundamental are unique in map.

Reference : StackOverflow

This article is contributed by Nitsdheerendra. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks principal folio and help other Geeks.

Please write comments if you discover anything incorrect, or yous want to share more data about the topic discussed higher up.


fisherbutiedis.blogspot.com

Source: https://www.geeksforgeeks.org/override-equalsobject-hashcode-method/

0 Response to "what do you need to do to use a custom object as key in collection classes like map or set?"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel