Подтвердить что ты не робот

Java: Чистый способ избежать NullPointerException при проверке равными

У меня есть адресный объект, для которого я хочу создать метод equals. Я мог бы сделать это довольно просто, выполнив что-то вроде следующего (немного сокращенного):

public boolean equals(Object obj) 
{
    if (this == obj)
        return true;

    if (obj == null)
        return false;

    if (getClass() != obj.getClass())
        return false;

    Address other = (Address) obj;

    return this.getStreet().equals(other.getStreet())
        && this.getStreetNumber().equals(other.getStreetNumber())
        && this.getStreetLetter().equals(other.getStreetLetter())
        && this.getTown().equals(other.getTown());
}

Проблема в том, что некоторые из них могут быть пустыми. Другими словами, я получаю a NullPointerException, если в этом адресе нет буквы улицы.

Как я могу написать это чистым способом, принимая во внимание нулевые значения?

4b9b3361

Ответ 1

Вы можете использовать вспомогательный метод, например

public static boolean isEqual(Object o1, Object o2) {
    return o1 == o2 || (o1 != null && o1.equals(o2));
}

Ответ 2

Вы можете сделать следующее:

public boolean equals(Object obj) 
{
    if (this == obj) {
        return true;
    }

    if (obj == null) {
        return false;
    }

    if (getClass() != obj.getClass()) {
        return false;
    }

    Address other = (Address) obj;

    return equals(this.getStreet(),other.getStreet())
        && equals(this.getStreetNumber(), other.getStreetNumber())
        && equals(this.getStreetLetter(), other.getStreetLetter())
        && equals(this.getTown(), other.getTown());
}

private boolean equals(Object control, Object test) {
    if(null == control) {
        return null == test;
    }
    return control.equals(test);
}

В Java 7 появилась встроенная поддержка этого варианта использования с классом java.util.Objects:

Ответ 3

Google Guava предоставляет Objects.equal(Object, Object), который проверяет равенство, принимая во внимание, что любой из параметров может иметь значение null:

...
return Objects.equal(this.getStreet(), other.getStreet())
    && Objects.equal(this.getStreetNumber(), other.getStreetNumber())
    && Objects.equal(this.getStreetLetter(), other.getStreetLetter())
    && Objects.equal(this.getTown(), other.getTown());

Также стоит отметить, что у объектов есть другие вспомогательные методы для реализации hashCode() и ToString().

Ответ 4

У меня есть помощник класса Checker с статическим методом:

 public static boolean isEquals(final Object o1, final Object o2) {
        return o1 == null ? o2 == null : o1.equals(o2);
 }

поэтому в методе equals

 return Checker.isEquals(this.getStreet(), other.getStreet())
        && Checker.isEquals(this.getStreetNumber(), other.getStreetNumber())
        && Checker.isEquals(this.getStreetLetter(), other.getStreetLetter())
        && Checker.isEquals(this.getTown(), other.getTown());

Ответ 5

Нет действительно чистого способа сделать это; лучший вариант, вероятно, заключается в том, чтобы ваша IDE генерировала код для вас. Eclipse может сделать это через контекстное меню Source → Generate hashCode() и equals().

Ответ 6

Я бы рассмотрел определение некоторых методов equals как статических методов класса, например, для объектов Street. Таким образом, вы никогда не пытаетесь вызвать метод .equals() на null.

Примерная функция может выглядеть так:

public static boolean equals(Object one, Object two)

Кроме того, неплохо было бы проверить такие чеки, как

if (obj == null)
   return false;

в самом начале функции.

Ответ 7

Вы можете использовать Objects.equal из Googles guava или EqualsBuilder от apache commons

Ответ 8

Apache Commons Lang предоставляет вспомогательный класс EqualsBuilder равенства. Существует также один для хеш-кодов.

return new EqualsBuilder()
.append(this.getStreet(), other.getStreet())
.append(this.getStreetNumber(), other.getStreetNumber()
.append(this.getStreetLetter(), other.getStreetLetter())
.append(this.getTown(), other.getTown())).isEquals();