【问题标题】:Java - equals() and hashCode() implementationJava - equals() 和 hashCode() 实现
【发布时间】:2019-06-02 08:46:42
【问题描述】:

我有一个类 PointDensity 实现为:

import java.sql.Date;

public class PointDensity {

    private int id_place;

    private String algorithm;

    private Date mission_date;

    private int mission_hour;

    private int x;

    private int y;

    public PointDensity(int id_place, String algorithm, Date mission_date, int mission_hour, int x, int y) {

        this.id_place = id_place;
        this.algorithm = algorithm;
        this.mission_date = mission_date;
        this.mission_hour = mission_hour;
        this.x = x;
        this.y = y;
    }


    @Override
    public boolean equals(Object obj){
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        PointDensity other = (PointDensity) obj;
        return id_place == other.id_place
            && algorithm.equals(other.algorithm) 
            && mission_date.equals(other.mission_date)

            && mission_hour == other.mission_hour
            && x == other.x
            && y== other.y;
    }

    @Override
    public int hashCode(){
        final int prime = 31;
        int result = 1;
        result = prime * result + y;
        result = prime * result + ((algorithm == null) ? 0 : algorithm.hashCode());
        result = prime * result + x;
        result = prime * result + ((mission_date == null) ? 0 : mission_date.toString().hashCode());
        result = prime * result + mission_hour;
        result = prime * result + id_place;
        return result;
    }
}

我读了一些东西并从数据库中获取值。然后我想使用 HashMap() 来将 PointDensity 对象存储为键,并将其遇到的时间存储为值。但是,它永远不会发现对象是相同的。

    Map<PointDensity, Integer> pointDensities = new HashMap<>();
    while (resultSet.next()){
        PointDensity pointDensity = 
            new PointDensity(
                resultSet.getInt(1), 
                resultSet.getString(2),
                new Date(timestampValues.getLong(i)), 
                new java.util.Date(timestampValues.getLong(i)).getHours(),
                xValues.getInt(i), 
                yValues.getInt(i)
            );  
        if (pointDensities.containsKey(pointDensity)){
            //IT NEVER ENTERS HERE!!!
            System.out.println("exists");
            int times = pointDensities.get(pointDensity);
            pointDensities.replace(pointDensity, times++);
        }else{
            pointDensities.put(pointDensity, 1);
        }
    }        

提前致谢:)

【问题讨论】:

  • 如果有错误,既不是在equals也不是在hashCode,这似乎是正确实现的。问题一定出在从数据库读取数据的代码中,我发现您多次读取同一列很可疑。 i 变量是什么?
  • 可能与您的问题无关,但pointDensities.replace(pointDensity, times++); 什么也不做。与...replace(..., times) 相同。你的意思可能是times+1
  • 我和 Federico 在一起,当我尝试时,代码对我有用。错误一定出在您没有向我们展示的代码中,或者出在数据库数据中。
  • 顺便说一句:您的hashCode 方法检查引用字段中的空值,但equals 方法不允许它们(因为您取消引用例如algorithm.equals)。您应该使它们保持一致。
  • 我也怀疑你在hashCode 中使用Date.toString().hashCode(),在equals 中使用Date.equals。虽然人们可能期望使用这些进行比较是相同的,但它们可能不是吗?此外,您似乎正在使用已弃用的 Date.getHours() 方法 - 由于时区不同,这很容易出错。

标签: java dictionary data-structures hashmap hashcode


【解决方案1】:

以下代码对我有用,您的 hashcodeequals 方法似乎没问题。错误必须在您没有向我们展示的代码中,或在数据库数据本身中。

    public static void main( String[] args ) {
       Map<PointDensity, Integer> pointDensities = new HashMap<>();
       PointDensity pointDensity = new PointDensity( 10, "TEST",
               new Date( 3, 1, 2019 ), new java.util.Date().getHours(),
               42, 24 );
       pointDensities.put( pointDensity, 1 );
       System.out.println( "pointDensity equal to self:"
               + pointDensity.equals( pointDensity ) );
       if( pointDensities.containsKey( pointDensity ) ) {

          //IT NEVER ENTERS HERE!!!
          System.out.println( "exists" );
          int times = pointDensities.get( pointDensity );
          pointDensities.replace( pointDensity, times++ );
       } else {
          pointDensities.put( pointDensity, 1 );
       }
    }
}

输出:

run:
pointDensity equal to self:true
exists
BUILD SUCCESSFUL (total time: 0 seconds)

【讨论】:

  • 更适合作为评论,而不是答案。
  • 也许,但我想展示我的代码。如果 OP 对我测试他们的代码的方式有任何意见,我想了解他们的观点。
  • 感谢大家的帮助,我发现问题出在哪里...在 equals() 中进行比较时,我正在比较 Date 对象(以毫秒为单位的时间戳),这在我的数据测试中显然没有重复.因为我想检查日期而不是时间戳,所以我将其更改为字符串,然后工作正常:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
相关资源
最近更新 更多