重写hashcode方法以返回类

时间:2017-04-10 07:45:53

标签: java set hashcode

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. 如果我使用Collections.sort()对UserScoring对象进行排序,我希望按降序排序。我已经覆盖了compareTo方法。
  2. 如果我创建了一组UserScoring对象,我不想要同一个用户的两个UserScoring对象。我已经覆盖了equals和hashcode方法。
  3. 我有两个疑问: 1.返回UserScoring对象的哈希码与User对象相同是错误的。这对我来说肯定是错的。但它可能导致的问题是什么?

    1. 是否有任何方法可以确保只要有更高分数的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);
      
    2. 这个集合如何包含us1而不是us2?

1 个答案:

答案 0 :(得分:1)

  
      
  1. 返回UserScoring对象的哈希码与User对象相同是错误的。这对我来说肯定是错的。但它可能导致的问题是什么?
  2.   

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

  
      
  1. 当试图添加同一用户的两个UserScoring对象时,是否有任何方法可以确保较高分数的UserScoring对象保留在集合中。
  2.   

我不认为有任何方法可以使用未修改的HashSet自动执行此操作,但您可以提供自己的Set装饰器(称为RankingSet),它会检查要添加的对象已存在于基础Set中的对象并保留具有更高排名的对象。 (在您的情况下,排名是得分。)您可以查看interwebz的CollectionDecorator,您可以使用它来减少您需要执行的工作量:它将使您只能覆盖add()方法并将其余方法委托给基础Set

由于您需要能够比较UserScoring个对象,因此您可能遇到的另一个问题是equals()方法与Comparable.compareTo()返回的结果不一致。解决此问题的一种方法是通过 使UserScoring具有可比性,而是实现一个单独的Comparator,用于比较基于的UserScoring个对象他们的分数。

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