树集的行为不同,但是在自定义对象的情况下哈希集不会

时间:2014-09-17 17:30:37

标签: java collections

在下面创建的代码中,Employee类具有属性Id和Name,创建了3个Employee类e1,e2,e3对象,各自的名称属性为a,b,a。当我在哈希集中添加这些对象时,大小显示3但在同一组中,而在树集中它显示大小2,即使我没有覆盖哈希码和等于方法。

    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());

        }
    }

5 个答案:

答案 0 :(得分:1)

在一般情况下,你不能重复。因此,大小是两个。

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

它只检查名称,即使id不同,它也会将它们视为相同的对象。

将其更改为

    @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;
    }

的代码也是错误的
@Override
public int compareTo(Employee o) {
    if(this.name==o.name){
        return 0;
    }else{
        return 1;
    }
}

将其更改为

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

您无法使用== use .equals方法比较字符串。

答案 1 :(得分:1)

每当你向TreeSet添加一些东西时,就会调用类Employee的compareTo方法,并且在compareTo方法中你会说如果两个名字相等,那么两个对象都是相同的。这就是为什么TreeSet只添加了2个对象alokvaibhav。此外,目前你正在错误地比较字符串,以便比较字符串使用compareTo对比较基于自然顺序的对象的字符串对象,即按字典顺序

答案 2 :(得分:0)

我们如何根据使用的集合获得不同的结果?它非常简单:HashSet使用equals和hashCode来检查对象相等性。您有3个不同的ID,这就是您在哈希集中获得3个对象的原因。

另一方面,TreeSet将使用您的compareTo方法(或提供的Comparator)来比较项目并检查相等性。如果compareTo方法仅使用名称来给出结果,并且知道你只有2个唯一的名称,那么TreeSet将只有2个元素(可能最后一个将被丢弃)

答案 3 :(得分:0)

就个人而言,如果我要将我的比较基于一个字符串插入树中,我将使用已经给予我们的内容:

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

不确定为什么这不是首选?我错过了什么吗?

鉴于此,您可能需要的不仅仅是String,否则为什么要拥有id?如果他们有不同的id,我无法理解两个员工对象是相同的(即如果他们有多个ID,我会创建一个id的数组,因为名称不是唯一的。)

答案 4 :(得分:0)

HashSetTreeset都不允许重复。

通过理解How do you define a Duplicate!

解释了这种行为

HashSet的

对于HashSet,两个对象的哈希码即使对于相同的名称也是不同的,因此它们不被视为重复。除非覆盖hashCodeequals,否则所有对象都被视为不同/独特


TreeSet中:

您正在提供&#34;复制&#34;的定义。通过覆盖compareTo。即如果名称相同则对象相同

要允许TreeSet中的重复项,请将compareTo更改为

@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;  
    }
  }