Почему метод .equals не работает на двух объектах с одинаковыми значениями? - PullRequest
2 голосов
/ 29 июля 2011

Я создал объект значения MarketVO, и два экземпляра этого объекта значения имеют одинаковые элементы и одинаковые значения для каждого элемента.

Мой класс объекта значения:

public class MarketVO {

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

Вот значения:

ReturnData:

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

Ожидаемые данные:

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 ]

11 голосов
/ 29 июля 2011

Реализация по умолчанию .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() {
        ...
    }
}
3 голосов
/ 01 ноября 2012

Используйте скорее библиотеку 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 голосов
/ 29 июля 2011

По умолчанию .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;
    }
2 голосов
/ 29 июля 2011

Метод equals не работает, поскольку вы не изменили его для требуемого поведения.Поведение по умолчанию Object (от которого наследуется ваш класс) - сравнивать ссылки.Два разных экземпляра имеют разные ссылки, поэтому equals терпит неудачу.

1 голос
/ 04 августа 2012

Я настоятельно рекомендую использовать Lombok аннотацию @EqualsAndHashcode, это действительно помогает избежать ошибок с equals и hashCode методами.

Создает равныеи методы hashCode, использующие все нестатические непереходные поля по умолчанию, но вы можете указать другое поведение, например, исключение некоторых полей:

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

или включение только некоторых полей:

@EqualsAndHashCode(of={"onlyFields", "thatMather"})
0 голосов
/ 29 июля 2011

Точнее, поведение по умолчанию заключается в сравнении адресов объектов в памяти (true, если ссылки указывают на один и тот же объект (адрес) в памяти).Поэтому переопределите эти методы, чтобы получить требуемое поведение.

0 голосов
/ 29 июля 2011

хэши разные, потому что это разные экземпляры

...