包含对列表

时间:2011-02-10 01:50:09

标签: java collections

  List<Pair<String, String> > lp = new ArrayList<Pair<String, String> >();
  lp.add(new Pair("1", "2"));

如何检查列表lp是否包含1和2,即对(“1”,“2”)。

2 个答案:

答案 0 :(得分:7)

您的Pair课程需要实施equals()hashCode(),而且您已全部设定。 List.contains()是根据类型的equals()方法实现的。请参阅API for List.contains()。 (编辑了一下来回应@maaartinus的评论,你的回答你应该读到b / c,观察结果是可靠的,我把它们折叠在这里有点荒谬。正如maaartinus指出的,这里的最佳做法是避免容易出错的equals和hashcode手动定义,而是建立在Guava的nullable equalshashCode for n objects的辅助函数上。

final class Pair<T> {

   final T left;
   final T right;

   public Pair(T left, T right)
   {
     if (left == null || right == null) { 
       throw new IllegalArgumentException("left and right must be non-null!");
     }
     this.left = left;
     this.right = right;
   }

   public boolean equals(Object o)
   {
     // see @maaartinus answer
     if (! (o instanceof Pair)) { return false; }
     Pair p = (Pair)o;
     return left.equals(p.left) && right.equals(p.right);
   } 

   public int hashCode()
   {
      return 7 * left.hashCode() + 13 * right.hashCode();
   } 
}

使用合适的equals(),您现在可以:

  lp.add(new Pair("1", "2"));
  assert lp.contains(new Pair("1","2"));

回应下面的评论,或许最好为“我为什么需要实施hashCode()”提供一个很好的参考?

答案 1 :(得分:1)

andersoj在答案中的实施

 return left != null && right != null && left.equals(p.left) && right.equals(p.right);

错误:null测试清楚地表明null是左右合法的值。所以至少存在两个问题:

  • new Pair(null, null).hashCode()抛出NPE
  • new Pair(null, null)不等于自己!

查看Guava类对象以获得正确的实现。使用它或编写静态帮助方法,如

public static boolean equal(Object a, Object b) {
    return a==b || a!=null && a.equals(b);
}
public static int hashCode(Object a) {
    return a==null ? 0 : a.hashCode();
}

并始终使用它们。

永远不要编写包含空测试的equals

很容易吹它,没有人注意到它。使用助手,做到正确是微不足道的:

public boolean equals(Object o)  {
    if (!(o instanceof Pair)) return false;
    Pair p = (Pair) o;
    return Helper.equals(left, p.left) && Helper.equals(right, p.right);
} 

public int hashCode() {
    return 7 * Helper.hashCode(left) + 13 * Helper.hashCode(right);
} 

当然,禁止在构造函数中使用空值也是一种选择。