我的 equals 和 hashcode 是否必须基于 compareTo 方法实现?

Do my equals and hashcode must be implemented based on compareTo method?

class Ngram implements Comparable<Ngram>{
    String name;
    int count;

    public Ngram(String name, int count){
       this.name = name;
       this.count = count;
    }

    ...

   @Override
   public int compareTo(Ngram other){
        return Integer.compare(this.count, other.count);
   }
}

我的class只有compareTo()方法,只用'count'变量比较。如果我使用 Ngram 作为 Map 的键,是否意味着在向地图插入新对象时只会考虑 'count'? 如果我想在class中加入equals()和hashcode(),是否只能在实现中使用'count'进行比较?

我真正的问题是,在确定Map的key时,我想使用"name"和"count"的组合,但是在对map或list中的元素进行排序时,我只想使用 'count' 进行排序。在这种情况下,似乎我的 equals 和 hash code 方法必须同时使用 'name' 和 'count' 作为比较标准,但是对于排序,我只想在 compareTo 方法中使用 'count' .如何实现这个双重目的?这个需求有意义吗?

我是否必须创建两个几乎相同的 classes 才能实现目标?两个 classes 之间的唯一区别是 hashcode、equals 和 compareTo() 的实现。是吗?

如果您想使用此 class 作为地图的键,您需要实施 equals() 和 hashcode(),这不是一个选项。

地图根本不使用compareTo()。它的唯一目的是对元素进行排序,地图是无序的。

要使用此 class 作为键,您需要确保所考虑的两个 equals 对象具有相同的 hashCode。确保在构造相等性和哈希码时使用相同的字段。

关于您的 class 最后一点:这个计数变量让我有点害怕。要使用 class 作为映射的键,您需要确保在计算 hashCode 时考虑的字段中的 none 可以更改。如果键的字段在将其放入地图的那一刻与您想要取回它的那一刻之间发生变化,那么 hashCode 将发生变化,这是一个问题,因为 Map 依赖 hashCode 在内部找到您的值。

如果要将对象放入集合中,如列表、映射、集合等,则必须实现 hashCode/equals。例如,集合需要知道对象是否存在;列表需要知道如何调用 contains();当然,HashMap 集合需要知道如何散列。

对排序没有直接影响,因为排序是由 ComparableComparator 接口完成的,但是为 Collection 添加 hashCode/equals 实现总是一个好主意用法。多个库和 IDE 提供自动生成或快速实施。

顺便说一下,两者应该始终一起实施——关于这方面的很多资源。