Почему этот метод String.equals () всегда возвращает false? - PullRequest
0 голосов
/ 11 мая 2011

У меня есть класс, для которого я реализовал собственный метод hashCode () и equals (Object), используя генератор методов Eclipse.Каждый объект класса имеет поле String с именем mUid, которое должно быть уникальным и достаточным для определения равенства.Переопределенные методы выглядят так:

    @Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((mUid == null) ? 0 : mUid.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    DataSource other = (DataSource) obj;
    if (mUid == null) {
        if (other.mUid != null)
            return false;
    } else if (!mUid.equals(other.mUid))
        return false;
    return true;
}

Но по какой-то причине, когда я сравниваю два объекта моего класса, он всегда возвращает false.Я прошел через код с помощью отладчика и могу определить, что строки mUid одинаковы.Но мой метод equals(Object) всегда возвращает false в строке

if (!mUid.equals(other.mUid)) {return false;}.

Это означает, что метод String equals () сообщает, что строки не равны.Но в отладчике я вижу, что даже их хэш-коды равны.

Вот скриншот отладки: Debugging screenshot Может кто-нибудь объяснить, что происходит?Спасибо.

Обновление: это работает!

Следует отметить, что я не вызываю метод equals (...) напрямую, а скорее из List<DataSource> list.contains(DataSource).Оказывается, что если я пошагово выполняю код equals(Object), он показывает, что он возвращает false для сравнения каждого объекта в списке (даже если есть совпадение).Но, похоже, метод List.contains() возвращает правильное значение (true или false) в любом случае.Не знаю, почему это так, но это работает.После if(list.contains(dataSource)); у меня была лишняя точка с запятой, поэтому я не мог правильно увидеть, что contains() работает нормально. Спасибо за вашу помощь всем .

Ответы [ 5 ]

2 голосов
/ 11 мая 2011

Ваш метод должен работать. Я только что проверил с этим кодом, и он работал нормально:

public class DataSource {

    private String mUid;

    public DataSource(String m) {
        mUid = m;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((mUid == null) ? 0 : mUid.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        DataSource other = (DataSource) obj;
        if (mUid == null) {
            if (other.mUid != null)
                return false;
        } else if (!mUid.equals(other.mUid))
            return false;
        return true;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        DataSource ds1 = new DataSource("test");
        DataSource ds2 = new DataSource("test");
        System.out.println(ds1.equals(ds2));
    }

}

Вывод на консоль был "true"; Когда я изменил код на DataSource ds2 = new DataSource("test1");, он вернул «ложь»;

0 голосов
/ 11 мая 2011

Хорошо, поэтому я взглянул на декомпилированную версию String.equals:

public boolean equals(Object obj)
{
    if(this == obj)
        return true;
    if(obj instanceof String)
    {
        String s = (String)obj;
        int i = count;
        if(i == s.count)
        {
            char ac[] = value;
            char ac1[] = s.value;
            int j = offset;
            int k = s.offset;
            while(i-- != 0) 
                if(ac[j++] != ac1[k++])
                    return false;
            return true;
        }
    }
    return false;
}

Итак, в отладчике я бы попытался сравнить и распечатать 2-символьные массивы.Для этого вы можете использовать метод toCharArray.Если символ действительно отличается, вероятно, это проблема кодирования, и я постараюсь проверить кодировку, используемую Yahoo, и убедиться, что вы декодируете ее.

0 голосов
/ 11 мая 2011

попробуйте

 if (mUid == null)
{
    if (other.mUid != null)
        return false;
} 
else if (!mUid.equalsIgnoreCase(other.mUid))
    return false;
return true;
0 голосов
/ 11 мая 2011

Если вы использовали генератор Eclipse, это очень странно, и редактирование сгенерированного кода вручную не требуется.Можете ли вы опубликовать весь исходный код класса?Вы расширяете другие объекты?

0 голосов
/ 11 мая 2011

This means the String equals() method is saying the strings are not equal. But, in the debugger I can see that even their hashcodes are equal.

Равные хеш-коды не обязательно представляют собой одинаковые строки.Их содержание действительно равны?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...