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,该类可以根据其可变得分进行排序,其唯一性由其用户确定。

这意味着 :


如果我使用Collections.sort()对UserScoring对象的集合进行排序,则希望基于分数按降序排序。我已经重写了compareTo方法。
如果创建一组UserScoring对象,则不需要同一个用户的两个UserScoring对象。我已经覆盖了equals和hashcode方法。


我在这里有两个疑问:
1.返回与用户对象相同的UserScoring对象的哈希码是否错误。在我看来,这肯定是错的。但是它会引起什么问题呢?


每当尝试添加两个相同的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?

最佳答案

返回与用户对象相同的UserScoring对象的哈希码是否错误。在我看来,这肯定是错的。但是它会引起什么问题呢?
  


没错在这种情况下,我们说UserScoring对象的“身份”是关联的User对象。但是,这要求您的equals()方法还必须遵守此身份约定,因此必须将其实现为return Objects.equal( this.user, other.user )


  
  有什么方法可以确保在尝试添加同一用户的两个UserScoring对象时,将得分较高的UserScoring对象保留在集合中。
  


我认为没有任何方法可以使用未经修改的HashSet来自动执行此操作,但是您可以提供自己的Set装饰器(调用它,例如RankingSet),该装饰器将针对正在添加的对象与基础并保持较高的排名。 (在您的情况下,排名是得分。)您可以在interwebz上查找CollectionDecorator,该集合可用于减少所需做的工作:它将使您仅覆盖Set方法并使其余方法将委托给基础Set

由于您需要能够比较add()对象,因此您可能会遇到的另一个问题是UserScoring方法与equals()返回的结果不一致。解决此问题的一种方法是不使Comparable.compareTo()具有可比性,而是实现一个单独的UserScoring,该Comparator根据其得分比较UserScoring对象。

(因此,RankingSet需要接收这样的Comparator作为构造函数参数。)

09-25 22:24