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

时间:2017-10-11 23:25:09

标签: java hashcode

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

我的班级只有compareTo()方法,该方法仅使用&#39; count&#39;变量来比较。如果我使用Ngram作为Map的关键,那是否仅表示&#39; count&#39;将新对象插入地图时会考虑? 如果我想在类中添加equals()和hashcode(),我必须只使用&#39; count&#39;在实施中进行比较?

我真正的问题是,在决定Map的键时,我想使用&#34; name&#34;的组合。和&#34; count&#34;,但在对地图或列表中的元素进行排序时,我想使用&#39; count&#39;仅用于分类目的。在这种情况下,似乎我的等号和哈希码方法必须同时使用&#39; name&#39;和&#39;计算&#39;作为比较标准,但对于排序,我只想使用&#39; count&#39;在compareTo方法中。如何实现这个双重目的?这种需求是否有意义?

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

2 个答案:

答案 0 :(得分:0)

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

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

顺便说一下,两者应该一起实施 - 很多资源都可以实现。

答案 1 :(得分:-2)

如果你想使用这个类作为地图的键,你需要实现equals()和hashcode(),它不是一个选项。

地图根本不使用compareTo()。它的唯一目的是订购元素,地图是无序的。

要将此类用作键,您需要确保两个等于的对象具有相同的hashCode。确保在构造相等性和哈希码时使用相同的字段。

关于你班级的最后一点说明:这个计数变量吓到了我一点。要将类用作映射的键​​,您需要确保计算hashCode时不考虑任何字段都可以更改。如果关键字的字段在您将其放入地图的那一刻与您想要获取它的那一刻之间发生变化,那么hashCode将会发生变化,这是一个问题,因为Map依赖于hashCode来在内部找到您的值。