If you simply want to know if the sets are equal, the equals method on AbstractSet is implemented roughly as below:
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;
return containsAll(c);
}
Note how it optimizes the common cases where:
这两个物体是一样的
另一个对象根本不是一个集合
这两套尺寸不同。
After that, containsAll(...) will return false as soon as it finds an element in the other set that is not also in this set. But if all elements are present in both sets, it will need to test all of them.
You could take this idea a bit further ... at least in theory.
警告 -这是高度推测性的。如果你愿意,可以称之为“思维实验”。
假设您的 set 元素类有一个方法来返回元素的加密校验和。现在通过 XORing 为元素返回的校验和来实现集合的校验和。
这能给我们带来什么?
好的,如果我们假设下面没有什么事情发生,那么任意两个不等集合元素具有相同 N 位校验和的概率是2不。并且2个不等集具有相同 N 位校验和的概率也是2不。因此,我的想法是,您可以按以下方式实现 equals:
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;
return checksums.equals(c.checksums);
}
Under the assumptions above, this will only give you the wrong answer once in 2不 time. If you make N large enough (e.g. 512 bits) the probability of a wrong answer becomes negligible (e.g. roughly 10-150).
The downside is that computing the crypto checksums for elements is very expensive, especially as the number of bits increases. So you really need an effective mechanism for memoizing the checksums. And that could be problematic.
Set<String> set = new HashSet<>();
set.addAll(Arrays.asList("leo","bale","hanks"));
Set<String> set2 = new HashSet<>();
set2.addAll(Arrays.asList("hanks","leo","bale"));
Predicate<Set> pred = set::equals;
boolean result = pred.test(set2);
System.out.println(result); // true