You are on page 1of 5

It is not always necessary to override hashcode and equals.

But if you think you need to override one, then you need to override both of them. Let's analyze what would happen if we override one but not the other and we attempt to use a Map. Say we have a class like this and that two objects of MyClass are equal if their importantField is equal (with hashCode and equals generated by eclipse) public class MyClass {

private final String importantField; private final String anotherField;

public MyClass(final String equalField, final String anotherField) { this.importantField = equalField; this.anotherField = anotherField; }

public String getEqualField() { return importantField; }

public String getAnotherField() { return anotherField; }

@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((importantField == null) ? 0 : importantField.hashCode());

return result; }

@Override public boolean equals(final Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final MyClass other = (MyClass) obj; if (importantField == null) { if (other.importantField != null) return false; } else if (!importantField.equals(other.importantField)) return false; return true; }

Override only hashCode Imagine you have this MyClass first = new MyClass("a","first"); MyClass second = new MyClass("a","second"); If you only override hashCode then when you call myMap.put(first,someValue) it takes first, calculates its hashCode and stores it in a given bucket. Then when you call

myMap.put(first,someOtherValue) it should replace first with second as per the Map Documentation because they are equal (according to our definition). But the problem is that equals was not redefined, so when the map hashes second and iterates through the bucket looking if there is an object k such that second.equals(k) is true it won't find any as second.equals(first) will be false. Override only equals If only equals is overriden, then when you call myMap.put(first,someValue) first will hash to some bucket and when you call myMap.put(first,someOtherValue) it will hash to some other bucket. So, although they are equal, as they don't hash to the same bucket (different hashCode) the map can't realize it and both of them stay in the map. Hope it was clear

You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the 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.

HashMap is similer to HashTable. HashMap accepts nulls as key s and values. But Hash Table cant HashMap is unsynchronized and Hash table is not(means synchronized).

What is the role of the clone() method in Java? protected Object clone() throws CloneNotSupportedException - this method is used to create a copy of an object of a class which implements Cloneable interface. By default it does field-by-field copy as the Object class doesn't have any idea in advance about the members of the particular class whose objects call this method. So, if the class has only primitive data type members then a completely new copy of the object will be created and the reference to the new object copy will be returned. But, if the class contains members of any class type then only the object references to those members are copied and hence the member references in both the original object as well as the cloned object refer to the same object. Cloneable interface We get CloneNotSupportedException if we try to call the clone() method on an object of a class which doesn't implement the Cloneable interface. This interface is a marker interface and the implementation of this interface simply indicates that the Object.clone() method can be called on the objects of the implementing class.

Example: how cloning works in Java? Class A { ... } A objA = new A(); A objACloned = (A) objA.clone(); Now, objA != objACloned - this boolean expression will always be true as in any case a new object reference will be created for the cloned copy. objA.getClass() == objACloned.getClass() - this boolean expression will also be always true as both the original object and the cloned object are instances of the same class (A in this case). Initially, objA.equals(objACloned) will return true, but any changes to any primitive data type member of any of the objects will cause the expression to return false. It's interesting to note here that any changes to the members of the object referenced by a member of these objects will not cause the expression to return false. Reason being, both the copies are referring to same object as only the object references get copied and not the object themselves. This type of copy is called Shallow Copy (Read Next Deep Copy vs Shallow Copy >> You may browse the links given in that article to go through various aspects of Cloning in Java). This can be understood easily by looking at the following memory diagram:-

Purpose of having marker interfaces in Java i.e., why to have marker interfaces? The main purpose to have marker interfaces is to create special types in those cases where the types themselves have no behavior particular to them. If there is no behavior then why to have an interface? Because the implementer of the class might only need to flag that it belongs to that particular type and everything else is handled/done by some other unit - either internal to Java (as in the case of Java supplied standard marker interfaces) or an app specific external unit.

You might also like