ArrayList索引是如何工作的?

时间:2014-12-18 11:23:31

标签: java arraylist

我无法从ArrayList中获取此对象我认为ArrayList使用equals方法和hashCode方法所以我确实错过了什么?这是我的对象

public class OPCode {

public String code;

public OPCode(String code){     

    this.code = code;      
}

@Override
public boolean equals(Object o){
 OPCode c = (OPCode) o; 
return this.code.equals(c.code.substring(0, c.code.length()-2)); // returns ture 
}

@Override
public int hashCode() {
   return 1;
}
}

和示例

ArrayList<OPCode> t_codes = new ArrayList();
 OPCode c = new OPCode("1-202");
    t_codes.add(c);
    OPCode e = new OPCode("1-202.0");
    t_codes.indexOf(e); // -1 <-- Problem here 
    t_codes.indexOf(c) // finds it

我希望e和c平等。

6 个答案:

答案 0 :(得分:2)

您的equals()hashCode()方法错误。你违约了。

如果我理解得很好,你想要找到e的索引,尽管列表中只有c,而你想这样做只会滥用String#equals()检查等式前5个字母。 c.code = 1-202e.code = 1-202.0c.code.equals(e.code.subString(0, e.code.lenght()-2)) true应保留public class OPCode { public String code; public OPCode(String code){ this.code = code; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((code == null) ? 0 : code.split("\\.")[0].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; OPCode other = (OPCode) obj; if (code == null) { if (other.code != null) return false; } else{ String thisCode = code.split("\\.")[0]; String otherCode = other.code.split("\\.")[0]; if (!thisCode.equals(otherCode)) return false; } return true; } }

这是正确的实施:

String#split

请注意,我使用方法split因为(这是我的假设)你想要使用相同数字部分的相等代码而不考虑小数部分。使用ArrayList<OPCode> t_codes = new ArrayList<OPCode>(); OPCode c = new OPCode("1-202"); t_codes.add(c); OPCode e = new OPCode("1-202.0"); System.out.println(t_codes.indexOf(e)); // -1 <-- Problem here now gives 0 System.out.println(t_codes.indexOf(c)); 我们避免管理可变数量的文字。

用以下方法测试:

{{1}}

BTW我使用eclipse内置函数通过 Source&gt;生成hashCode()和equals()... 并为任务修改了这两种方法。

答案 1 :(得分:1)

您尚未将该元素添加到列表t_codes.add(e);

t_codes.indexOf(c) // finds it有效,因为您已将此对象添加到列表t_codes.add(c);

但您尚未将对象OPCode e = new OPCode("1-202.0");添加到列表中。因此,t_codes.indexOf(e);会为您提供-1

答案 2 :(得分:0)

如果您正在使用Eclipse。选择方法并按F3(需要jdk)。现在您将看到实现:

/**
 * Returns the index of the first occurrence of the specified element
 * in this list, or -1 if this list does not contain the element.
 * More formally, returns the lowest index <tt>i</tt> such that
 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
 * or -1 if there is no such index.
 */
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;
}

答案 3 :(得分:0)

问题在于你的equals方法。

t_codes.indexOf(c)实际上是指object e。因为根据您的等于方法实现, e 等于 c ,反之亦然。

你的e.equals(c) != c.equals(e)。您需要重新审视equals实现。

答案 4 :(得分:0)

您的equals()方法不可交换。即e.equals(c) != c.equals(e),所以你得到奇怪的行为并不出人意料。

答案 5 :(得分:0)

问题在于你的equals方法。

return (c.code.equals(code)) || c.code.equals(this.code.substring(0, this.code.length() - 2));