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:
- Start, discover out the right saucepan using hashCode().
- 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.
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
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.
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