java.util.TreeSet没有遵循Set没有重复合同?

时间:2016-02-29 17:40:25

标签: java collections set override treeset

我之前看到过这个问题,但从那时起我没有得到很多帮助,所以我再次问我真正的问题。

我想根据对象的所有属性(这里Name, id, CompanyName, Address)删除重复对象。这是我的代码:

package CollectionDemo;
import java.util.TreeSet;
class Employee implements Comparable<Employee> {
    String Name;
    int id;
    String CompanyName;
    String Address;
    public Employee(String Name,int id,String CompanyName,String Address) {
        this.Name = Name;
        this.id = id;
        this.CompanyName = CompanyName;
        this.Address = Address;
    }
    @Override
    public String toString() {
        return "Name : "+this.Name+"\tID : "+this.id+"\tCompanyName : "+this.CompanyName+"\tAddress : "+this.Address;
    }
    @Override
    public int compareTo(Employee obj){
        if((this.Name.equals(obj.Name))&&(this.id==obj.id)&&(this.CompanyName.equals(obj.CompanyName))&&(this.Address.equals(obj.Address))) {
            return 0;
        }
        return 1;
    }
}
public class DemoTreeset {

    public static void main(String[] args) {
        TreeSet<Employee> ts = new TreeSet<>();
        ts.add(new Employee("Panda", 11, "Google", "California"));
        ts.add(new Employee("Panda", 12, "Google", "California"));
        ts.add(new Employee("Panda", 11, "Google", "California"));
        ts.add(new Employee("Panda", 13, "Google", "California"));
        ts.add(new Employee("Panda", 11, "Google", "California"));
        ts.add(new Employee("Panda", 11, "Infosys", "India"));
        ts.add(new Employee("Panda", 11, "Google", "California"));
        ts.add(new Employee("Panda", 11, "Infosys", "India"));
        ts.add(new Employee("Panda", 12, "Google", "California"));
        ts.add(new Employee("Panda", 11, "Google", "California"));
        ts.add(new Employee("Panda", 13, "Google", "California"));
        ts.add(new Employee("Panda", 11, "Google", "California"));
        ts.add(new Employee("Panda", 11, "Infosys", "India"));
        ts.add(new Employee("Panda", 11, "Google", "California"));
        ts.add(new Employee("Panda", 11, "Infosys", "India"));
        for(Employee  e : ts) {
            System.out.println(e);
        }
    }
}

输出:

Name : Panda    ID : 11 CompanyName : Google    Address : California 
Name : Panda    ID : 12 CompanyName : Google    Address : California
Name : Panda    ID : 13 CompanyName : Google    Address : California
Name : Panda    ID : 11 CompanyName : Google    Address : California
Name : Panda    ID : 11 CompanyName : Infosys   Address : India
Name : Panda    ID : 13 CompanyName : Google    Address : California

我知道TreeSet使用 compareTo() 代替 equals() 来比较对象,所以我覆盖了它,但正如您所见输出,它删除了一些重复但不是全部。我不明白为什么我得到这个输出。为什么不删除所有重复项而只删除其中的少数?

2 个答案:

答案 0 :(得分:3)

当您实施Comparable接口定义的合同时,您需要尊重合同从实施中要求的所有方面。部分尊重合同会导致奇怪的行为,就像您在案件中遇到的那样。您实施Comparable合同时明显遗漏的是传递性。来自Comparable.compareTo(...)方法的javadoc

  

实现者还必须确保关系是可传递的:   (x.compareTo(y)>0 && y.compareTo(z)>0)隐含x.compareTo(z)>0

您的实施绝对不具有传递性。

答案 1 :(得分:0)

你可以看一下吗? 输出:

  

姓名:熊猫ID:11公司名称:谷歌地址:加利福尼亚州

     

姓名:熊猫ID:12公司名称:谷歌地址:加利福尼亚州

     

姓名:Panda ID:13公司名称:Google地址:加利福尼亚州

     

姓名:熊猫ID:11公司名称:Infosys地址:印度

package algorithms;

import java.util.TreeSet;

class Employee implements Comparable<Employee> {
String Name;
int id;
String CompanyName;
String Address;

public Employee(String Name,int id,String CompanyName,String Address) {
    this.Name = Name;
    this.id = id;
    this.CompanyName = CompanyName;
    this.Address = Address;
}

@Override
public String toString() {
    return "Name : "+this.Name+"\tID : "+this.id+"\tCompanyName : "+this.CompanyName+"\tAddress : "+this.Address;
}

@Override
public int compareTo(Employee obj){
    final int BEFORE = -1;
    final int EQUAL = 0;
    final int AFTER = 1;

    if (this.equals(obj)) return EQUAL;

    int comparison = this.Name.compareTo(obj.Name);
    if (comparison != EQUAL) return comparison;

    comparison = this.Address.compareTo(obj.Address);
    if (comparison != EQUAL) return comparison;

    comparison = this.CompanyName.compareTo(obj.CompanyName);
    if (comparison != EQUAL) return comparison;

    comparison = ((Integer)(this.id)).compareTo(obj.id);
    if (comparison != EQUAL) return comparison;

    return EQUAL;
}

   @Override 
   public boolean equals(Object aThat) {
       if (this == aThat) return true;
       if (!(aThat instanceof Employee)) return false;

       Employee that = (Employee)aThat;
       return
           ( this.Address.equals(that.Address)) &&
           (this.id == that.id) &&
           ( this.Name.equals(that.Name) ) &&
           ( this.CompanyName.equals(that.CompanyName) )
         ;
   }
}


public class DemoTreeSet {

public static void main(String[] args) {
    TreeSet<Employee> ts = new TreeSet<>();
    ts.add(new Employee("Panda", 11, "Google", "California"));
    ts.add(new Employee("Panda", 12, "Google", "California"));
    ts.add(new Employee("Panda", 11, "Google", "California"));
    ts.add(new Employee("Panda", 13, "Google", "California"));
    ts.add(new Employee("Panda", 11, "Google", "California"));
    ts.add(new Employee("Panda", 11, "Infosys", "India"));
    ts.add(new Employee("Panda", 11, "Google", "California"));
    ts.add(new Employee("Panda", 11, "Infosys", "India"));
    ts.add(new Employee("Panda", 12, "Google", "California"));
    ts.add(new Employee("Panda", 11, "Google", "California"));
    ts.add(new Employee("Panda", 13, "Google", "California"));
    ts.add(new Employee("Panda", 11, "Google", "California"));
    ts.add(new Employee("Panda", 11, "Infosys", "India"));
    ts.add(new Employee("Panda", 11, "Google", "California"));
    ts.add(new Employee("Panda", 11, "Infosys", "India"));
    for(Employee  e : ts) {
        System.out.println(e);
    }
}

}