равенство адресов не выполняется, даже если все поля идентичны - PullRequest
0 голосов
/ 11 февраля 2012

Я создал класс Address, как показано ниже. Затем я хотел проверить равенство двух Address es. Если все поля идентичны, два Address es считаются идентичными.

Так, Я реализовал методы hashCode и equals.

public class Address{

    public String addressLine1;

    public String addressLine2;

    public String city;     

    public String state;

    public String pincode;

    public String phoneNumber;      

    public String country; 

    public Address() {

    }

    public Address(String addressLine1, String addressLine2, String city,
            String state, String pincode, String phoneNumber, String country) {         
        this.addressLine1 = addressLine1;
        this.addressLine2 = addressLine2;
        this.city = city;
        this.state = state;
        this.pincode = pincode;
        this.phoneNumber = phoneNumber;
        this.country = country;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result
                + ((addressLine1 == null) ? 0 : addressLine1.hashCode());
        result = prime * result
                + ((addressLine2 == null) ? 0 : addressLine2.hashCode());
        result = prime * result + ((city == null) ? 0 : city.hashCode());
        result = prime * result + ((country == null) ? 0 : country.hashCode());
        result = prime * result
                + ((phoneNumber == null) ? 0 : phoneNumber.hashCode());
        result = prime * result + ((pincode == null) ? 0 : pincode.hashCode());
        result = prime * result + ((state == null) ? 0 : state.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        System.out.println("equals("+obj);
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        Address other = (Address) obj;
        if (addressLine1 == null) {
            if (other.addressLine1 != null)
                return false;
        } else if (!addressLine1.equals(other.addressLine1))
            return false;
        if (addressLine2 == null) {
            if (other.addressLine2 != null)
                return false;
        } else if (!addressLine2.equals(other.addressLine2))
            return false;
        if (city == null) {
            if (other.city != null)
                return false;
        } else if (!city.equals(other.city))
            return false;
        if (country == null) {
            if (other.country != null)
                return false;
        } else if (!country.equals(other.country))
            return false;
        if (phoneNumber == null) {
            if (other.phoneNumber != null)
                return false;
        } else if (!phoneNumber.equals(other.phoneNumber))
            return false;
        if (pincode == null) {
            if (other.pincode != null)
                return false;
        } else if (!pincode.equals(other.pincode))
            return false;
        if (state == null) {
            if (other.state != null)
                return false;
        } else if (!state.equals(other.state))
            return false;
        return true;
    }

    public String toString() {
        return this.addressLine1+","+this.addressLine2+","+this.city+","+this.state+","+this.pincode+","+this.country+","+this.phoneNumber;
    }

}

В TestCase для этого класса я попытался создать два идентичных адреса и вызвать assertEquals .. Однако это не удается ..

Класс AddressTests расширяет UnitTest {

@Test
public void testAddressEquality() {
    Address address1 = new Address();
    address1.addressLine1 = "#1000,South Avenue";
    address1.state = "New York";
    address1.country = "U.S";
    System.out.println("address1="+address1);

    Address address2 = new Address();
    address2.addressLine1 = "#1000,South Avenue";
    address2.state = "New York";
    address2.country = "U.S";
    System.out.println("address2="+address2);

    assertEquals(address1,address2);

}

}

Сбой assertEquals

Failure, expected: models.Address<#1000,South Avenue,null,null,New York,null,U.S,null> but was: models.Address<#1000,South Avenue,null,null,New York,null,U.S,null>

Может кто-нибудь помочь мне понять, почему это не удалось?

Ответы [ 3 ]

3 голосов
/ 11 февраля 2012

Это проблема:

if (!super.equals(obj))
        return false;

Object.equals проверяет, совпадают ли ссылки (тот же тест, что и ваш this == obj тест). Вам вообще не нужна эта проверка - вы уже проверили на равенство ссылок и не хотите выручать, если ссылки на объекты не совпадают.

Форма Документы :

Метод equals для класса Object реализует максимально различающее возможное отношение эквивалентности для объектов; то есть для любых ненулевых ссылочных значений x и y этот метод возвращает true тогда и только тогда, когда x и y ссылаются на один и тот же объект (x == y имеет значение true).

Одна реализация ( OpenJDK ):

public boolean equals(Object obj) {
  return (this == obj);
}
0 голосов
/ 13 февраля 2012

Вы никогда не должны никогда не создавать хэш-код / ​​равно вручную ... пусть выбранная вами IDE сделает это за вас.

В IntelliJ IDEA это просто ALT + Insert, создайте hashCode / равно,Затмение было бы как-то похоже.

0 голосов
/ 11 февраля 2012

Я думаю, вам также следует изменить хэш-функцию. Почему бы просто не взять сумму других хеш-значений? Как у вас есть, результат превышает 2 миллиарда (Integer.MAX_VALUE), если большинство полей не являются нулевыми, поэтому вы оборачиваете целочисленные значения.

...