当我们尝试在Hashset中添加重复对象时,为什么编译器不会阻止我们?

时间:2017-06-05 07:50:03

标签: java exception collections hashset

我知道HashSet不会不重复对象,当我尝试下面的代码时,它只需添加第一个而忽略第二个。为什么没有检查异常。如何为HashSet实现add()?

public static void main (String[] args) throws java.lang.Exception
{
    HashSet Hs = new HashSet();
    Hs.add("A");
    Hs.add("A");
    System.out.println(Hs);
}

输出 - [A]

4 个答案:

答案 0 :(得分:3)

Set界面允许您尝试反复添加相同的元素。它只是第一次添加元素。

尝试多次添加同一元素并不是错误。

  

布尔值java.util.Set.add(E e)

     

如果指定的元素尚不存在,则将其添加到此集合中(可选操作)。更正式地,如果集合不包含元素e2,则将指定的元素e添加到该集合中(e == null?e2 == null:e.equals(e2))。 如果此集合已包含该元素,则调用将保持设置不变并返回false 。结合对构造函数的限制,这可以确保集合永远不会包含重复元素。

这允许您检查元素是否属于Set,如果没有单个语句,则将其添加到Set

if (set.add(value)) { 
    .... // will be executed only if the value was added
}

而不是更长的

if (!set.contains(value)) {
    set.add(value);
    ....
}

答案 1 :(得分:1)

  

在传递重复元素时内部会发生什么   set对象的add()方法,它将返回false而不添加   到HashSet,因为元素已经存在。太好了。   但主要问题是它如何返回错误。所以这是   回答当你在中打开add()方法的HashSet实现时   Java Apis即rt.jar,您将在其中找到以下代码。

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
    private transient HashMap<E,Object> map;
    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();
    public HashSet() {
        map = new HashMap<>();
    }
    // SOME CODE ,i.e Other methods in Hash Set
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
    // SOME CODE ,i.e Other methods in Hash Set
}

因此,我们通过HashMap在Java内部实现了Set的唯一性。每当你创建一个HashSet对象时,它将创建一个HashMap对象,你可以在上面代码的斜体线中看到。

答案 2 :(得分:1)

当您尝试在集合中添加值并且当时没有出现在集合中时它将被添加并且add方法将返回true,但是如果该值已经存在于此时设置添加方法将返回false。 当你尝试在Set中添加一个值时,set.add()方法不应该给你一个错误,它只会返回false。

https://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html#add%28E%29

答案 3 :(得分:0)

检查集合中的重复值是运行时的责任,但编译器。在编译java代码时,编译器对集合的内容一无所知。因此,您不会看到任何警告,建议等。

我希望这会回答你的问题。