【问题标题】:Guava Vs Apache Commons Hash/Equals buildersGuava Vs Apache Commons Hash/Equals 构建器
【发布时间】:2015-09-12 12:46:48
【问题描述】:

我想知道 Guava 与 Apache Commons 在 equals 和 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 找到更多信息。如果有任何差异,了解更多差异(尤其是任何性能改进?)会很有用。

【问题讨论】:

  • Apache 创建了一个临时对象,但从好的方面来说,它还支持反射式构建快速原型代码。
  • 正确。谢谢,本。
  • 还可以考虑像AutoValue 这样的值对象来为您生成equals/hashCode/toString 等。
  • 相关:Java 7 包括 Objects.equalsObjects.hash,它们的工作方式与 Guava 类似
  • 尽管具有所有可读性,OP 的作者仍然犯了一个错误,将 field1 比较两次并忘记了 field2(番石榴等于)。通过简单的实现,静态代码分析器会发出警报......

标签: java guava apache-commons


【解决方案1】:

我将这种差异称为“存在”。 Apache Commons 中有 EqualsBuilderHashCodeBuilder,而 Guava 中没有构建器。你从 Guava 得到的只是一个实用类 MoreObjects(从 Objects 重命名,因为现在 JDK 中有这样一个类)。

Guava 方法的优势来自于 builder 的不存在:

  • 不会产生垃圾
  • 更快

JIT 编译器可能会通过Escape Analysis 消除垃圾以及相关的开销。然后,它们的速度与它们完全相同的速度一样快。

我个人认为构建器的可读性略高一些。如果你发现没有更好地使用它们,那么 Guava 肯定是适合你的东西。如您所见,静态方法足以胜任这项任务。

还要注意,还有一个 ComparisonChain,它是一种 Comparable-builder。

【讨论】:

  • Objects.hashCode 将分配给可变参数,当然也可能用于自动装箱。另请注意,ComparisonChain 看起来像一个构建器,但实际上并没有分配任何东西。
  • 我想知道 Hotspot 需要多长时间来优化这个,因为我刚刚重做了我的微基准测试,它仍然是最快的实现 hashCode inline,使用 HashCodeBuilder 并没有明显慢,但使用 Objects.hash 慢了 20 倍(...)。在最坏的情况下,您要散列的所有内容都是整数。
【解决方案2】:

Guava 在后台使用 Arrays.hashCode()。 Varagrs 会造成性能损失,并且有可能进行自动装箱,这会再次对性能造成影响。根据Java的documentation

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2010-11-29
    • 2011-06-29
    • 2011-02-20
    • 2012-02-10
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    相关资源
    最近更新 更多