为什么.equals方法在两个相同的值对象上失败?

时间:2011-07-29 19:17:16

标签: java unit-testing equals

我创建了一个值对象MarketVO,并且此值对象的两个实例具有相同的元素,并且每个元素的值相同。

我的价值对象类是:

public class MarketVO {

    private double floatAmt;
    private Date marketDate;
    private long marketCap;
}

以下是值:

returnedData:

FloatAmt: 247657.5418618201, MarketCap: 5249164,
MarketDate: 2011-07-29 00:00:00.0 

expectedData:

FloatAmt: 247657.5418618201, MarketCap: 5249164, 
MarketDate: 2011-07-29 00:00:00.0

现在在我的单元测试类中,我想断言我的返回和预期类型是相同的,包含相同顺序的相同值,所以我正在做类似的事情

assertTrue(returnedData.equals(expectedData)),现在返回false值,但如果我这样做

assertEquals(testObject.getfloatAmt(), testObject2.getfloatAmt());
assertEquals(testObject.getmarketCap(), testObject2.getmarketCap());
assertEquals(testObject.getmarketDate(), testObject2.getmarketDate());

此测试通过,所以我不确定为什么.equals方法在这里不起作用?有什么建议吗?

更新:我想在此强调我们正在使用它来执行 单元测试

7 个答案:

答案 0 :(得分:11)

.equals的默认实现比较了对象引用,而不是对象内容。

您可能希望覆盖equals(和hashCode)方法。像这样:

public class MarketVO {

    private double floatAmt;
    private Date marketDate;
    private long marketCap;

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof MarketVO))
            return false;
        MarketVO other = (MarketVO) o;
        return other.floatAmt == floatAmt &&
               other.marketDate.equals(marketDate) &&
               other.marketCap == marketCap;
    }

    @Override
    public int hashCode() {
        ...
    }
}

答案 1 :(得分:3)

使用org.apache.commons库,它为您提供了复杂的方法来很好地实现这些有价值的方法。同一个库也包含ToStringBuilder,非常方便。

Maven依赖关系=> commons-lang3(org.apache.commons)

class WhatEver{
...

   @Override
   public int hashCode() {
       return HashCodeBuilder.reflectionHashCode(this, false);
   }


   @Override
   public boolean equals(Object obj) {
       return EqualsBuilder.reflectionEquals(this, obj, false);
   }

...
}

答案 2 :(得分:2)

equals方法不起作用,因为您没有根据所需行为覆盖它。 Object(您的类继承自的)的默认行为是比较引用。两个不同的实例具有不同的引用,因此equals失败。

答案 3 :(得分:2)

默认情况下.equals()会检查身份,而不是相等。更改并将此代码添加到您的班级

 @Override
    public boolean equals(Object o) {
        if(this == o) {
            return true;
        }
        if(o == null || getClass() != o.getClass()) {
            return false;
        }

        MarketVO marketVO = (MarketVO) o;

        if(Double.compare(marketVO.floatAmt, floatAmt) != 0) {
            return false;
        }
        if(marketCap != marketVO.marketCap) {
            return false;
        }
        if(marketDate != null ? !marketDate.equals(marketVO.marketDate) : marketVO.marketDate != null) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int result;
        long temp;
        temp = floatAmt != +0.0d ? Double.doubleToLongBits(floatAmt) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        result = 31 * result + (marketDate != null ? marketDate.hashCode() : 0);
        result = 31 * result + (int) (marketCap ^ (marketCap >>> 32));
        return result;
    }

答案 4 :(得分:1)

我强烈建议您使用Lombok注释@EqualsAndHashcode,这有助于避免使用equalshashCode方法的错误。

默认情况下,它使用所有非静态非瞬态字段创建equals和hashCode方法,但您可以指定其他行为,例如排除某些字段:

@EqualsAndHashCode(exclude={"fieldsThat", "dontMather"})

或仅包含一些字段:

@EqualsAndHashCode(of={"onlyFields", "thatMather"})

答案 5 :(得分:0)

哈希是不同的,因为它们是不同的实例

答案 6 :(得分:0)

更确切地说,默认行为是比较内存中的对象地址(如果引用指向内存中完全相同的对象(地址),则为true)。因此,覆盖这些方法可以获得所需的行为。