Java 删除树集中的重复项

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

我一直在为我的项目使用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(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
是不同的游戏,那么在比较方法中的游戏、得分等字段