如何防止将重复对象添加到ArrayList

Lon*_*guy 16 java oop data-structures

可能重复:
防止arraylist中的重复条目

我有一个特定班级C的arraylist.

List<C> myList = new ArrayList<C>();
Run Code Online (Sandbox Code Playgroud)

C类有两个属性即.

String str1;
String str2;
Run Code Online (Sandbox Code Playgroud)

现在,当我将类型C的对象添加到ArrayList myList时,我想检查列表中是否已存在一个对象,其中str1和str2的值与对象的参数(str1和str2)的值相匹配我即将补充.

有没有有效的方法来做到这一点,而不必每次遍历完整列表并检查参数之间的匹配?

Kar*_*k T 39

当您需要检查重复项或确保唯一值时,请考虑使用类似Set的数据结构,而不是List.

您可以选择以下其中一种 -

  • HashSet的

    • 更快的访问 - 粗略地说O(1)访问.
    • 没有排序
    • 哈希表用作基本存储.
  • TreeSet中

    • 访问速度较慢(相对于HashSet) - O(log(n))
    • 值自动排序.
    • 红黑树用作基础存储.

自动设置仅允许唯一值.尝试添加以前存在的值将失败.

请注意,要使其工作,您需要覆盖equalshashcode告诉Set如何比较对象.这个步骤可以更好地解释在Java中覆盖equals和hashCode时应该考虑哪些问题?

  • 应该指出的是,当它们的`hashCode`方法返回的值相等时,Set认为两个对象是相等的.如果希望将具有相同内容的两个不同对象视为重复项,则需要覆盖hashCode方法,以便从对象的所有相关字段计算它. (3认同)

cow*_*wls 19

您需要覆盖equalsC类中的方法.

例如

public boolean equals(Object c) {
    if(c !instanceof C) {
        return false;
    }

    C that = (C)c;
    return this.str1.equals(that.getStr1()) && this.str2.equals(that.getStr2());
}
Run Code Online (Sandbox Code Playgroud)

然后你可以调用myList.contains(即)来查看列表是否已经包含一个相等的对象.

这是未经测试的,您可能需要一些额外的错误处理.

如果你确实覆盖了这样的equals方法,你还应该确保覆盖hashcode()方法.请参阅:http://www.technofundo.com/tech/java/equalhash.html

编辑:正如评论中指出的那样,set实现会更有效,尽管你仍然需要覆盖equals/hashcode方法,所以上面的例子最好与上面的Karthiks答案一起使用.

  • 应该指出的是,大多数List实现类的`contains`方法对大型列表的扩展性很差,因为需要检查列表的每个条目.在这种情况下,大多数Set-实现都是优越的. (2认同)

小智 12

if (yourList.contains(Object object))
{
    // do not add
}
Run Code Online (Sandbox Code Playgroud)

  • 应该指出的是,大多数List实现类的contains方法确实对大型列表进行了严格的扩展,因为需要检查列表的每个单独条目.在这种情况下,大多数Set-实现都是优越的. (2认同)