有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重写hashcode方法以返回类中变量的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. 如果我使用集合对UserScoring对象集合进行排序。sort(),我希望根据分数按降序排序。我已经覆盖了相同的compareTo方法
  2. 若我创建了一组UserScoring对象,我不想要同一用户的两个UserScoring对象。我已经重写了equals和hashcode方法

我有两个疑问: 1.返回与用户对象相同的UserScoring对象的哈希代码是否错误。在我看来,这的确是不对的。但它会导致什么问题呢

  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);
    

此集合如何包含us1而不是us2


共 (1) 个答案

  1. # 1 楼答案

    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.

    我不认为有任何方法可以使用未修改的哈希集来自动执行此操作,但您可以提供自己的Set装饰器(称之为RankingSet),它根据底层Set中已经存在的对象检查正在添加的对象,并保持较高级别的对象。(你的排名就是分数。)你可以在interwebz中寻找一个CollectionDecorator,你可以用它来减少你需要做的工作量:它只允许你重写add()方法,并让剩下的方法被委托给基础集合

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

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