番石榴 vs Apache Commons Hash/Equals Builders

2022-09-03 13:11:34

我想知道Guava与Apache Commons在平等和hashCode构建器方面的关键区别是什么。

等于

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 找到更多信息。如果有的话,了解更多差异(特别是任何性能改进?)将是有用的。


答案 1

我把这种差异称为“存在”。在Apache Commons中有,在Guava中没有构建器。你从番石榴得到的只是一个实用程序类(重命名为现在JDK中有这样一个类)。EqualsBuilderHashCodeBuilderMoreObjectsObjects

番石榴方法的优势来自于建筑商的不存在:

  • 它不产生垃圾
  • 它更快

JIT 编译器可以通过转义分析消除垃圾以及相关的开销。然后,它们变得同样快,因为它们完全相同。

我个人认为构建器的可读性稍微强一些。如果您发现不使用它们更好,那么番石榴肯定是适合您的东西。如您所见,静态方法对于任务来说已经足够好了。

还要注意,还有一个ComposerChain,它是一种可比构建器。


答案 2

在引擎盖下,Guava使用Arrays.hashCode()。Varagrs会降低性能,并且可能会自动装箱,这再次会对性能造成影响。根据Java的文档

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

Objects.hasCode的替代品可能是Objectes.deepHashCode,但它没有被Guava使用。在循环引用的情况下它有一个缺点

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

通常,Apache Commons的工作方式更像deepHashCode,但可能会给图片添加反射并解决所有上述问题,但是(可以说)可能会遭受更差的性能。

表单设计视角 Apache Commons 实现了由 Effective Java 项 10 和 11 制定的规则。这增加了一种非常不同的感觉


推荐