idl*_*age 33 java contains list equals
我有一个ArrayList的Test对象,使用字符串作为等价检查.我希望能够用来List.contains()检查列表是否包含使用某个字符串的对象.
只是:
Test a = new Test("a");
a.equals("a"); // True
List<Test> test = new ArrayList<Test>();
test.add(a);
test.contains("a"); // False!
Run Code Online (Sandbox Code Playgroud)
等于和散列函数:
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (o == this) return true;
if (!(o instanceof Test)) {
return (o instanceof String) && (name.equals(o));
}
Test t = (Test)o;
return name.equals(t.GetName());
}
@Override
public int hashCode() {
return name.hashCode();
}
Run Code Online (Sandbox Code Playgroud)
我读到这是为了确保contains自定义类的工作,它需要覆盖equals.因此,当我equals返回true时contains返回false 对我来说是非常奇怪的.
我怎样才能做到这一点?
Era*_*ran 41
仅仅因为你Test的equals时候,你可以通过返回true一个字符串它并不意味着String的equals,当你通过一个永远不会返回true,Test例如它.事实上,String的equals只能返回true时传递给它的实例是另一种String:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) { // the passed instance must be a String
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
ArrayList使用搜索实例的方法(在您的示例中为"a")的contains调用,而不是元素类型(在您的情况下):indexOfequalsStringListTest
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i])) // o in your case is a String while
// elementData[i] is a Test
// so String's equals returns false
return i;
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)
And*_*eas 27
equals()应该永远是可交换的,即a.equals(b)和b.equals(a)应始终返回相同的值.或者对称,作为equals()调用它的javadoc :
该
equals方法在非null对象引用上实现等价关系:
- 它是自反的:对于任何非空引用值
x,x.equals(x)应该返回true.- 它是对称的:对于任何非空引用值
x和y,x.equals(y)应该返回true当且仅当y.equals(x)回报true.- 它是传递性:对于任何非空的参考值
x,y以及z,如果x.equals(y)回报率true和y.equals(z)回报率true,那么x.equals(z)应该返回true.- 它是一致的:对于任何非空引用值
x以及一致返回或一致返回的y多次调用,前提是不修改在对象比较中使用的信息.x.equals(y)truefalseequals- 对于任何非空引用值
x,x.equals(null)应返回false.
不幸的是,即使Java运行时库也错了.Date.equals(Timestamp)将比较毫秒值,忽略存在的纳秒Timestamp,同时Timestamp.equals(Date)返回false.
Mic*_*urr 18
问题是List<E>.contains(object o)记录为返回true:
当且仅当此列表包含至少一个元素e时(o == null?e == null:o.equals(e)).
(来自https://docs.oracle.com/javase/8/docs/api/java/util/List.html#contains-java.lang.Object-)
请注意,它不会执行测试,e.equals(o)因为测试工作是必需的.您的equals方法无法交换(使用Java文档中的术语"对称").
Java文档表示equals()类的方法必须遵循以下规则:
equals方法在非null对象引用上实现等价关系:
- 它是自反的:对于任何非空引用值
x,x.equals(x)应该返回true.- 它是对称的:对于任何非空引用值
x和y,x.equals(y)应真,当且仅当返回y.equals(x)返回true.- 它是传递性的:对于任何非空引用值
x,y和z,如果x.equals(y)返回true并y.equals(z)返回true,x.equals(z)则应返回true.- 它是一致的:对于任何非空引用值,
x并且y多次调用x.equals(y)始终返回true或始终返回false,前提是不修改在对象的equals比较中使用的信息.- 对于任何非空引用值
x,x.equals(null)应返回false.
如果你写
test.contains(new Test("a"));
Run Code Online (Sandbox Code Playgroud)
那肯定会回归真实.您正在检查Test列表中的字符串对象.
| 归档时间: |
|
| 查看次数: |
8831 次 |
| 最近记录: |