vaib
vaib

Reputation: 321

Tree Set behaves differently but hash set doesn't in case of custom object

In below created code have Employee class with attributes Id and Name,Created 3 objects of Employee class e1,e2,e3 with respective name attribute a,b,a. when I add these object in hash set the size shows 3 but on same while in Tree Set it show size 2 even i am not overriding the hash code and equals method.

    Emplyoee class.............................


        package collection.core.concept;

        public class Employee implements Comparable<Employee>{

            private int id;
            private String name;

            public int getId() {
                return id;
            }
            public void setId(int id) {
                this.id = id;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }

           @Override
           public int compareTo(Employee o) {
            if(this.name.equal(o.getName()){
               return 0;
            }else{
              return 1;
              }
           }
            @Override
            public String toString(){
            return name;

            }
    }

    main class...............................................
    public class CustomTreeSetSorting {
        public static void main(String[] args) {

            Employee e1 = new Employee();
            e1.setId(1);
            e1.setName("alok");
            Employee e2 = new Employee();
            e2.setId(2);
            e2.setName("vaibhav");
            Employee e3 = new Employee();
            e3.setId(3);
            e3.setName("alok");


            Set<Employee> Employee1 = new TreeSet<Employee>();

            Employee1.add(e1);
            Employee1.add(e2);
            Employee1.add(e3);
            System.out.println(Employee1.size());

        }
    }

Upvotes: 0

Views: 137

Answers (5)

sol4me
sol4me

Reputation: 15698

Whenever you are add something to TreeSet then compareTo method of class Employee is getting invoked and in compareTo method you are stating that if 2 names are equal then both objects are the same. Thats why TreeSet is adding only 2 objects alokand vaibhav . Moreover, currently you are comparing string wrongly , in order to compare Strings use compareTo on String objects that compare objects based on natural ordering i.e. lexicographically

Upvotes: 1

Ravi Yenugu
Ravi Yenugu

Reputation: 3898

Both HashSet and Treeset doesn't allow duplicates.

The behavior is explained by understanding How do you define a Duplicate!


HashSet

In case of HashSet, the hashcodes for two objects are different even for same names, hence they are not considered duplicates.Unless you override hashCode and equals all the objects are considered distinct/unique


TreeSet:

You are providing the definition of "Duplicate" by overriding compareTo. i.e. If the names are same then the Objects are same

To allow duplicates in your TreeSet, Change your compareTo to

@Override
  public int compareTo(Employee o) {
    if (this.name.equals(o.getName())) {
      return -1; //return 0 says that two objects are same 
    } else {
      return 1;  
    }
  }

Upvotes: 0

StackFlowed
StackFlowed

Reputation: 6816

In general sets you cannot have repetitions. Hence the size is two.

Since

 @Override
    public boolean equals(Object obj) {
        Employee emp = (Employee) obj;  
           if (name.equals(emp. getName())) {  
               return true;  
           }
           return false;  
}

It checks only name even though the id is different it treats them as same objects.

Change it to

    @Override
    public boolean equals(Object obj) {
       if(obj instanceof this) {
           Employee emp = (Employee) obj;  
           if (name.equals(emp. getName()) && id == emp.getId()) {  
               return true;  
           }
           return false;  
       }
       return false;
    }

Also the code is wrong for

@Override
public int compareTo(Employee o) {
    if(this.name==o.name){
        return 0;
    }else{
        return 1;
    }
}

Change it to

@Override
public int compareTo(Employee o) {
    return name.compareTo(o.getName());
}

You cannot compare strings with == use .equals method.

Upvotes: 1

TechTrip
TechTrip

Reputation: 4537

Personally if I was going to base my comparison on a single string for insertion into the tree I would use what is already given to us:

public int compareTo(Employee o) {
    return this.name.compareTo(o.getName());
}

Not sure why this isn't the first choice? Am I missing something?

Given that, you probably need more than just the String, otherwise why have id's? I can't fathom two employee objects being the same if they have different id's (i.e. if they have more than one ID, I would create an array of id's as names are not unique.)

Upvotes: 0

Joel
Joel

Reputation: 2404

How could we get different results according to the set that is used? It's quite simple : the HashSet uses both equals and hashCode to check object equality. You've got 3 different ids, that's why you get 3 objects in your hashset.

On the other hand, the TreeSet will use your compareTo method (or a provided Comparator) to compare items and check equality. If you compareTo method uses names only to give its result, and knowing you have only 2 unique names, then the TreeSet will only have 2 elements (probably the last one will be discarded)

Upvotes: 0

Related Questions