ArrayList 的自定义 Contains 方法

Posted

技术标签:

【中文标题】ArrayList 的自定义 Contains 方法【英文标题】:ArrayList's custom Contains method 【发布时间】:2012-01-09 11:07:46 【问题描述】:

我有一些东西

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() 方法吗?

【问题讨论】:

你在你的 A 类中重写了 equals() 吗?如果是的话,你能把它贴在这里吗? 从下面的答案来看,我想没有方便的解决方案。我觉得这可以通过匿名类实现来解决,就像您使用自己的 Comparator 调用 Collections.sort() 时使用的那种。 经过一番搜索,我在这里找到了一些有用的答案:***.com/questions/587404/… 【参考方案1】:

你没有覆盖你的类中的方法。为了覆盖,方法参数也必须是相同的类型。

应该是

public boolean equals(Object o) 


在你的情况下它在哪里

public boolean equals(Long o) 

 

你可能需要这样做

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

【讨论】:

我更新了代码,结果还是一样。包含找不到具有特定 ID 的对象 查看我的答案以获得可能的解释 - “另一个问题......” 我认为在演员表之前添加一个 if 是个好主意... if(!(o instanceof A)) return false;【参考方案2】:

我做错了什么?

你没有压倒一切。你超载了。

contains 方法调用带有签名equals(Object)equals 方法,因此您添加的这个(新)方法将不会被调用。

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

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


我也应该重写 hashcode() 方法吗?

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

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

【讨论】:

【参考方案3】:

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

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 中的 instanceof A 检查将确保您不会尝试比较不同的对象。

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

【讨论】:

很好的例子谢谢! @Vern 嗨,我试图实现和你一样的东西,就我而言,我有一个 POJO 类,我试图使用 contains 方法比较一个属性,但它没有按预期工作。如果您有 id 的 setter 和 getter 并命名您将传递给 contains 方法的值,能否请您告诉我。 我有两个要使用的属性。我将如何实施hashCode() 方法?

以上是关于ArrayList 的自定义 Contains 方法的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 contains 在自定义对象 ArrayList 中搜索特定字符串?

Kotlin - ArrayList 的自定义排序

将arraylists1和arraylist2之间相等的自定义对象移除到arraylist1中

ht-7 对arrayList中的自定义对象排序

在kotlin的自定义类型arraylist中按id搜索对象[重复]

HashSet的contains()和ArrayList的contains()方法哪个更快一些?