让我说我有一个班级
public class Data{
public int k;
public int l;
public Data(int k, int l){
this.k = k;
this.l = l;
}
public boolean equals(Date m){
if(this.k == m.k && this.l = m.l)
return true;
return false;
}
}
我向ArrayList添加了一些Data对象:
ArrayList<Data> holder = new ArrayList<Data>;
Data one = new Data(0,0);
Data two = new Data(0,4);
Data three = new Data(0,5);
为什么indexOf找不到这个?:
holder.indexOf(new Data(0,4)); //returns -1
indexOf是否比自己遍历整个数组列表更好?或者我错过了什么。
答案 0 :(得分:22)
indexOf()
方法 遍历整个列表。以下是Java 7源代码的摘录:
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]))
return i;
}
return -1;
}
让Java通过它比自己编写更好。只需确保您的equals
方法足以找到所需的对象。您还想要覆盖hashCode()
。
我不会写出你的equals
方法,但我建议你至少:
if(boolean_expr) { return true; }
;只返回布尔表达式。equals
方法 - 签名需要Object
参数,而不是Date
。答案 1 :(得分:9)
equals
方法的签名是错误的。您没有覆盖equals
中的Object
,只是重载它。
要覆盖equals
中Object
方法的行为,您的签名必须与Object
中的签名完全匹配。试试这个:
public boolean equals(Object o) {
if(!(o instanceof Data)) return false;
Data other = (Data) o;
return (this.k == other.k && this.l == other.l);
}
此外,正如其他人所建议的那样,最好覆盖hashCode
方法,以使对象在基于地图的集合中正常工作。
答案 2 :(得分:2)
Makoto的答案是对的。我会说同样的。但是你的代码中有一些错误。
问题: Makoto的答案是一个解决方案。 我的解决方案是使用eclipse的帮助来自动生成哈希码和等于方法。像这样:
public class Data {
// your class code here
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + k;
result = prime * result + l;
return result;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Data)) {
return false;
}
Data other = (Data) obj;
if (k != other.k) {
return false;
}
if (l != other.l) {
return false;
}
return true;
}
}
答案 3 :(得分:-2)
按照惯例,您希望在覆盖等于
时覆盖哈希码您很可能会发现indexOf使用hashcode方法匹配对象而不是equals
如果您使用eclise编辑代码 - eclipse将从“源”菜单为您生成一个好的equals和hashcode方法。