Guava和Apache Commons Hash/Equals构建器比较

16

我想知道Guava与Apache Commons在equals和hashCode builder方面的主要区别。

equals:

Apache Commons:

public boolean equals(Object obj) {
    if (obj == null) { return false; }
    if (obj == this) { return true; }
    if (obj.getClass() != getClass()) { return false; }
    MyClass other = (MyClass) obj;
    return new EqualsBuilder()
            .appendSuper(super.equals(obj))
            .append(field1, other.field1)
            .append(field2, other.field2)
            .isEquals();
}

番石榴:

public boolean equals(Object obj) {
    if (obj == null) { return false; }
    if (obj == this) { return true; }
    if (obj.getClass() != getClass()) { return false; }
    MyClass other = (MyClass) obj;
    return Objects.equal(this.field1, other.field1)
            && Objects.equal(this.field1, other.field1);
}

哈希码:

Apache Commons:

public int hashCode() {
    return new HashCodeBuilder(17, 37)
            .append(field1)
            .append(field2)
            .toHashCode();
}

番石榴:

public int hashCode() {
    return Objects.hashCode(field1, field2);
}

看起来,Guava版本的代码可读性有所提升。

我从https://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained上找不到更多信息。如果有的话,了解更多差异(特别是任何性能改进)会很有用。


Apache会创建一个临时对象,但它也支持通过反射快速构建原型代码。 - Ben Manes
正确的。谢谢,Ben。 - Abhishek
还可以考虑使用类似 AutoValue 的工具来生成值对象的 equals/hashCode/toString 等方法。 - ColinD
相关:Java 7 包含 Objects.equalsObjects.hash,它们的工作方式类似于 Guava 的。 - laffuste
1
尽管OP的作者具有可读性,但仍犯了两次比较field1并忘记了field2(guava equals)的错误。使用普通实现,静态代码分析器会发出警报... - Daniel Alder
2个回答

24
我把这种区别称为“存在性”。Apache Commons中有EqualsBuilderHashCodeBuilder,而Guava中没有生成器。 Guava提供了一个实用程序类MoreObjects(从Objects重命名,因为现在JDK中有这样的类)。
Guava方法的优点来自于不存在生成器:
  • 它不会产生垃圾
  • 它更快
通过Escape Analysis JIT编译器可能会消除垃圾以及相关开销。然后它们变得同样快,因为它们完全相同。
个人认为生成器稍微更易读。如果您发现不使用它们更好,则Guava肯定适合您。如您所见,静态方法已足够完成任务。
还要注意,ComparisonChain也是一种Comparable-builder类型。

1
Objects.hashCode 会为可变参数或自动装箱分配内存。另外请注意,ComparisonChain 看起来像是一个构建器,但实际上并不会分配任何内存。 - ColinD
我想知道Hotspot需要多长时间来优化这个,因为我刚刚重新做了我的微基准测试,使用inline实现hashCode仍然是最快的,使用HashCodeBuilder不会显著变慢,但使用Objects.hash(...)则要慢20倍。在最坏的情况下,你要散列的所有内容都是整数。 - Hakanai

0

在底层,Guava使用Arrays.hashCode()。Varargs会带来性能损失,并且存在自动装箱的潜在问题,这将再次导致性能下降。根据Java的文档

如果数组包含其他数组作为元素,则哈希码基于它们的标识而不是它们的内容

Objects.hasCode的替代方法可能是Objects.deepHashCode,但Guava没有使用它。并且在存在循环引用的情况下有缺陷

因此,在包含自身作为元素的数组上调用此方法是不可接受的

通常情况下,Apache Commons更像deepHashCode,但可能会添加反射并解决所有上述问题,但(可以说)可能会遭受更糟糕的性能。

从表单设计角度来看,Apache Commons实现了Effective Java第10和11项规则。这使得它具有非常不同的感觉


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接