Home page Java C++ Hardware HTML i javascript Java Software SQL flag_united_kingdom flag_poland

Java - override methods equals() and hashCode() in created classes.

2011-07-22

Classes that have attributes non-static and have been used in collection, one should replace methods equals() and hashCode(). This will ensure that the returned results comparing two object are correctly.

If classes are not used in collection, this does not guarantee that that inherited method equals() from class Object ensures the correct operation of the. So and so must you do testing it, and in case of problems must overriding this two methods.

In some IDE of programing you can generate overwritten methodsequals() and hashCode() for created class. In Eclipse in class body press Shift+Alt+S and from menu context chose Generate hashCode() and equals()....

The best way is to see it on examples, below method generated by Eclipse.

Print Select code
CEquals_hashCode_override.java
import java.util.HashSet;
import java.util.Set;


public class CEquals_hashCode_override  {
	public static void main(String args[]){
		System.out.println("Overriding equals() i hashCode()");
		
		Set<CDog> dog = new HashSet<CDog>();
		dog.add(new CDog("Alaskan Malamute", "Funny"));
		dog.add(new CDog("St. Bernard", "Bethoveen"));
		
		System.out.println(dog.contains(new CDog("Alaskan Malamute", "Funny")) 
				+ " - new CDog(\"Alaskan Malamute\", \"Funny\")");
		System.out.println(dog.contains(new CDog("Alaskan Malamute", "Fun"))
				+ " - new CDog(\"Alaskan Malamute\", \"Fun\")");
		System.out.println(dog.contains(new CDog(null, null)) 
				+ " - new CDog(\"null\", \"null\")");
		
		String t0 = new String("tekst");
		String t1 = new String("tekst");
		System.out.println("t0: " + t0.hashCode());
		System.out.println("t1: " + t1.hashCode());
		
		
		CDog dog0 = new CDog("Alaskan Malamute", "Funny");
		CDog dog1 = new CDog("Alaskan Malamute", "Funny");
		System.out.println("dog0: " + dog0.hashCode());
		System.out.println("dog1: " + dog1.hashCode());
		
		System.out.println(dog0.equals(dog1));
	}
	
}

class CDog {
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((nameDog == null) ? 0 : nameDog.hashCode());
		result = prime * result + ((breed == null) ? 0 : breed.hashCode());
		return result;
	}



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



	public CDog(String breed, String nameDog){
		this.setNameDog(nameDog);
		this.setBreed(breed);
	}
	
	
	
	public String getBreed() {
		return breed;
	}
	
	public void setBreed(String breed) {
		this.breed = breed;
	}
	
	public String getNameDog() {
		return nameDog;
	}
	
	public void setNameDog(String nameDog) {
		this.nameDog = nameDog;
	}
	
	private String breed;
	private String nameDog;
}

Commented all and/or some methods whose been overwritten and see what was happens.

Created method equals() and hashCode() by Eclipse work well, but if you want to better know, how it works encode yourself.

The use of if (getClass() != obj.getClass()) instead of if (!(obj instanceof CDog)) has big meaning. In first case if you created class CSmallDog, whose inherited form class CDog and created two objects CSmallDog sdog and CDog dog and you do compare dog.equals(sdog); that you have result false. In second case when you use instanceof you see result true, what can cheat programer ;)

If you must use instanceof , then deleting checking block if (obj == null) that object is null, because in that case returned false without throw exception.

Example application instanceof in method equals().

@Override
	public boolean equals(Object obj){
		if (obj == this)
			return true;

		if (!(obj instanceof CDog))
		return false;
		
		CDog other = (CDog) obj;
		return ((nameDog == null && other.nameDog == null) || nameDog.equals(other.nameDog)) 
				&& ((breed == null && other.breed == null) || breed.equals(other.breed));
	}

If you find unintelligible text, write to me corrected words, please - lis.la(at)wp.pl