Java 为什么编译器不';当我们试图在Hashset中添加重复的对象时,是否会阻止我们?

Java 为什么编译器不';当我们试图在Hashset中添加重复的对象时,是否会阻止我们?,java,exception,collections,hashset,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]通过设置界面,您

正如我所知,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]

通过
设置
界面,您可以尝试一次又一次地添加相同的元素。它只会在第一次添加元素

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

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

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

这允许您检查某个元素是否属于
集合
,如果不属于单个语句,则将其添加到
集合

if (set.add(value)) { 
    .... // will be executed only if the value was added
}
而不是更长的时间

if (!set.contains(value)) {
    set.add(value);
    ....
}
当您在中传递重复的元素时,内部会发生什么 Set对象的add()方法,它将返回false且不添加 到HashSet,因为元素已经存在。到目前为止还不错。 但主要的问题是它如何返回false。因此,这里是 在中打开add()方法的HashSet实现时回答 Java API即rt.jar,您将在其中找到以下代码

公共类哈希集
扩展抽象集
实现Set、Cloneable、java.io.Serializable
{
私有瞬态HashMap;
//要与背景贴图中的对象关联的虚拟值
私有静态最终对象存在=新对象();
公共哈希集(){
map=新的HashMap();
}
//一些代码,即哈希集中的其他方法
公共布尔加法(E){
返回map.put(e,PRESENT)=null;
}
//一些代码,即哈希集中的其他方法
}

因此,我们通过HashMap在java内部实现了集合的唯一性。无论何时创建HashSet对象,它都将创建一个HashMap对象,正如您在上述代码的斜体行中所看到的。

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


检查集合中的重复值是运行时的职责,但编译器不负责。编译java代码时,编译器对集合的内容没有任何概念。因此,你不会看到任何警告、建议等


我希望这能回答您的问题。

您为什么希望出现例外情况?这不是一个错误条件——这只是集合的行为。那么你的问题到底是什么?为什么编译器在添加重复条目时不抱怨?或者为什么没有检查异常?@AdrianShum你不认为这是相关的吗?如果在这种情况下定义了检查异常,你将自动获得CE。@Prabhazinghyadav不,不是。您的标题意味着“如果编译器看到一个集合中添加了重复的条目,它应该抱怨”(这显然是不会发生的)。而且,是否存在选中异常取决于集合API的设计,而不是编译器。@PrabhatSinghYadav不,这不是错误。集合不是“拒绝接收重复条目”。它是“只保留唯一的条目”。多次接收同一条目是Set收到的预期输入,如果该输入已经存在,Set将忽略该输入。如果您认为复制是有用的,您可以构建自己的数据结构,将其视为错误,但显然这不是SetAmit的意图,它给了我一些线索。
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
}