繁体   English   中英

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

[英]Why .equals method is failing on two same value objects?

我创建了一个值对象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方法不能在这里工作? 有什么建议么?

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

.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() {
        ...
    }
}

请使用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);
   }

...
}

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

默认情况下.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;
    }

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

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

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

或仅包括一些字段:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM