java Set&lt;List &gt;在< Integer>概念上是如何工作的

ijnw1ujt  于 2023-05-21  发布在  Java
关注(0)|答案(2)|浏览(118)

我写了一个程序如下:

public static void main(String[] args) {
        Set<List<Integer>> s = new HashSet<>();
        List<Integer> l1 = new ArrayList<>(List.of(1,2,3));
        List<Integer> l2 = new ArrayList<>(List.of(1,2,3));
        List<Integer> l3 = new ArrayList<>(List.of(3,2,1));
        s.add(l1);
        if(s.contains(l2)) {
            System.out.println("l2 is already present");
        }
        if(s.contains(l3)) {
            System.out.println("l3 is present");
        } else {
            System.out.println("l3 is absent");
        }
}

下面是输出:

l2 is already present
l3 is absent

我对Java中的equalshashcode有一个大致的概念,对Object类型有一个大致的概念,等等。
有人能从概念上解释一下这个东西是如何在内部比较一个整数列表并发现它是否已经存在的吗?注意,只有当列表中元素的顺序相同时,它才有效。

dtcbnfnu

dtcbnfnu1#

HashSet依赖于元素类型的equalshashCode方法(在本例中为List)。List类型上这些方法的文档如下:
equals-将指定的对象与此列表进行相等性比较。当且仅当指定的对象也是一个列表,两个列表具有相同的大小,并且两个列表中所有对应的元素对都相等时,返回true。(如果Objects.equals(e1,e2),则两个元素e1和e2相等。)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。
hashCode-返回此列表的哈希代码值。列表的哈希码被定义为以下计算的结果:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

这确保了list1.equals(list 2)意味着对于任何两个列表list 1和list 2,list1.hashCode()==list2.hashCode(),正如Object.hashCode()的一般约定所要求的那样。
也就是说,ListhashCodeequals实现只是对列表中的每个元素进行操作。

v6ylcynt

v6ylcynt2#

HashSet#contains(Object o) javadoc声明如下(强调我的):
如果此集合包含指定的元素,则返回true。更正式地说,当且仅当这个集合包含一个元素e,使得(o==null?e==null:o.equals(e))。
因此,这意味着当您检查s.contains(l2)时,s中的List实际上是通过List#equals()内部检查l2是否相等。
List#equals(Object o) javadoc声明(强调我的):
比较指定对象与此列表是否相等。当且仅当指定的对象也是一个列表,两个列表具有相同的大小,并且两个列表中所有对应的元素对都相等时,返回true。(两个元素e1和e2相等,如果(e1==null?e2==null:e1.equals(e2)).)**换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。**此定义确保equals方法在List接口的不同实现中正常工作。
这就是为什么l2被发现包含在s中,而l3没有。

相关问题