开发者

Contains for List of Pair

开发者 https://www.devze.com 2023-02-09 20:54 出处:网络
List<Pair<String, String> > lp = new ArrayList<Pair<String, String> >(); lp.add(new Pair(\"1\", \"2\"));
  List<Pair<String, String> > lp = new ArrayList<Pair<String, String> >();
  lp.add(new Pair("1", "2"));

How should I check if the list lp contains 1 and 2 i.e the Pair ("1",开发者_如何学Python "2").


Your Pair class needs to implement equals() and hashCode() and you're all set. List.contains() is implemented in terms of the type's equals() method. See the API for List.contains(). (Edited a bit to address comments from @maaartinus, whose answer you should read b/c the observations are solid, and it's a bit ridiculous for me to fold them in here. As maaartinus points out, a best-practice here would be to avoid error-prone manual definitions for equals and hashcode, and instead build on Guava's helper functions for nullable equals and hashCode 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();
   } 
}

With suitable equals(), you can now do:

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

Responding to the comments below, perhaps it would be good to include a good reference for "Why do I need to implement hashCode()?"

  • JavaPractices.com — Implementing equals() — "if you override equals, you must override hashCode"

  • Object.equals() contract as defined in the API documentation

  • StackOverflow answer


The implementation in the answer by andersoj

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

is wrong: The null tests clearly suggest that null is a legal value for left and right. So there are at least two problems there:

  • new Pair(null, null).hashCode() throws NPE
  • new Pair(null, null) does NOT equal to itself!

Have a look at Guava class Objects for a correct implementation. Use it or write a static helper methods like

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();
}

and always use them.

Never ever write equals containing a null test.

It's to easy to blow it, and nobody noticed it. Using the Helper, it's trivial to get it right:

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);
} 

Of course, forbidding nulls in the constructor is an option, too.

0

精彩评论

暂无评论...
验证码 换一张
取 消