Java 删除树集中的重复项
我一直在为我的项目使用ArrayList来存储板球队球员并订购他们。 我开始考虑使用TreeSet,因为它具有删除重复项的优势。 然而,我遇到的问题是,例如,如果我创建了以下两个玩家:Java 删除树集中的重复项,java,collections,arraylist,treeset,Java,Collections,Arraylist,Treeset,我一直在为我的项目使用ArrayList来存储板球队球员并订购他们。 我开始考虑使用TreeSet,因为它具有删除重复项的优势。 然而,我遇到的问题是,例如,如果我创建了以下两个玩家: P p1 = new P("Jack","Daniel",33(age),180(height),78(weight),41(games played),2300 (runs scored),41(dismisses)) P p2 = new P("Jack","Daniel",37(age),185(heigh
P p1 = new P("Jack","Daniel",33(age),180(height),78(weight),41(games played),2300
(runs scored),41(dismisses))
P p2 = new P("Jack","Daniel",37(age),185(height),79(weight),45(games played),2560
(runs scored),45(dismisses))
请注意,这两个玩家的名字和姓氏相同,但其他所有东西都不同。当我尝试将这两个玩家添加到树集时,由于名字的相似性,它认为他们是重复的,并删除了第二个。显然,我不希望这种情况发生,我希望只有当一名球员拥有的一切都与另一名球员相同,而不仅仅是名字和姓氏时,球队才会将他除名
有没有办法做到这一点
另外,我的树集接受一个玩家对象。最初,这个答案忽略了这样一个事实,即
树集
基于compareTo()
而不是equals()
进行比较。已对此进行了编辑
您需要为您的播放器对象正确定义equals()
、hashCode()
和compareTo()
。(因为它是一个树集
而不是哈希集
,所以实现hashCode()
并不重要,但这是一个很好的实践。)
Equals和hashCode需要考虑所有字段。Eclipse可以为您自动生成一个类似于此的(源代码>生成hashcode和equals)
如果您已经有了一个不使用所有字段的自然排序顺序,那么您可以为TreeSet
提供一个自定义比较器。然而,即使您真的只想按字段的子集进行排序,也并没有什么可以阻止您按所有字段进行排序(不感兴趣的字段只扮演一部分,感兴趣的部分是相同的)。这里需要注意的重要一点是,TreeSet
不是通过equals()
方法,而是通过compareTo()==0
来确定相等性
下面是一个equals()示例:
下面是哈希代码:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.age;
result = prime * result + this.dismisses;
result = prime * result + this.family.hashCode());
result = prime * result + this.games;
result = prime * result + this.given.hashCode());
result = prime * result + this.height;
result = prime * result + this.runs;
result = prime * result + this.weight;
return result;
}
最后,这里有一个比较:
public int compareTo(Player that)
{
int result;
result = this.family.compareTo(that.family);
if (result != 0) // is the family name different?
{
return result; // yes ... use it to discriminate
}
result = this.given.compareTo(that.given);
if (result != 0) // is the given name different?
{
return result; // yes ... use it to discriminate
}
result = this.age - that.age; // is the age different?
if (result != 0)
{
return result; // yes ... use it to discriminate
}
... (and so on) ...
... with the final one ...
return this.dismisses - that.dismisses; // only thing left to discriminate by
}
最初,这个答案忽略了一个事实,TreeSet
基于compareTo()
,而不是equals()
进行比较。已对此进行了编辑
您需要为您的播放器对象正确定义equals()
、hashCode()
和compareTo()
。(因为它是一个树集
而不是哈希集
,所以实现hashCode()
并不重要,但这是一个很好的实践。)
Equals和hashCode需要考虑所有字段。Eclipse可以为您自动生成一个类似于此的(源代码>生成hashcode和equals)
如果您已经有了一个不使用所有字段的自然排序顺序,那么您可以为TreeSet
提供一个自定义比较器。然而,即使您真的只想按字段的子集进行排序,也并没有什么可以阻止您按所有字段进行排序(不感兴趣的字段只扮演一部分,感兴趣的部分是相同的)。这里需要注意的重要一点是,TreeSet
不是通过equals()
方法,而是通过compareTo()==0
来确定相等性
下面是一个equals()示例:
下面是哈希代码:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.age;
result = prime * result + this.dismisses;
result = prime * result + this.family.hashCode());
result = prime * result + this.games;
result = prime * result + this.given.hashCode());
result = prime * result + this.height;
result = prime * result + this.runs;
result = prime * result + this.weight;
return result;
}
最后,这里有一个比较:
public int compareTo(Player that)
{
int result;
result = this.family.compareTo(that.family);
if (result != 0) // is the family name different?
{
return result; // yes ... use it to discriminate
}
result = this.given.compareTo(that.given);
if (result != 0) // is the given name different?
{
return result; // yes ... use it to discriminate
}
result = this.age - that.age; // is the age different?
if (result != 0)
{
return result; // yes ... use it to discriminate
}
... (and so on) ...
... with the final one ...
return this.dismisses - that.dismisses; // only thing left to discriminate by
}
班级学生实施可比较的{
字符串名;
公立学生(字符串名称){
this.name=name;
}
公共字符串toString(){
返回名称;
}
公共国际比较(学生/学生){
如果(!this.name.equals(gStudent.getName()))
返回1;
返回0;
}
私有字符串getName(){
返回名称;
}
}
班级学生实施可比较的{
字符串名;
公立学生(字符串名称){
this.name=name;
}
公共字符串toString(){
返回名称;
}
公共国际比较(学生/学生){
如果(!this.name.equals(gStudent.getName()))
返回1;
返回0;
}
私有字符串getName(){
返回名称;
}
}
TreeSet实例使用其compareTo(或compare)方法执行所有元素比较,因此,从集合的角度来看,此方法认为相等的两个元素是相等的。即使集合的顺序与equals不一致,集合的行为也是定义良好的;它只是没有遵守Set接口的总合同
来自Java平台标准版8文档TreeSet
part
TreeSet实例使用其compareTo(或compare)方法执行所有元素比较,因此,从集合的角度来看,此方法认为相等的两个元素是相等的。即使集合的顺序与equals不一致,集合的行为也是定义良好的;它只是没有遵守Set接口的总合同
来自Java平台标准版8文档TreeSet
part.是否有一个示例可以帮助我?我有一个compareTo方法,可以按名称和ID对玩家进行排序。我是否需要使用其他字段,如玩的游戏,在这种情况下,你需要确保如果a
和b
是不同的玩家,那么a.compareTo(b)!=0
和b.与(a)!=0
。您可以通过确保ID是唯一的来确保这一点。@trutheality如果您能给出一个简单的示例,我可以从中学习,或者更详细地解释,因为我有点困惑-抱歉,但对Java来说有点陌生有没有一个示例可以帮助我?我有一个compareTo方法,可以按名称和ID对玩家进行排序?我需要使用另一个吗在这种情况下,你需要确保如果a
和b
是不同的游戏,那么在比较方法中的游戏、得分等字段