Using HashSet with custom Employee class

I know this would be a very stupid question, but I was confused after what I knew about HashSet

and what I see when I execute the code below.

I have an Employee class as follows (keeping only the relevant piece of code):

public class Employee {
    //assume it has 3 variable name(String),salary(double) and id(int)
    //assume the constructor, getter-setters are there 

    //following is my equals and hashCode implementation
    public boolean equals(Employee e){
        return name.equals(e.name);
    }

    public int hashCode(){
        return id;
    }
}

      

I now have the following code that uses HashSet

:

Employee e1  = new Employee("Abc", 2.0, 1);
Employee e2  = new Employee("abc", 3.0, 4);
Employee e3  = new Employee("XYZ", 4.0, 3);
Employee e4  = new Employee("Mno", 5.0, 2);
Employee e5  = new Employee("Abc", 77.0, 1);

Set<Employee> sEmp = new HashSet<Employee>();
sEmp.add(e1);
sEmp.add(e2);
sEmp.add(e3);
sEmp.add(e4);
sEmp.add(e5);

for(Employee e : sEmp){
    System.out.println(e);
}

      

So, I get all the object data that is printed to my console like:

Abc 77.0 1
Abc 2.0 1
Mno 5.0 2
XYZ 4.0 3
abc 3.0 4

      

AFAIK, the set does not allow duplicates and this duplicate will be checked against equals

(correct me if I'm wrong).

Also HashSet

uses hashCode

, so in the above case it shouldn't add an object e5

. But it successfully adds this item to the set. This confused me.

(Please ignore if I missed standards and all, I'm trying to understand the concept / implementation).

EDITED: This may sound like a stupid question, but I'm preparing for certification and trying to figure out how stuff works.

+3


source to share


3 answers


You are overloading equals

, not overriding it. Its parameter must be of type Object

.



But yours also hashCode

checks id

, and equals

checks name

. They should probably be built from the same properties.

+7


source


This is a common example of why we should use annotation @Override

where possible.

If you use this annotation with a method equals

, you will be told by the compiler that you are not overriding the method equals

, because there is no method in the superclass equals(Employe)

, but equals(Object)

. Thus, you are overloading this method (you create an additional method with different arguments).



Because of this, the HashSet does not use the code of your method equals

, but the code from the method equals(Object)

inherited from the class Object

, which simply checks for equality references:

public boolean equals(Object obj) {
    return (this == obj);
}

      

+2


source


I added some more code to the equals methods. This will allow you to update the latest value for the employee ID.

package com.test.day16;

import java.util.HashSet;
import java.util.Set;

/**
 * 
 * @author PradeepPadmarajaiah
 *
 */
public class Employee {

    private int empId;
    private String empName;

    public Employee(int empId, String empName) {
        super();
        this.empId = empId;
        this.empName = empName;
    }

    /**
     * @return the empId
     */
    public final int getEmpId() {
        return empId;
    }

    /**
     * @param empId
     *            the empId to set
     */
    public final void setEmpId(int empId) {
        this.empId = empId;
    }

    /**
     * @return the empName
     */
    public final String getEmpName() {
        return empName;
    }

    /**
     * @param empName
     *            the empName to set
     */
    public final void setEmpName(String empName) {
        this.empName = empName;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "Employee [empId=" + empId + ", empName=" + empName + "]";
    }

    @Override
    public int hashCode() {
        return this.empId;
    }

    @Override
    public boolean equals(Object obj) {
        Employee employee = (Employee) obj;
        if (employee.empId == this.empId) {
            employee.setEmpName(this.empName);
            return true;
        } else {
            return false;
        }
    }

    public static void main(String[] args) {
        Set<Employee> employees = new HashSet<>();
        employees.add(new Employee(1, "Raj"));
        employees.add(new Employee(1, "Pradeep"));
        employees.add(new Employee(1, "Kumar"));
        employees.add(new Employee(2, "Chandan"));
        employees.add(new Employee(2, "Amitava"));

        System.out.println(employees);
    }
}

      

Check the line " employee.setEmpName (this.empName); " This will override the id value. This means empId 1 will have the last empName value as Kumar Else, empId 1 will have the empName value as Raj that was first assigned, and it will not override the Kumar value after checking Now, this works like a HashMap mechanism.

The result of the code will be [Employee [empId = 1, empName = Kumar], Employee [empId = 2, empName = Amitava]]

0


source







All Articles