java - 重写 hashcode 方法以返回类中变量的 hashcode

标签 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 方法。

我这里有两个疑问: 1.返回UserScoring对象的hashcode与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?

    最佳答案

    1. Is it wrong to return the hashcode of the UserScoring object the same as the User object. It sure looks wrong to me. But what are the problems it can cause?

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

    1. Is there any way at all to make sure that the UserScoring object of the higher score is kept in the set whenever there is an attempt to add two UserScoring objects of the same user.

    我认为没有任何方法可以使用未修改的 HashSet 来自动执行此操作,但您可以提供自己的 Set 装饰器(例如,将其称为 RankingSet)根据底层 Set 中已有的对象检查添加的对象,并保留排名较高的对象。 (您的案例中的排名就是分数。)您可以在 interwebz 上查找 CollectionDecorator,您可以使用它来减少您需要做的工作量:它使您能够只覆盖 add() 方法,并让其余方法委托(delegate)给底层 Set

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

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

    关于java - 重写 hashcode 方法以返回类中变量的 hashcode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43317482/

    相关文章:

    java - 使用 GLCM 进行图像处理

    javascript - 创建一系列独特的组合

    java - 如何在Java中根据主题划分RDF三元组

    java - Play Framework 2.2 Java Iteratee - 响应式上传

    java - 删除多对多关系中的所有内容 (JPA)

    sql - 关系型数据库查询问题

    mysql - 查询 SQL 集

    java - 如何在与Equal和hashcode一致的情况下实现compareTo()方法

    java - "Normalizing"BigDecimal 的哈希码 : howto?

    java - 使用 CellTable 作为结果集