Java - 两个HashSets是否同样加班?

时间:2018-04-12 12:35:36

标签: java hashset

我已经研究了不同的问题,但这些问题通常会询问一致性或排序,而我有兴趣同时订购两个包含相同元素的HashSets。

我想创建一个包含整数的HashSet的HashSet。随着时间的推移,我将把大小为3的HashSets放在这个更大的HashSet中,我想看看新创建的HashSet是否已经包含在更大的HashSet中。

现在我的问题是它总是会发现重复,或者两个具有相同元素的HashSets的排序是否会有所不同?

我因为使用​​相同的hashcode()函数而发生冲突,但这是否意味着它们总是相同?

HashSet<HashSet<Integer>> test = new HashSet<>();
HashSet<Integer> one = new HashSet<>();
one.add(1);
one.add(2);
one.add(5);
test.add(one);
HashSet<Integer> two = new HashSet<>();
two.add(5);
two.add(1);
two.add(2);
//Some other stuff that runs over time
System.out.println(test.contains(two));

上面的代码试图说明我的意思,这总是会返回真的吗? (请记住,我可能会使用相同的元素初始化另一个HashSet并再次尝试包含)

3 个答案:

答案 0 :(得分:3)

是的,上面总是返回true。 Set没有顺序,当您测试两个Set是否彼此相等时,您正在检查它们是否具有相同的元素。订单没有意义。

详细说明,test.contains(two)将返回true,前提是test仅包含与hashCode()相同的two元素,等于two (根据equals方法)。

具有相同元素的两组s1s2具有相同的hashCode()s1.equals(s2),返回true。

这是equals界面的hashCodeSet合同所要求的:

  

<强>等于

     

将指定对象与此集进行相等性比较。如果指定的对象也是一个集合,则返回true,两个集合具有相同的大小,并且指定集合的​​每个成员都包含在此集合中(或者等效地,此集合的每个成员都包含在指定的集合中)。此定义确保equals方法在set接口的不同实现中正常工作。

     

<强>的hashCode

     

返回此set的哈希码值。集合的哈希码被定义为集合中元素的哈希码的总和,其中空元素的哈希码被定义为零。 这确保了s1.equals(s2)意味着对于任何两个集合s1和s2 的s1.hashCode()== s2.hashCode(),正如Object.hashCode的常规协定所要求的那样。 / p>

如您所见,onetwo甚至不必使用Set接口的相同实现,以使test.contains(two)返回true。它们只需包含相同的元素。

答案 1 :(得分:0)

集合的属性与键的唯一性有关。

按&#34;默认&#34;,广告订单根本不重要。

链接 LinkedHashSet向您保证迭代时,您获得的元素总是以相同的顺序(用于插入它们的顺序)。但即便如此,在比较这些集时,仍然只是关于他们的内容,而不是插入顺序部分。

换句话说:无论您正在使用的Set接口的什么(默认)实现,您都应该始终看到一致的行为。当然,您可以自由地实施自己的套装并违反该合同,但是,违反合同会导致违反合同,即错误。

答案 2 :(得分:-1)

You can look for yourself,这是开源代码:

public boolean equals(Object o) {
    if (o == this)
        return true;

    if (!(o instanceof Set))
        return false;
    Collection<?> c = (Collection<?>) o;
    if (c.size() != size())
        return false;
    try {
        return containsAll(c);
    } catch (ClassCastException unused)   {
        return false;
    } catch (NullPointerException unused) {
        return false;
    }
}

public int hashCode() {
    int h = 0;
    Iterator<E> i = iterator();
    while (i.hasNext()) {
        E obj = i.next();
        if (obj != null)
            h += obj.hashCode();
    }
    return h;
}

您可以很容易地看到哈希码将是元素哈希码的总和,因此它不受任何顺序的影响,并且等于使用containsAll(...)所以此处顺序也无关紧要。< / p>