您是否应该在插入集合之前检查重复项

时间:2016-01-10 23:50:14

标签: java performance set big-o

我正在学习使用套装。我的问题是:集合不包含重复项。当我们尝试插入重复项时,它不会抛出任何错误并自动删除重复项。在插入集合之前检查每个值是否存在是否是一个好习惯?或者可以执行类似下面的代码?我认为Java会在内部使用.contains(value)进行检查。你觉得怎么样?

考虑到 n 元素进入集合,两种情况下的Big O复杂性是什么?

import java.util.HashSet;
import java.util.Set;

public class DuplicateTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
         Set<Integer> mySet = new HashSet<Integer>();

         mySet.add(10);
         mySet.add(20);
         mySet.add(30);
         mySet.add(40);
         mySet.add(50);
         mySet.add(50);
         mySet.add(50);
         mySet.add(50);
         mySet.add(50);
         mySet.add(50);

         System.out.println("Contents of the Hash Set :"+mySet);
    }

}

5 个答案:

答案 0 :(得分:23)

根据docs

  

public boolean add(E e)

     

如果指定的元素尚不存在,则将其添加到此集合中。更正式地,如果此集合不包含元素e2(e == null?e2 == null:e.equals(e2)),则将指定元素e添加到此集合。 如果此set已包含该元素,则调用将保持set不变并返回false。

因此add()方法已经返回true或false。所以你不需要做额外的检查。

答案 1 :(得分:9)

the API documentation of Set.add(E)

比较

add方法检查该元素是否已在Set中。如果元素已存在,则不添加新元素,Set保持不变。在大多数情况下,您不需要检查任何内容。

该方法的复杂性取决于您正在使用的Set的具体实现。

答案 2 :(得分:4)

可以不检查。这是优于列表集的主要优势,因为它们会自动过滤掉重复项。

HashSet具有恒定的时间性能(http://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html

  

该类为基本操作(添加,删除,包含和大小)提供恒定的时间性能,假设散列函数在桶之间正确地分散元素

答案 3 :(得分:2)

add函数返回一个布尔值,您可以检查该布尔值以确定该项是否已在Set中。这当然是基于您的需求而不是最佳实践。很高兴知道它不会删除已经存在的项目,因此如果您根据数据库中的代理键定义等于,则不能依赖于使用新信息更新现有值。这与地图作为地图工作的方式将返回任何现有值并将其替换为新值。

答案 4 :(得分:1)

以下是您的问题的答案:

  

当我们尝试插入重复项时,它不会抛出任何错误   自动删除重复项。

您的理解不正确。如果新项目已在集合中,则对Set.add()的调用不会添加新项目;此声明适用于Set的所有实施,包括HashSetTreeSet

  

在插入set之前检查每个值是否是一个好习惯   是否存在?或者可以做下面这样的事情   码?我认为java会在内部进行检查   .contains(价值)。你觉得怎么样?

由于您的理解从一开始就不正确,因此您无需在插入集合之前检查每个值以查看它是否已存在。是的,在内部,它正在做contains()

之类的事情
  

在考虑这两种情况下,大喔的复杂性是什么?   有&#34; n&#34;元素进入集合?

对于HashSet,每个O(1)的时间复杂度为add()。对于TreeSet() - 您没有使用 - 每个O(lg N)的时间复杂度为add()