Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何防止向ArrayList添加重复对象_Java_Oop_Data Structures - Fatal编程技术网

Java 如何防止向ArrayList添加重复对象

Java 如何防止向ArrayList添加重复对象,java,oop,data-structures,Java,Oop,Data Structures,可能重复: 我有一个特定C类的数组列表 List<C> myList = new ArrayList<C>(); 现在,当我将C类型的对象添加到ArrayList myList时,我想检查列表中是否已经存在一个对象,其str1和str2的值与我要添加的对象的参数(str1和str2)的值匹配 有没有一种有效的方法来完成这个过程而不必每次迭代遍历完整的列表并检查参数之间的匹配?当您需要检查重复或确保唯一值时,考虑使用类似的数据结构,而不是列表。 您可以从以下选项中进行选

可能重复:

我有一个特定C类的数组列表

List<C> myList = new ArrayList<C>();
现在,当我将C类型的对象添加到ArrayList myList时,我想检查列表中是否已经存在一个对象,其str1和str2的值与我要添加的对象的参数(str1和str2)的值匹配


有没有一种有效的方法来完成这个过程而不必每次迭代遍历完整的列表并检查参数之间的匹配?

当您需要检查重复或确保唯一值时,考虑使用类似的数据结构,而不是列表。

您可以从以下选项中进行选择-

    • 更快的访问—粗略地说是O(1)访问
    • 未分类
    • 用作基本存储的哈希表
    • 访问速度较慢(相对于哈希集)-O(log(n))
    • 自动排序的值
    • 红黑色的树,用作基本存储
自动设置仅允许唯一值。尝试添加以前存在的值将失败


请注意,要使其工作,您需要覆盖
equals
hashcode
,以告知
集合
如何比较对象。这一步在

中有更好的解释,您需要重写类C中的
equals
方法

e、 g

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

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

如果确实像这样重写equals方法,还应该确保重写hashcode()方法。见:

编辑
正如评论中指出的,set实现将更加高效,尽管您仍然需要重写equals/hashcode方法,因此上面的示例最好与上面的Karthiks答案结合使用。

使用java.util.set接口,最好使用TreeSet实现,而不是List。一套自动满足您的需求。您只需将字符串值添加到集合中。在网上搜索或阅读一本关于数据结构的书,了解Set是如何工作的。这里:应该指出的是,大多数列表实现类的
包含的
方法对于大型列表的伸缩性很差,因为列表中的每个条目都需要检查。在这种情况下,大多数Set实现都是优越的,但这将遍历整个列表。就像OP想要避免的手写版本一样低效,但是更干净code@Karthik,很好,更新了我的答案,并加上一条注释:)谢谢,我接受了你的答案,因为我的列表长度不长,时间优化也不是一个严格的限制。我觉得这是一种很好的编写equals方法的小方法,只需使用contains检查来查看它是否已经存在。它起作用了!应该指出的是,大多数列表实现类的contains方法对于大型列表的伸缩性很差,因为需要检查列表的每个条目。在这种情况下,大多数集合实现都是优越的。应该指出的是,当两个对象的
hashCode
方法返回的值相等时,集合认为两个对象相等。如果希望两个内容相同的不同对象被视为重复对象,则需要重写hashCode方法,以便从该对象的所有相关字段计算该方法。因此,如果我使用HashSet(我不希望使用排序集),并且如果我尝试添加一个对象,它基本上会检查集合中是否存在另一个参数值相同的对象吗?@Philipp谢谢Philipp。这正是我想要的。我想检查是否存在另一个具有相同相等内容的对象,而不是根据任何不同的标准检查这两个对象是否相等。如何覆盖hashCode方法?@AbhishekShivkumar正如Philipp提到的那样,您需要覆盖
equals
hashCode
来告诉
集合
如何比较objects@AbhishekShivkumar要重写hashCode方法,请创建一个方法
@override public int hashCode()
并以基于str1和str2内容计算整数的方式实现它。当您没有编写好的哈希函数的经验时,可以采用str1和str2的hashCode方法,并以某种方式组合这些值。您可以对它们进行异或或相加,同时也可以对其中一个值进行位移位或相乘(这样它们就不能互换)。
String str1;
String str2;
if (yourList.contains(Object object))
{
    // do not add
}
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());
}