The doc about java.util.Set.contains(Object o)
says:
Returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)).
That said, here is a POJO (as you can see, I overwrote its equals
method):
public class MonthAndDay {
private int month;
private int day;
public MonthAndDay(int month, int day) {
this.month = month;
this.day = day;
}
@Override
public boolean equals(Object obj) {
MonthAndDay monthAndDay = (MonthAndDay) obj;
return monthAndDay.month == month && monthAndDay.day == day;
}
}
So please, why does the following code prints false
instead of true
?
Set<MonthAndDay> set = new HashSet<MonthAndDay>();
set.add(new MonthAndDay(5, 1));
System.out.println(set.contains(new MonthAndDay(5, 1)));
// prints false
A solution is to rewrite the contains(Object o)
method, but the original one should be (almost) exactly the same, am I wrong?
Set<MonthAndDay> set = new HashSet<MonthAndDay>() {
private static final long serialVersionUID = 1L;
@Override
public boolean contains(Object obj) {
MonthAndDay monthAndDay = (MonthAndDay) obj;
for (MonthAndDay mad : this) {
if (mad.equals(monthAndDay)) {
return true;
}
}
return false;
}
};
set.add(new MonthAndDay(5, 1));
System.out.println(set.contains(new MonthAndDay(5, 1)));
// prints true
Explanation: Set has contains(Object o) method instead of get(Object o) method as get is needed for comparing object and getting corresponding value.
A Java object is a member (also called an instance) of a Java class. Each object has an identity, a behavior and a state. The state of an object is stored in fields (variables), while methods (functions) display the object's behavior. Objects are created at runtime from templates, which are also known as classes.
The set() method of Java Stack is used to replace any particular element in the stack created using the Stack class with another element. This can be done by specifying the position of the element to be replaced and the new element in the parameter of the set() method. Syntax: public E set(int index, Object element)
Collection contains() method in Java with ExamplesThis method returns a boolean value depicting the presence of the element. If the element is present, it returns true, else it returns false. Parameters: This method accepts a mandatory parameter element of type Object which is to be checked in this collection.
When you override equals(Object)
you also need to override hashcode()
.
Specifically, the methods must be implemented so that if a.equals(b)
is true
, then a.hashcode() == b.hashcode()
is all true
. If this invariant is not respected, then HashMap
, HashSet
and Hashtable
will not work properly.
The technical details of how hashcode()
and equals(Object)
should behave are specified in the Object API.
So why do the hash-based data structures break if you get this wrong? Well basically because a hash table works by using the value of the hash function to narrow down the set of values to be compared with the "candidate". If the hashcode for the candidate is different to the hashcode for some object in the table, then the chances are that the lookup algorithm won't compare with the object in the table ... even if the objects are equal.
HashSet
will only use equals()
if the elements share the same hashCode()
, thus you need to override both. Here's the relevant part of the code that is used by HashSet#contains()
(note that HashSet
is backed by a HashMap
):
355 /**
356 * Returns the entry associated with the specified key in the
357 * HashMap. Returns null if the HashMap contains no mapping
358 * for the key.
359 */
360 final Entry<K,V> getEntry(Object key) {
361 int hash = (key == null) ? 0 : hash(key.hashCode());
362 for (Entry<K,V> e = table[indexFor(hash, table.length)];
363 e != null;
364 e = e.next) {
365 Object k;
366 if (e.hash == hash &&
367 ((k = e.key) == key || (key != null && key.equals(k))))
368 return e;
369 }
370 return null;
371 }
Not doing so, violates the contract of Object#hashCode()
, which states that:
If two objects are equal according to the
equals(Object)
method, then calling thehashCode
method on each of the two objects must produce the same integer result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With