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

发布于 2024-11-26 19:22:36 字数 1043 浏览 1 评论 0原文

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

更新:我想在这里强调一下,我们正在使用它来进行单元测试

I have created a value object MarketVO and two instances of this value object have same elements and same value for each element.

My value object class is:

public class MarketVO {

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

Here are the values:

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

Now in my unit test class, I want to assert that my returned and expected type is same containing same value in same order so am doing something like

assertTrue(returnedData.equals(expectedData)), now this is returning false value but if I do

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

this test passes and so am not sure as to why .equals method is not working in here? Any suggestions?

Update: I want to put emphasize here that we are using this for doing Unit Testing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

韬韬不绝 2024-12-03 19:22:36

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

The default implementation of .equals compares object references, not object content.

You probably want to override the equals (and hashCode) methods. Something like this:

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() {
        ...
    }
}
眼趣 2024-12-03 19:22:36

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

...
}

Use rather the org.apache.commons library which gives you sophisticated ways implement those valuable methods well. The same library also contains ToStringBuilder which is very handy too.

Maven dependency => 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);
   }

...
}
夏日落 2024-12-03 19:22:36

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

The equals method doesn't work as you didn't override it for your required behaviour. The default behaviour on Object (which your class inherits from) is to compare references. Two different instances have different references, thus the equals fails.

2024-12-03 19:22:36

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

By default .equals() checks identity and not equality. Change and add this code to your class

 @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;
    }
停滞 2024-12-03 19:22:36

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

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

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

或仅包含某些字段:

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

I highly recommend using Lombok annotation @EqualsAndHashcode, it really helps to avoid bugs with equals and hashCode methods.

It creates equals and hashCode methods using all non-static non-transient fields by default, but you can specify other behaviors like excluding some fields:

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

or including only some fields:

@EqualsAndHashCode(of={"onlyFields", "thatMather"})
最终幸福 2024-12-03 19:22:36

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

the hashes are different because they are different instances

緦唸λ蓇 2024-12-03 19:22:36

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

More precisely the default behaviour is to compare object's addresses in memory (true if the references point to the exactly same object (address) in memory). So override these methods the get the required behaviour.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文