ArrayList的自定义Contains方法

nKo*_*ito 29 java contains arraylist

我有一些对象

class A {
  private Long id; 
  private String name; 
  public boolean equals(Long v) {
     return this.id.equals(v);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

ArrayList<A> list = new ArrayList<A>(); if (list.contains(0L)) {...}
Run Code Online (Sandbox Code Playgroud)

但是压倒的Equals方法对我没有帮助.我做错了什么?谢谢

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

Ver*_*ern 49

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

这应该够了吧!希望它有所帮助!干杯:)


Zoh*_*aib 8

您没有覆盖您班级中的方法.为了覆盖,方法参数也必须是相同的类型.

它应该是

public boolean equals(Object o) {

}
Run Code Online (Sandbox Code Playgroud)

它就像你的情况一样

public boolean equals(Long o) {

 }
Run Code Online (Sandbox Code Playgroud)

你可能需要这样做

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);
    }
Run Code Online (Sandbox Code Playgroud)

  • 我认为在演员阵容之前添加一个if是个好主意... if(!(o instanceof A))return false; (3认同)

Ste*_*n C 8

我做错了什么?

你不是压倒一切.你正在超载.

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

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

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


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

如果你覆盖equals(Object)那么你也应该覆盖hashcode().

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