class UserScoring implements Comparable<UserScoring> {
User user;
int score;
UserScoring(User user, int score) {
this.user = user;
this.score = score;
}
@Override
public int compareTo(UserScoring o) {
if (this.score < o.score) {
return 1;
}
else if (this.score == o.score) {
return 0;
}
return -1;
}
@Override
public int hashCode() {
return user.hashCode();
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final UserScoring other = (UserScoring) obj;
return user.equals(other.user);
}
}
我想创建一个类UserScoring
,可以根据其变量得分进行排序,其唯一性由用户决定。
这意味着:
我有两个疑问: 1.返回UserScoring对象的哈希码与User对象相同是错误的。这对我来说肯定是错的。但它可能导致的问题是什么?
是否有任何方法可以确保只要有更高分数的UserScoring对象保留在集合中(并且每当尝试添加时,分数较低的对象被驱逐或不被添加)同一用户的两个UserScoring对象。
UserScoring us1 = new UserScoring(u1, 1000);
UserScoring us2 = new UserScoring(u1, 100);
Set<UserScoring> set = new HashSet<>();
set.add(us1);
set.add(us2);
这个集合如何包含us1而不是us2?
答案 0 :(得分:1)
- 返回UserScoring对象的哈希码与User对象相同是错误的。这对我来说肯定是错的。但它可能导致的问题是什么?
醇>
没错。在这种情况下,我们说UserScoring
对象的“标识”是关联的User
对象。但是,这要求您的equals()
方法也必须遵守此身份约定,因此必须将其实现为return Objects.equal( this.user, other.user )
。
- 当试图添加同一用户的两个UserScoring对象时,是否有任何方法可以确保较高分数的UserScoring对象保留在集合中。
醇>
我不认为有任何方法可以使用未修改的HashSet自动执行此操作,但您可以提供自己的Set
装饰器(称为RankingSet
),它会检查要添加的对象已存在于基础Set
中的对象并保留具有更高排名的对象。 (在您的情况下,排名是得分。)您可以查看interwebz的CollectionDecorator,您可以使用它来减少您需要执行的工作量:它将使您只能覆盖add()
方法并将其余方法委托给基础Set
由于您需要能够比较UserScoring
个对象,因此您可能遇到的另一个问题是equals()
方法与Comparable.compareTo()
返回的结果不一致。解决此问题的一种方法是通过 不 使UserScoring
具有可比性,而是实现一个单独的Comparator
,用于比较基于的UserScoring
个对象他们的分数。
(因此,RankingSet
需要接收这样的Comparator
作为构造函数参数。)