List<Pair<String, String> > lp = new ArrayList<Pair<String, String> >();
lp.add(new Pair("1", "2"));
如何检查列表lp是否包含1和2,即对(“1”,“2”)。
答案 0 :(得分:7)
您的Pair
课程需要实施equals()
和hashCode()
,而且您已全部设定。 List.contains()
是根据类型的equals()
方法实现的。请参阅API for List.contains()
。 (编辑了一下来回应@maaartinus的评论,你的回答你应该读到b / c,观察结果是可靠的,我把它们折叠在这里有点荒谬。正如maaartinus指出的,这里的最佳做法是避免容易出错的equals和hashcode手动定义,而是建立在Guava的nullable equals和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();
}
}
使用合适的equals()
,您现在可以:
lp.add(new Pair("1", "2"));
assert lp.contains(new Pair("1","2"));
回应下面的评论,或许最好为“我为什么需要实施hashCode()
”提供一个很好的参考?
JavaPractices.com - Implementing equals()
- “如果覆盖等于,则必须覆盖hashCode”
Object.equals()
contract as defined in the API documentation
答案 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);
}
当然,禁止在构造函数中使用空值也是一种选择。