2011-11-30 71 views
22

我有这些对象的一些对象ArrayList中的自定义包含方法

class A { 
    private Long id; 
    private String name; 
    public boolean equals(Long v) { 
    return this.id.equals(v); 
    } 
} 

和ArrayList。 我想要的是能够检查该列表是否包含按对象字段的某个对象。 例如:

ArrayList<A> list = new ArrayList<A>(); if (list.contains(0L)) {...} 

但overrided equals方法不帮助我。我做错了什么? 谢谢

UPDATE 我应该覆盖的哈希码()方法呢?

+0

你有没有重写equals()在你的A类?如果是这样,你可以在这里发布吗? – c05mic

+0

根据下面的答案判断,我想这没有方便的解决方案。我觉得这可以用匿名类实现来解决,比如你用你自己的比较器调用Collections.sort()时使用的类。 – kodu

+0

搜索了一下之后,我在这里找到了一些有用的答案:http://stackoverflow.com/questions/587404/finding-all-objects-that-have-a-given-property-inside-a-collection – kodu

回答

38

这里的一些代码,可能会证明它是如何工作:

import java.util.ArrayList; 

class A { 
    private Long id; 
    private String name; 

    A(Long id){ 
     this.id = id; 
    } 

    @Override 
    public boolean equals(Object v) { 
     boolean retVal = false; 

     if (v instanceof A){ 
      A ptr = (A) v; 
      retVal = ptr.id.longValue() == this.id; 
     } 

    return retVal; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 7; 
     hash = 17 * hash + (this.id != null ? this.id.hashCode() : 0); 
     return hash; 
    } 
} 

public class ArrayList_recap { 
    public static void main(String[] args) { 
     ArrayList<A> list = new ArrayList<A>(); 

     list.add(new A(0L)); 
     list.add(new A(1L)); 

     if (list.contains(new A(0L))) 
     { 
      System.out.println("Equal"); 
     } 
     else 
     { 
      System.out.println("Nah."); 
     }  
    } 

} 

首先是等号(对象o)方法的重写。然后还有hashCode()的覆盖。另请注意,equals中的instanceof检查将确保您不试图比较不同的对象。

这应该做的伎俩!希望它有帮助!干杯:)

+0

很好的例子谢谢! –

+0

它也适用于containsAll方法吗? – Amriteya

+0

它适用于containsAll – Amriteya

8

你还没有重写你班上的方法。为了覆盖,方法参数也必须是相同的类型。

应该

public boolean equals(Object o) { 

} 

地方在你的情况下,它是

public boolean equals(Long o) { 

} 

你可能需要为此

public boolean equals(Object o) 
    { 
     if (o == null) return false; 
     if (o == this) return true; //if both pointing towards same object on heap 

      A a = (A) o; 
     return this.id.equals(a.id); 
    } 
+0

我更新了代码,但结果是一样的。包含无法找到具有特定ID的对象 – nKognito

+0

可以请您发布相关代码。 – Zohaib

+1

看到我的答案可能的解释 - *“另一个问题...”* –

7

我做错了吗?

你不是压倒一切的。你超载。

contains方法调用带签名equals(Object)equals方法,因此您添加的这个(新)方法将不会被调用。

另一个问题是您的equals方法对于contains有错误的语义。 contains方法需要将this与可能是列表成员的对象进行比较。您的列表不包含Long对象。它包含A类型的对象。

现在你可能会逃避这个......如果你使用原始列表类型......但是你试图做的是违反API合同和不良做法。更好的解决方案是显式地迭代和测试列表的元素。


而且,我也要重写hashCode()方法的方法吗?

如果你重写equals(Object)那么你也应该重写hashcode()

它在这里没有什么区别,但是如果你把你的A对象放入散列数据结构中,这是非常重要的。而且,由于您不知道下一个人将如何处理您的代码,因此确保equals(Object)hashCode()具有兼容的语义是一种很好的做法。

+0

感谢您的解释 – nKognito