Unique identification of entities in Collections

Overview
Every java class need to have equals() and hashcode() methods implemented which are used for distinctly identify the object. The equals() method is used by methods like contains(Object o), remove(Object o) and put() to uniquely identify the objects.

Business use cases:

  • When a specific business key need to be used for any of the methods specified above, equals() and hashcode() need to be overwritten.
  • A person entity need to be identified uniquely based on combination of name and dob, which combination need to be verified before adding to the list.
  • A map of persons need to be maintained where the key represent the Person entity which can be uniquely identified based on combination of name and dob.

Source Code snippets:

  • Implementation of hashcode() and equals():
    • The below source code snippet provides implementation of equals and hashcode.
    • The equals method checks the combination of name and dob as unique key.
    • As per java contract every object with distinct equals result need to have distinct hashcode which makes it mandatory to override hashcode also every time equals is overwritten.
	private class Person {

		private String name;
		private Date dob;
		private String address;
		private String skillset;

		public Person(String name, Date dob) {
			this.name = name;
			this.dob = dob;
		}
:::::::::::::::::::::::::::::::::::
		@Override
		public int hashCode() {
			int dateInt = (int) (dob.getTime() / 1000);
			int nameHash = name.hashCode() + dateInt + 31;
			return nameHash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) return false;
			if (!(obj instanceof Person)) return false;
			if (obj == this) return true; 
			Person person = (Person) obj;
			if (person.name.equalsIgnoreCase(name) && person.dob.equals(dob)) {
				return true;
			} else {
				return false;
			}
		}
	}

 

  • Testing contains method on List:
    • Create person1 and person2 entities with same name(Tom) and dob(1980-01-01).
    • Check whether entity exist in list using contains method.
    • The first sysout results in personlist size as 1, as contains method returns false as person2 entity business key matches to that of person1 entity.
    • Modifying the person2 dob will allow it to be added to the arraylist
    • Comment the equals and hashcode method in Person class and re-try the examples to notice how contains method works.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		List<Person> personsList = new ArrayList<DemoHasCodeEqualsImpl.Person>();
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
	Person person1 = codeEqualsImpl.createPerson("Tom", dateFormat.parse("1980-01-01"), "US", "Run");
	personsList.add(person1);
	Person person2 = codeEqualsImpl.createPerson("Tom", dateFormat.parse("1980-01-01"), "Germany", "Rob");
	if (!personsList.contains(person2)) {
		personsList.add(person2);	
	}
	System.out.println("Person list when name and dob are same for person2 "+personsList.size());
	person2 = codeEqualsImpl.createPerson("Tom", dateFormat.parse("1980-02-01"), "Germany", "Rob");
	if (!personsList.contains(person2)) {
			personsList.add(person2);	
	}
	System.out.println("Person list when name and dob are different for person2 "+personsList.size());

  • Testing unique key in Map:
    • Create person1 and person2 entities with same name and dob
    • Add both the persons to map and check the size of the map
    • Its noticed there is only entry in the map and its also noticed person2 data overwrites the data of person1
    • Now modify person2 dob and re-try it, to notice both the entities are added to the map
    • Comment the equals and hashcode method in Person class and re-try the examples to notice how put method works.
	Person person1 = codeEqualsImpl.createPerson("Tom", dateFormat.parse("1980-01-01"), "US", "Run");
	personMap.put(person1, person1);
	Person person2 = codeEqualsImpl.createPerson("Tom", dateFormat.parse("1980-01-01"), "Germany", "Rob");
	personMap.put(person2, person2);
	System.out.println("PersonMap expects to have only one entity:--> "+personMap.size());
	person2 = codeEqualsImpl.createPerson("Tom", dateFormat.parse("1980-02-01"), "Germany", "Rob");
	personMap.put(person2, person2);
	System.out.println("PersonMap expects to have two entities:--> "+personMap.size());

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s