简体   繁体   English

如何在内部避免重复?

[英]How sets avoid duplicates internally?

I had a doubt about the set in Collections framework. 我对Collections框架中的set有疑问。 How the set itself will identify duplicates and how it will come to know? 集合本身将如何识别重复项以及它将如何识别? Could anyone please explain how it is implemented? 谁能解释一下它是如何实现的? How hashcode and equals method will come into the picture? 哈希码和等于方法将如何进入图片? I need a brief explanation as it is really important for me. 我需要一个简短的解释,因为它对我来说非常重要。

It roughly works like this 它大致类似于此

if (!collection.contains(element))
    collection.add(element);

And the contains method, would use equals/hashcode. 而contains方法,将使用equals / hashcode。

In TreeSet, the elements are stored in a Red-Black Tree, whereas HashSet, uses a HashMap. 在TreeSet中,元素存储在红黑树中,而HashSet使用HashMap。

Infact, the way it is added to the container is specific to the element (the spot on the tree, bucket in the hashtable), thus the adding itself uses equals/hashcode. 事实上,它添加到容器的方式特定于元素(树上的点,哈希表中的桶),因此添加本身使用equals / hashcode。

This is explained in the javadoc for Set . 这在Setjavadoc中有解释

A collection that contains no duplicate elements. 不包含重复元素的集合。 More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. 更正式地说,集合不包含元素对e1和e2,使得e1.equals(e2)和至多一个null元素。

HashSet使用hashcode()解析对象应该去的bucket和equals()方法来检查位于该bucket上的对象的相等性

The actual implementation depends on the container. 实际的实现取决于容器。 HashMap lookup the item bucked given its hashCode then test the inserted object and the stored ones by using equals (this is one of the reasons for requiring that a.equals(b) iff b.equals(a) ). HashMap在给定hashCode查找项目,然后使用equals测试插入的对象和存储的对象(这是要求a.equals(b) iff b.equals(a) )的原因之一。

TreeMap , on the other hand, relies on the result of the compareTo method (if the element implements Comparable or the compare method implemented by a Comparator ). TreeMap ,在另一方面,依赖于结果compareTo方法(如果该元件实现Comparablecompare用实施的方法Comparator )。 If compare returns 0, the elements are regarded as "equals". 如果compare返回0,则元素被视为“等于”。 (Note that compareTo should be consistent with equals , ie a.compareTo(b)==0 iff a.equals(b) ). (注意, compareTo应该与equals一致 ,即a.compareTo(b)==0 iff a.equals(b) )。

"Can u please explain with these example. s.add("123");s.add("123");" “你可以用这些例子来解释.s.add(”123“); s.add(”123“);”

For the above query explained in context with Set interface, Please refer to the below snippet and explanation. 对于上面使用Set界面解释的查询,请参考下面的代码片段和说明。

public void setTest() {
    Set<String> obj = new HashSet<>();
    System.out.println(obj.add("123")); //Output : true
    System.out.println(obj.add("123")); //Output : false
}

If you notice in the above snippet, we have added 123 two times. 如果您在上面的代码段中注意到,我们已经添加了两次123。 for the first time add SOP will return true. 第一次添加SOP将返回true。 then for the second time of added "123", SOP will return false. 然后第二次添加“123”,SOP将返回false。

With this we can understand that, if we add same value in the Set for the second time or more, then the duplicated value will be skipped . 有了这个,我们可以理解, 如果我们第二次在Set中添加相同的值,那么将跳过重复的值

Basically set is an interface which has many different implementations, let's take HashSet implementation for now, to answer you question, I downloaded the source code and went inside the HashSet class, then I searched add method and saw that it uses HashMap to store unique values. 基本上set是一个有很多不同实现的接口,让我们暂时使用HashSet实现,回答你的问题,我下载了源代码并进入了HashSet类,然后我搜索了add方法并看到它使用HashMap来存储唯一值。 It uses the value to be stored as key of a HashMap and the corresponding value of key (ie PRESENT in below code snippet) as a constant value(this value is a dummy value), we all know that keys of map are unique. 它使用值作为HashMap的键和key的相应值(即下面代码片段中的PRESENT)作为常量值(此值是虚拟值),我们都知道map的键是唯一的。 So that is how it works. 这就是它的工作原理。 Code below: 代码如下:

private static final Object PRESENT = new Object();
public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM