3

我有一堂课

final class BuildingPair {

    int mBA;
    int mBB;

    public BuildingPair(int pBuildingA,int pBuildingB) {
        mBA = pBuildingA;
        mBB = pBuildingB;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + mBA;
        result = prime * result + mBB;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        BuildingPair other = (BuildingPair) obj;
        if ((mBA==other.mBA&&mBB==other.mBB)||(mBA==other.mBB&&mBB==other.mBA)) return true;
        return false;
    }
}

我想比较两个对象,当它们具有相同的建筑物 id 时,它们是相等的

所以它们在以下情况下需要在两个方向上相等:

BuildingPair(1,2) vs BuildingPair(2,1) 
BuildingPair(1,2) vs BuildingPair(1,2)
BuildingPair(2,1) vs BuildingPair(1,2)

我认为equals方法还可以,但是hashcode是错误的。

4

3 回答 3

8

您需要计算相同结果的东西,无论是通过A,B还是B,A. 可能有更微妙的解决方案,但我可能会选择:

@Override
public int hashCode() {
    return mBA * mBB;
}

或任何其他使用可交换运算符的东西。


或者,您可以更改您的构造函数,使其始终存储min(a,b)mBA其中- 然后您可以简化您max(a,b)mBB比较代码并保持您的哈希代码为当前状态。

于 2012-08-15T13:22:11.600 回答
3

您需要一个对称哈希码 ( hashcode(a,b) == hashcode(b,a)),例如:

return mBB ^ mBA;

(您当前的代码不是对称的 - 例如:hascode (2,1) = 1024 但 hashcode(1,2) = 994)

注意:这是从哈希码的启发Long

return (int)(value ^ (value >>> 32));
于 2012-08-15T13:21:53.797 回答
3

如果它们是无序的,您可以使用任意顺序来简化其余代码。

public BuildingPair(int pBuildingA,int pBuildingB) {
    mBA = Math.min(pBuildingA, pBuildingB);
    mBB = Math.max(pBuildingA, pBuildingB);
}

将其余方法编码为正常,BuildingPair(2,1) 将与 BuildingPair(1,2) 完全相同

于 2012-08-15T13:26:09.727 回答