我有一个 B 类定义如下 -->
Class B {
private List<String> obj1;
private List<A> obj2;
// Need to implement hashcode() and equals() methods
}
在我的代码中,我使用以下逻辑来识别对象类型 B 的重复(非唯一)元素 -->
Set<B> setBObjects = new HashSet<>();
for (B tempB : listOfBTypeObjects) {
boolean isUnique = setBObjects.add(tempB);
if (!isUnique) {
// Print non-unique elements
}
}
需要找到唯一的 B 类型元素,无论对象 B 中列表元素的顺序如何,例如
假设对象 B(B1) 的 1 个实例如下 ->
B1 ->
{
obj1 -> ["R", "G", "B"]
obj2 -> [objA1, objA2, objA3]
}
对象 B(B2) 的另一个实例如下 ->
B2 ->
{
obj1 -> ["B", "G", "R"] <<<< order of list is changed
obj2 -> [objA3, objA2, objA1] <<<< order of list is changed
}
现在,我希望 B1 和 B2 在上面的 set -> add() 操作中相同,我们可以在其中找到唯一元素。所以 B1 和 B2 将不是唯一的。
为了实现这一点,我应该如何为类 B 定义 hashcode() 和 equals() 方法?
整个设计有点有问题,但要说到你问题的实际要点,我认为是:
给定一个包含元素
的集合和另一个包含元素
["B", "G", "R"]
的集合,我将如何设置它们以使它们被认为彼此相等?
["R", "G", "B"]
答案是:对所有元素的 hashCode 进行异或(因为
A XOR B XOR C
与 C XOR A XOR B
的值相同 - 这是一个交换运算)。
对于平等来说,这就更棘手了;您将相等定义为集合以任意顺序包含相同的数据。要实现这一点:
对于 A 中的每个元素,检查它是否存在于 B 中。如果 B 是一个列表,那就
O(n^2)
;如果是一套,那就O(n)
。如果您希望用此编写的算法在输入变大时不会从性能方面跌落悬崖,那么这一点很重要,但如果输入很小(每个列表不超过几千个),则没关系。
您必须找出诸如
["R", "G", "B", "B"]
之类情况的答案 - 这等于["B", "R", "G"]
吗?如果不是,大小就成为一个因素,对于哈希编码,您会遇到一些麻烦(因为如果应用上述算法,即仅将所有内容异或在一起,["B", "B"]
的哈希码为0,即任何成对元素都会消除自身,因为x XOR x
对于任何
x
,都是 0),如果你实际上最终存储了
{"R": 1, "G": 1, "B": 2}
,事情就会简单得多相反。