为大对象创建.hashcode()和.equals()方法

时间:2014-12-10 03:48:12

标签: java equals hashcode

我有一个有很多(大约100个)字段的课程。我想为这些字段实施hashCode()equals()方法,是否可以手动执行此操作?

4 个答案:

答案 0 :(得分:4)

没有好的答案。以下是一些建议。正如其他人评论的那样,100个领域太多了。你最好的选择是重构课程。但是,如果你必须把它们放在一起:

  • 您是否可以使用地图(或其他收藏品)来容纳多个字段?

如果是这样,您可以使用他们内置的hashCode()和equals()方法。 (或@ dimo414指出的番石榴等)

  • hashcode()应该只考虑不可变字段(或者至少很少变化的字段。)

如果只有少数字段是不可变的,那么这将大大简化您的hashCode()代码。而且,更重要的是,使其正确。 : - )

  • 有100多个字段,两个实例永远相等的现实可能性是什么?

如果答案是"非常罕见",问问自己是否可以使用基本的对象相等(实际上,使用==)?

  • 您是否已拥有信息丰富的 toString()方法?

如果是这样,您可以有时使用该String作为低效但易于编码的hashCode()和equals()。 e.g:

public int hashCode() { return this.toString().hashCode(); }

public boolean equals(Object o) {
   return (o instanceof MyClass) &&
          (this.toString().equals(o.toString()));
}

答案 1 :(得分:1)

其他人已经指出,这么大的物体可能不是一个很好的模式,所以我假设你已经知道并且已经决定继续进行。我也会假设这个对象(大部分)是不可变的,因为为可变对象实现.hashCode()通常是一个糟糕的计划(至少,你必须小心将可变对象放在{ {1}}或HashSet中的键。

如果您有一个包含大量字段的类,则可以通过利用执行相同操作的现有功能来避免定义复杂的HashMap.hashCode().equals()方法。一个简单的选择是构建字段的.toString()List,并简单地调用Map的相应方法。如果需要,您甚至可以缓存这些函数的返回值,而不是保留整个Collection

还有许多有用的实用程序可以使这些方法更容易;有太多的东西要列出,但我会试着说出一些特别有用的东西:

此外,您可以在运行时在对象中use reflection to get all the fields。这比硬编码实现要慢,但编写起来可能会更快。如果你不太关心速度,这是一个不错的选择。

答案 2 :(得分:0)

我认为最好使用 eclipse功能hashCode()equals()生成代码,这对于实现此方法非常有用。

答案 3 :(得分:0)

虽然拥有一个包含许多字段的对象并不是一个好习惯,但有时候遗留约束会让你陷入困境。

无论大小如何,我发现覆盖这些方法的最简单方法是使用Apache commons库。它使用反射从实例生成值,并且有许多方法可以配置结果。如果字段更新,我也永远不必记住重新生成方法,这与eclipse生成的方法不同。

@Override
public final boolean equals(final Object obj) {
    if (obj == this) {
        return true;
    }

    if(obj != null && obj.getClass() == this.getClass()) {
        return EqualsBuilder.relectionEquals(this, obj, true);
    }

    return false;
}

@Override
public final int hashCode() {
    return HashCodeBuilder.relectionHashCode(this);
}

@Override
public final String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}