2015-06-15 124 views
0

我的代码有一个奇怪的问题。Java ArrayList indexOf返回-1

继承人的代码我测试用的组块类:

List<Chunk> chunks = new ArrayList<Chunk>(); 
chunks.add(new Chunk(1,1,1)); 
System.out.println(chunks.indexOf(new Vector3i(1, 1, 1))); 

这里是块的类的equals方法:

public boolean equals(Object object) { 
    System.out.println("Test _1_"); 
    if (object != null && object instanceof Vector3i) { 
     System.out.println("Test _2_"); 
     if((this.x == ((Vector3i) object).x)&&(this.y == ((Vector3i) object).y)&&(this.z == ((Vector3i) object).z)) { 
      System.out.println("Test _3_"); 
      return true; 
     } 
    } 
    System.out.println("Test _4_"); 

    return false; 
} 

的Vector3i:

public class Vector3i { 
    public int x; 
    public int y; 
    public int z; 


    public Vector3i(int x, int y, int z) { 
     this.x = x; 
     this.y = y; 
     this.z = z; 
    } 

} 

当我运行它,它只返回-1。来自equals方法的测试打印不会打印,这意味着它甚至不会开始执行。这是为什么?

+4

这是['的Object.Equals()'合同(HTTP严重滥用:// docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-)。你的'equals()'方法不是**自反**,**对称**或**传递**。使用'Map '来代替一个唯一的块与一个给定的矢量值。 – biziclop

+0

您有一个名为'Chunk'的类,它有一个'equals'方法来检查参数是否是其他类型? – MadConan

+0

@MadConan这是因为chunk包含大量数据,如果我应该将它与新的数据进行比较,这将会太重。 – KaareZ

回答

5

如果您检查ArrayList.indexOf的实现,您会发现在您的情况下会调用Vector3i.equals。其实它在Javadoc甚至指定List

更正式地说,返回满足我这样(o==null ? get(i)==null : o.equals(get(i))),或-1如果没有这样的索引。

一般而言equals操作必须是对称的:a.equals(b) == b.equals(a)。所以你必须实现Vector3i.equals

请注意,您目前的equals实施缺乏像反身性的其他属性。当您实施equals时,请考虑实施hashCode

+0

谢谢!这使它。 – KaareZ

+1

虽然这是100%真实的,但这也是一个可怕的建议。首先,你刚刚破坏了'Object.hashCode()'合约,所以我期待着“为什么我的HashMap.get()'返回'null'?问题很快。其次,它仍然不会使'equals()'自反。 – biziclop

+1

@biziclop,当我说“实现等于”时,这意味着实现'hashCode'也是一个好主意。至于其他'equals()'属性(反射性,传递性,一致性),它写在链接的JavaDoc中。那么,我会为答案添加通知。 –

0
chunks.indexOf(new Vector3i(1, 1, 1) 

调用equals()方法上Vector3i类,howeve,而不是组块类......