13

假设我有一堂课

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 是否比我自己遍历整个数组列表更好?或者我错过了什么。

4

4 回答 4

24

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.
于 2013-07-08T04:04:01.877 回答
11

您的方法的签名equals是错误的。您没有覆盖equalsin Object,而只是重载它。

要覆盖equals方法 in的行为Object,您的签名必须与 in 的签名完全匹配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方法以使您的对象在基于地图的集合中正常工作。

于 2013-07-08T04:36:25.530 回答
2

诚的回答是对的。我也会这么说。但是您在上面的代码中有一些错误。

  1. 您写了“公共布尔等于(日期 m){”。我认为,您的意思是数据而不是日期。
  2. 你写了“if(this.k == mk && this.l = ml)”。if 查询中的第二个条件必须是“==”。

对于您的问题:Makoto 的回答是一种解决方案。我的解决方案是使用 eclipse 的帮助来自动生成hashcodeequals方法。像这样:

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;
    }
}
于 2016-12-09T13:50:23.660 回答
-2

按照惯例,当您覆盖 equals 时,您也希望覆盖哈希码

您很可能会发现 indexOf 使用 hashcode 方法来匹配对象而不是 equals

如果您使用 ecrise 来编辑您的代码 - eclipse 会从“源”菜单为您生成一个好的等号和哈希码方法。

于 2013-07-08T04:12:40.513 回答