简体   繁体   English

ArrayList 对象如何存储在 Java 的 HashSet 中?

[英]How the ArrayList objects are stored inside a HashSet in Java?

Today I was doing a question and in that they have used a code similar to this.今天我在做一个问题,因为他们使用了与此类似的代码。 I am amazed to see this.我很惊讶地看到这一点。 I thought every HashSet stores the hash of an object and the answer would be 2. However, the answer to this 1. Could anyone explain what actually happens internally when I store HashSet of ArrayList of objects and why the answer is 1 instead of 2?我认为每个HashSet都存储 object 的 hash ,答案是 2。但是,这个 1 的答案。谁能解释当我存储HashSetArrayList时内部实际发生了什么?

import java.io.*;
import java.util.*;

class Code {
    public static void main (String[] args) {
        
        HashSet<ArrayList<Integer>> set=new HashSet<>();
        ArrayList<Integer> list1=new ArrayList<>();
        ArrayList<Integer> list2=new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list2.add(1);
        list2.add(2);
        set.add(list1);
        set.add(list2);
        System.out.println(set.size()); // 1
    }
}

Two instances of List are considered "equal" if they have the same elements in the same order .如果 List 的两个实例具有相同 order 中的相同元素,则它们被认为是“相等的”。 So that means list1 and list2 are "equal".这意味着 list1 和 list2 是“相等的”。 By the general contract of the hashCode method they must also have the same hash code根据hashCode方法的一般约定,它们也必须具有相同的 hash 代码

HashSet does not store duplicate items: if you give it two items that are equal it stores only the first one. HashSet 不存储重复的项目:如果你给它两个相等的项目,它只存储第一个。 So here it's storing list1 only.所以这里它只存储 list1 。

The answer is 1 because both Lists contain the same elements.答案是1 ,因为两个列表都包含相同的元素。 The hash code of an ArrayList is a function of the hash codes of all elements in the list. ArrayList 的 hash 代码是 Z0800FC577294C34E0B28AD2893 中所有元素的列表 4 个代码的 function。 In your case, both lists contain the same elements which means they correspond to the same hash code.在您的情况下,两个列表都包含相同的元素,这意味着它们对应于相同的 hash 代码。

HashSet implements the Set interface, backed by a hash table. HashSet实现了Set接口,由 hash 表支持。 Any implementation of Set simply discards the duplicate elements. Set的任何实现都会简单地丢弃重复的元素。 Since both list1 and list2 are equal, set will discard list2 when you try to insert it into into set when set already has list1 .由于list1list2是相等的,当您尝试将 list2 插入setset将丢弃list2 ,而set已经有list1 Thus, the size of set remains 1 .因此, set的大小保持为1

Here both the list values are equal so there hashcode is also the same by the contract and hashset stores hash value of its object and doesn't contain duplicates so list1 is replaced with list2 and hence the size is 1.这里两个列表值相等,因此合约的哈希码也相同,哈希集存储其 object 的 hash 值并且不包含重复项,因此 list1 被替换为 list2,因此大小为 1。

It would follow its default behaviour - it would first check if there is any existing entry (using hashCode() and equals() ) and if found, it would replace it and if not, it would insert it.它将遵循其默认行为 - 它会首先检查是否存在任何现有条目(使用hashCode()equals() ),如果找到,它将替换它,如果没有,它将插入它。

Note that the hashCode() and equals() method invocations will eventually get invoked on the object-entry - in this case the ArrayList object itself (ArrayList inturn inherits the methods from AbstractList ).请注意, hashCode()equals()方法调用最终将在对象条目上调用 - 在这种情况下, ArrayList object 本身(ArrayList 又继承了AbstractList的方法)。

PS: It appears HashSet is implemented internally as a HashMap ! PS:似乎 HashSet 在内部实现为 HashMap

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

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