0

我正在编写一个具有“成就”系统的应用程序,类似于 Stack Overflow 的徽章。我也在使用 SugarORM 来存储成就的进度。这是Achievement课程:

public class Achievement extends SugarRecord<Achievement>{
    @StringRes
    public int shortNameId;
    @StringRes
    public int descriptionId;
    public int progressNow;
    public int fullProgress; 
    //I am afraid that Sugar ORM will ignore private fields 
    //so I made them public. Please tell me if Sugar ORM does
    //not ignore those.
}

现在我想覆盖equals. 这很容易。

@Override
public boolean equals (Object other) {
    if (other == null) return false;
    if (!(other instanceof Achievement)) return false;
    Achievement a = (Achievement)other;
    return a.shortNameId == shortNameId &&
            a.descriptionId == descriptionId &&
            a.fullProgress == fullProgress;
}

hashCode然后我记得如果我覆盖,我应该总是覆盖equals。根据Joshua Bloch 的Effective Java,我写了hashCode这样的方法:

@Override
public int hashCode () {
    int result = 17;
    result = result * 31 + shortNameId;
    result = result * 31 + descriptionId;
    result = result * 31 + fullProgress;
    return result;
}

然后我认为我应该将实现更改equals

@Override
public boolean equals (Object other) {
    if (other == null) return false;
    if (!(other instanceof Achievement)) return false;
    Achievement a = (Achievement)other;
    return a.hashCode() == hashCode ();
}

在那之后,我认为如果我hashCode错误地覆盖,equals也不会工作。但是,上面的实现对我来说似乎是“正确的”,因为我认为哈希码是使对象相等的原因。

PS不要告诉我这是个人喜好。我认为这必须有一个标准,对吧?而且我也非常愿意遵循标准。

4

1 回答 1

3

一般来说a.hashCode()==b.hashCode(),这并不意味着a.equals(b)一定是真的。因此,您不应该依靠hashCode来确定平等。

然而,另一个方向是正确的。如果a.equals(b)thena.hashCode()必须等于b.hashCode()

于 2015-11-01T08:28:56.707 回答