ArrayList 的自定义 Contains 方法

2022-09-01 04:17:39

我有一些对象

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)) {...}

但是覆盖的Equals方法对我没有帮助。我做错了什么?谢谢

更新我也应该覆盖一个hashcode()方法吗?


答案 1

这里有一些代码可以演示它是如何工作的:

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

}

首先,有一个 equals(Object o) 方法的重写。然后还有hashCode()的覆盖。另请注意,在 equals 中 A 检查的实例将确保您不会尝试比较不同的对象。

这应该可以解决问题!希望它有所帮助!干杯:)


答案 2

我做错了什么?

你没有覆盖。您正在超载。

该方法使用 签名 调用该方法,因此不会调用您添加的此(新)方法。containsequalsequals(Object)

另一个问题是,您的方法具有 错误的语义。该方法需要与可能成为列表成员的对象进行比较。您的列表不包含对象。它包含 类型的对象。equalscontainscontainsthisLongA

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


我也应该覆盖一个hashcode()方法吗?

如果覆盖,则还应覆盖 。equals(Object)hashcode()

它在这里不会有任何区别,但是如果您将对象放入散列数据结构中,这是必不可少的。而且,由于您不知道下一个人将如何处理您的代码,因此最好确保这一点并具有兼容的语义。Aequals(Object)hashCode()