【问题标题】:Check if an ArrayList contains a given object检查 ArrayList 是否包含给定对象
【发布时间】:2013-04-22 19:18:09
【问题描述】:

假设我有这样的课程:

class A {
  int elementA;
  int elementB
}

我也有这样的ArrayListArrayList<A> listObj

如何检查该列表是否包含仅使用A 的某些属性的对象?例如。只考虑elementA 来查找对象newA{elementA} 是否已经在列表中?

对于对象A,我定义了一个equals 方法,我只考虑elementA,但这还不够。

【问题讨论】:

  • 显示您的equals 方法。
  • 如果您正确地覆盖了您的 equals(),那么 listObj.contains(new A(elemAvalue)) 应该可以工作。请注意,您还应该仅考虑 elementA 值来覆盖 hashCode,尽管它与此示例在功能上不相关。
  • if (!days.contains(getDate())) { days.add(getDate()); }
  • 对于equals我使用here is example作为源(equals和hashCode)

标签: java list arraylist


【解决方案1】:

数组的hashCode()equals() 在涉及到这一点时有点坏(这是一个很长的不同讨论原因)。

一种可能的解决方法是使用ArrayList<ArrayList<String>> 而不是ArrayList<String[]>,ArrayList 的equals() 方法将如您所愿。

例如:

   ArrayList<String> l1 = new ArrayList<>();
    ArrayList<String> l2 = new ArrayList<>();
    l1.add("asdf");
    l2.add("asdf");
    ArrayList<ArrayList<String>> coll = new ArrayList<>();
    coll.add(l1);
    System.out.println(coll.contains(l2));

如预期的那样会产生真

也可以参考下面的链接

Most efficient way to see if an ArrayList contains an object in Java

【讨论】:

    【解决方案2】:

    List#contains() 方法使用equals() 方法来评估两个对象是否相同。因此,您需要覆盖 A 类中的 equals() 并覆盖 hashCode()

    @Override
    public boolean equals(Object object)
    {
        boolean isEqual= false;
    
        if (object != null && object instanceof A)
        {
            isEqual = (this.elementA == ((A) object).elementA);
        }
    
        return isEqual;
    }
    
    @Override
    public int hashCode() {
        return this.elementA;
    }
    

    【讨论】:

    • 只要您必须比较 A 元素就可以正常工作,但是一旦需求发生变化,您就可以将其扔掉,更不用说您可能想使用 equals 或 hashcode 方法其他地方,我肯定会选择比较器。
    • 很公平!但是 List contains() 使用 equals 方法,而不是 Comparable.compareTo()
    • 感谢您的解决方案。对于像我这样的新手:如果elementAString 类型,则使用isEqual = (this.elementA.equals(((A) object).elementA));
    • 如果“elementA”是一个String,我们不需要重写hashCode()方法
    【解决方案3】:

    我不会为此覆盖equals。即使{1, 1}{1, 2} 不能同时出现在您的列表中,这两个对象相等。

    我会改用Map

    Map<Integer, A> map = new HashMap<>();
    A a1 = new A(1, 1);
    A a2 = new A(1, 2);
    
    map.put(a1.elementA, a1);
    
    // test if key is contained
    boolean contains = map.containsKey(a2.elementA);
    
    // overwrite a1 with a2
    map.put(a2.elementA, a2);
    

    【讨论】:

      【解决方案4】:

      您可以调整您的equals 以满足您的需求,但您也可以使用已经存在的强大集合库之一,例如commons-collectionsGuavalambdaj。它们都有迭代和谓词结构,允许您基于某些谓词“探索”您的集合。

      Commons Collections 示例:

      boolean contains = CollectionUtils.exists(myArrayList, new Predicate<A>() {
          public boolean evaluate(A theA) {
              // Do the comparison
          }
      });
      

      【讨论】:

        【解决方案5】:

        以上所有解决方案都适合您的问题。 我想在这里建议你的是!!! 每当您使用集合时,请始终将变量数据类型添加到其超类中。这将帮助您进行更多操作并转换为它的任何子类。

        Ex:
        List<String> myList = new ArrayList<String>();
        

        List 的实现可以更改(例如更改为 LinkedList)而不影响其余代码的优点。使用 ArrayList 很难做到这一点,不仅因为您需要在任何地方将 ArrayList 更改为 LinkedList,还因为您可能使用了 ArrayList 特定的方法。

        【讨论】:

          【解决方案6】:

          用于比较arrayList 中的对象值。 按照这个链接。 How to compare Objects attributes in an ArrayList?

          我希望这个解决方案对您有所帮助。 谢谢

          【讨论】:

          • 这不应该被设置为我猜的答案,而是作为评论。
          • 你不能只链接回答。你必须在这里给出答案。
          【解决方案7】:
          List<Upload> mUploadPost = new ArrayList<Upload>();
          Upload upload = new Upload();
          upload.addName("Mpendulo");
          upload.addLastName("Mtshali");
          if(!mUploadPost.contains(upload)){
              mUploadPost.add(upload);
          }
          

          【讨论】:

            猜你喜欢
            • 2012-10-17
            • 1970-01-01
            • 2021-04-27
            • 1970-01-01
            • 2012-12-04
            • 2022-11-09
            • 2023-03-09
            • 2021-05-27
            • 2018-03-08
            相关资源
            最近更新 更多