为什么这个String.equals()方法总是返回false?

时间:2011-05-11 08:03:36

标签: java android string

我有一个类,我使用Eclipse方法生成器实现了自定义hashCode()和equals(Object)方法。该类的每个对象都有一个名为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 个答案:

答案 0 :(得分:2)

你的方法应该有用。我刚用这段代码测试过它运行良好:

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");时,它返回“false”;

答案 1 :(得分:0)

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.

等号哈希码不一定代表相等的字符串。他们的内容真的相同吗?

答案 2 :(得分:0)

试试这个

 if (mUid == null)
{
    if (other.mUid != null)
        return false;
} 
else if (!mUid.equalsIgnoreCase(other.mUid))
    return false;
return true;

答案 3 :(得分:0)

如果你使用了Eclipse生成器,这很奇怪,并且不需要手动编辑生成的代码。你可以发布全班的源代码吗?你扩展了另一个对象吗?

答案 4 :(得分:0)

好的,我看了一下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;
}

所以在debbuger中,我会尝试比较并打印2个char数组。您可以使用toCharArray方法。如果char确实不同,则可能是编码问题,我会尝试检查Yahoo使用的编码并确保使用它进行解码。