TreeSet 正在向 Set 添加重复值
TreeSet is adding duplicate values to the Set
我正在解决一个问题。我必须创建一个自定义 Employee 对象的 TreeSet,其中数据应按薪水排序,但员工 ID 必须是唯一的。我知道 equals() 和 hashCode() 方法对 TreeSet 不起作用,我们需要在 compareTo() 方法中编写我们的对象是否相等的逻辑。我正在检查两个员工 ID 是否相等,然后 return 0,表示不应添加对象。
但是输出没有达到预期效果,因为还添加了具有相同员工 ID 的员工。我尝试对此进行调试,但没有得到正确的答案。
这是代码。
public class Employee implements Comparable<Employee>{
int empId;
String empName;
double salary;
public Employee() {
super();
}
public Employee(int empId, String empName, double salary) {
super();
this.empId = empId;
this.empName = empName;
this.salary = salary;
}
@Override
public int hashCode() {
return empId;
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null || this.getClass() != o.getClass()) return false;
Employee e = (Employee) o;
return (this.empId == e.empId);
}
@Override
public String toString() {
return empId + " " + empName + " " + salary;
}
@Override
public int compareTo(Employee e) {
if(empId == e.empId)
return 0;
if(this.salary < e.salary) {
return -1;
}
else {
return 1;
}
}
}
程序的主要方法
public static void main(String[] args) {
TreeSet<Employee> eSet = new TreeSet<>();
eSet.add(new Employee(1, "john", 20000));
eSet.add(new Employee(2, "jim", 10000));
eSet.add(new Employee(9, "mike", 50000));
eSet.add(new Employee(3, "jack", 30000));
eSet.add(new Employee(3, "david", 40000));
eSet.add(new Employee(9, "liam", 80000));
eSet.add(new Employee(9, "brad", 89000));
eSet.add(new Employee(3, "jason", 85000));
eSet.add(new Employee(2, "ted", 35000));
for(Employee e: eSet) {
System.out.println(e);
}
}
以上程序的输出结果为
2 jim 10000.0
1 john 20000.0
3 jack 30000.0
2 ted 35000.0
9 mike 50000.0
3 jason 85000.0
在这里,您可以看到具有相同员工 ID 的员工被添加到 TreeSet,这是不应该发生的。如果我使用的是 HashSet,问题就解决了,但我必须使用 TreeSet 来实现它才能获得排序的行为。
谁能指导我哪里出错了?
Comparable
的实现违反了 contract of Comparable::compareTo
,特别是这部分:
Finally, the implementor must ensure that x.compareTo(y)==0
implies that signum(x.compareTo(z)) == signum(y.compareTo(z))
, for all z
.
我们可以用下面的代码证明这种违规行为:
final Employee jim = new Employee(2, "jim", 10_000);
final Employee ted = new Employee(2, "ted", 35_000);
final Employee john = new Employee(9, "john", 20_000);
System.out.println("jim compare to ted: " + jim.compareTo(ted));
System.out.println("john compare to jim: " + john.compareTo(jim));
System.out.println("john compare to ted: " + john.compareTo(ted));
导致以下输出:
jim compare to ted: 0
john compare to jim: 1
john compare to ted: -1
我们可以通过从 compareTo
方法中删除薪水并仅按 empId
:
排序来解决这个问题
@Override
public int compareTo(Employee e) {
return Integer.compare(empId, e.empId);
}
我正在解决一个问题。我必须创建一个自定义 Employee 对象的 TreeSet,其中数据应按薪水排序,但员工 ID 必须是唯一的。我知道 equals() 和 hashCode() 方法对 TreeSet 不起作用,我们需要在 compareTo() 方法中编写我们的对象是否相等的逻辑。我正在检查两个员工 ID 是否相等,然后 return 0,表示不应添加对象。
但是输出没有达到预期效果,因为还添加了具有相同员工 ID 的员工。我尝试对此进行调试,但没有得到正确的答案。
这是代码。
public class Employee implements Comparable<Employee>{
int empId;
String empName;
double salary;
public Employee() {
super();
}
public Employee(int empId, String empName, double salary) {
super();
this.empId = empId;
this.empName = empName;
this.salary = salary;
}
@Override
public int hashCode() {
return empId;
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null || this.getClass() != o.getClass()) return false;
Employee e = (Employee) o;
return (this.empId == e.empId);
}
@Override
public String toString() {
return empId + " " + empName + " " + salary;
}
@Override
public int compareTo(Employee e) {
if(empId == e.empId)
return 0;
if(this.salary < e.salary) {
return -1;
}
else {
return 1;
}
}
}
程序的主要方法
public static void main(String[] args) {
TreeSet<Employee> eSet = new TreeSet<>();
eSet.add(new Employee(1, "john", 20000));
eSet.add(new Employee(2, "jim", 10000));
eSet.add(new Employee(9, "mike", 50000));
eSet.add(new Employee(3, "jack", 30000));
eSet.add(new Employee(3, "david", 40000));
eSet.add(new Employee(9, "liam", 80000));
eSet.add(new Employee(9, "brad", 89000));
eSet.add(new Employee(3, "jason", 85000));
eSet.add(new Employee(2, "ted", 35000));
for(Employee e: eSet) {
System.out.println(e);
}
}
以上程序的输出结果为
2 jim 10000.0
1 john 20000.0
3 jack 30000.0
2 ted 35000.0
9 mike 50000.0
3 jason 85000.0
在这里,您可以看到具有相同员工 ID 的员工被添加到 TreeSet,这是不应该发生的。如果我使用的是 HashSet,问题就解决了,但我必须使用 TreeSet 来实现它才能获得排序的行为。
谁能指导我哪里出错了?
Comparable
的实现违反了 contract of Comparable::compareTo
,特别是这部分:
Finally, the implementor must ensure that
x.compareTo(y)==0
implies thatsignum(x.compareTo(z)) == signum(y.compareTo(z))
, for allz
.
我们可以用下面的代码证明这种违规行为:
final Employee jim = new Employee(2, "jim", 10_000);
final Employee ted = new Employee(2, "ted", 35_000);
final Employee john = new Employee(9, "john", 20_000);
System.out.println("jim compare to ted: " + jim.compareTo(ted));
System.out.println("john compare to jim: " + john.compareTo(jim));
System.out.println("john compare to ted: " + john.compareTo(ted));
导致以下输出:
jim compare to ted: 0
john compare to jim: 1
john compare to ted: -1
我们可以通过从 compareTo
方法中删除薪水并仅按 empId
:
@Override
public int compareTo(Employee e) {
return Integer.compare(empId, e.empId);
}