Java 我能够在树集合中插入重复的条目。如何克服这个问题
我有一个名为Employee的类,它将Java 我能够在树集合中插入重复的条目。如何克服这个问题,java,treeset,Java,Treeset,我有一个名为Employee的类,它将employeeName和employeeId作为其成员变量。我正在创建新的Employee对象,然后将其添加到TreeSet中,在那里我希望根据employeeId对其进行排序。但是,如果有相同的雇员名称< /代码>,我认为2个雇员对象是相等的。集合不允许重复。但在这里我可以观察到一种奇怪的行为。这是我的代码。(我在这里不使用getter和setter。我直接访问成员变量。) packagesecondone; 导入java.util.Set; 导入jav
employeeName
和employeeId
作为其成员变量。我正在创建新的Employee对象,然后将其添加到TreeSet
中,在那里我希望根据employeeId
对其进行排序。但是,如果有相同的<代码>雇员名称< /代码>,我认为2个雇员对象是相等的。集合不允许重复。但在这里我可以观察到一种奇怪的行为。这是我的代码。(我在这里不使用getter和setter。我直接访问成员变量。)
packagesecondone;
导入java.util.Set;
导入java.util.TreeSet;
类Employee实现了可比较的{
字符串employeeName;
国际雇员ID;
公共雇员(字符串名称,整数id){
this.employeeName=名称;
this.employeeId=id;
}
公共内部比较(员工环境管理计划){
//将此.employeeName.compareTo(emp.employeeName)返回给emp.employeeName;
返回(this.employeeId-emp.employeeId);
}
@凌驾
公共字符串toString(){
返回(“名称为:“+employeeName+”Emp id为:“+employeeId”);
}
@凌驾
公共布尔等于(对象emp){
if(emp instanceof Employee&((Employee)emp).employeeName==此.employeeName){
返回true;
}
返回false;
}
}
具有可比性的公共类测试集{
/**
*@param args
*/
公共静态void main(字符串[]args){
员工e1=新员工(“A”,1);
雇员e2=新雇员(“A”,2);
员工e3=新员工(“B”,3);
Set=新树集();
增加(e1);
添加(e2);
集合。添加(e3);
系统输出打印项次(套);
}
}
此处,上述代码的输出为,[名称是:Emp id是:1,名称是:Emp id是:2,名称是:B Emp id是:3]
我的第一个问题是,在等式()方法中,我认为如果有相同的雇员名,2个雇员对象是相等的,但是在CuffReto方法中,我使用EnguleID进行排序。在本例中,输出显示employeeName“A”的两个条目。当我考虑2个对象是相同的,如果他们有相同的雇员名称时,TeSESET允许重复的条目。这怎么可能。。?
第二个问题是,在compareTo方法中,如果我使用employeeName进行排序,那么我不会得到相同名称的第二个重复条目。第二种情况下的输出为
[名称为:A Emp id为:1,名称为:B Emp id为:3]
为什么会这样?比较字符串的方式是错误的。看 应该是
(Employee)emp).employeeName.equals(this.employeeName)
问题在于:
((Employee)emp).employeeName== this.employeeName
必须使用equals
方法比较String
s:
((Employee)emp).employeeName.equals(this.employeeName)
指
另外,由于您正在重写equals
方法,所以最好也重写hashCode
方法,如合同中所述:
请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码
附加:由于您使用的是TreeSet
,因此它将使用compareTo
方法,而不是equals
和hashCode
方法。这是因为TreeSet
实现了SortedSet
接口。请参阅javadoc(我的重点):
进一步对其元素提供总排序的集合。元素使用它们的(即实现可比的
)或通常在排序集创建时提供的比较器进行排序
您应根据自己的需要在中实施此方法:
public int compareTo(Employee emp) {
if (this.employeeName.equals(emp.employeeName)) {
return 0;
}
//removed the comparison by subtraction since it will behave wrongly on int overflow
return new Integer(this.employeeId).compareTo(emp.employeeId);
}
由于您正在比较字符串,我建议使用提供帮助程序方法的类来避免null
检查和其他检查。您应该比较string
而不是使用==,而是使用equals()
方法,此外,如果您希望这样做,您还应该重写compareTo
方法以与employeeName
进行比较,而不是与employeeId
进行比较
(Employee)emp).employeeName.equals(this.employeeName)
及
取消对此的注释//返回this.employeeName.compareTo(emp.employeeName);,这不起作用吗?@Piyuesh:是的,它起作用了。如果您使用Eclipse,只需生成equals()和hashCode()。当然,在其他好的IDE中也是如此;-)即使使用equals()方法,我仍然得到相同的输出。我仍在获取重复条目。我在代码中将==改为equals。即使使用equals方法,我仍然得到相同的输出。我仍在获取重复条目。我在代码中将==改为等于。TreeSet
不使用equals
方法进行元素比较。@luigimendoza它使用了。。这就是TreeSet.add文档所告诉我们的?请参考我的答案,了解关于这个主题的更多细节,我不想重复:)@sanbhat:Luiggi Mendoza是对的。它根本不使用equals方法进行比较。连我现在都查过了。删除equals方法,并在Luiggi的答案描述中插入compareTo方法。我编辑了使用equals方法比较两个字符串而不是==的代码。但我还是得到了同样的结果。在compareTo方法中,我不想根据两名员工的姓名对他们进行比较,我的要求是根据他们的Id对员工进行排序。因此,我使用他们的Id在compareTo方法中进行排序。在排序之前,当我说两个对象的名称匹配时,为什么Set允许重复条目?为了满足我的请求,我应该使用哪种结构?@Prasad Response在刷新我的脸并重新思考问题后更新。请注意compareTo
方法的新实现。@Prasad这意味着您首先比较传入的Employee
对象是否与当前的Employee同名
public int compareTo(Employee emp) {
if (this.employeeName.equals(emp.employeeName)) {
return 0;
}
//removed the comparison by subtraction since it will behave wrongly on int overflow
return new Integer(this.employeeId).compareTo(emp.employeeId);
}
(Employee)emp).employeeName.equals(this.employeeName)
public int compareTo(Employee emp) {
return (this.employeeName-emp.employeeName);
}