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

蓝咒 提交于 2019-11-29 15:47:43

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

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

...
}

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.

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

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

the hashes are different because they are different instances

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!