我刚开始使用google的Guava集合(ComparisonChain和Objects)。在我的pojo中,我覆盖了equals方法,所以我先做了这个:
return ComparisonChain.start()
.compare(this.id, other.id)
.result() == 0;
然而,我意识到我也可以使用它:
return Objects.equal(this.id, other.id);
我没有看到比较链何时更好,因为你可以轻松地添加更多条件:
return Objects.equal(this.name, other.name)
&& Objects.equal(this.number, other.number);
如果您特别需要返回int,我可以看到的唯一好处。它有两个额外的方法调用(开始和结果),并且对于菜鸟来说更复杂。
我错过了 ComparisonChain 的明显好处吗?
(是的,我也用适当的Objects.hashcode()
覆盖哈希码)
答案 0 :(得分:18)
ComparisonChain
允许您通过比较多个属性(例如按多列排序网格)来检查对象是否小于或大于另一个对象。
在实施Comparable
或Comparator
。
Objects.equal
只能检查是否相等。
答案 1 :(得分:11)
ComparisonChain旨在用于帮助对象实现Comparable或Comparator接口。
如果您只是实现Object.equals(),那么您是正确的; Objects.equal就是您所需要的。但是,如果您正在尝试实现Comparable或Comparator,那么使用ComparisonChain比使用其他方法更容易。
考虑:
class Foo implements Comparable<Foo> {
final String field1;
final int field2;
final String field3;
public boolean equals(@Nullable Object o) {
if (o instanceof Foo) {
Foo other = (Foo) o;
return Objects.equal(field1, other.field1)
&& field2 == other.field2
&& Objects.equal(field3, other.field3);
}
return false;
}
public int compareTo(Foo other) {
return ComparisonChain.start()
.compare(field1, other.field1)
.compare(field2, other.field2)
.compare(field3, other.field3)
.result();
}
}
而不是将compareTo实现为
int result = field1.compareTo(other.field2);
if (result == 0) {
result = Ints.compare(field2, other.field2);
}
if (result == 0) {
result = field3.compareTo(other.field3);
}
return result;
...更不用说正确地做到这一点的诡计,这比你猜想的要高。 (我已经看到了比你想象的更多比较混乱的方法。)
答案 2 :(得分:2)
在POJO中覆盖方法的上下文中,我想到了一些与几种标准方法匹配的Guava工具。
Object.equals
使用Objects.equals
按照您提到的方式处理Object.hashCode
由Objects.hashCode
处理,如return Objects.hashCode(id, name);
Comparable.compareTo
由ComparisonChain
处理,如下所示:
public int compareTo(Chimpsky chimpsky) {
return ComparisonChain.start()
.compare(this.getId(), chimpsky.getId())
.compare(this.getName(), chimpsky.getName())
.result();
}
答案 3 :(得分:0)
使用番石榴的ComparisonChain
时要小心,因为它会为每个被比较的元素创建一个实例,因此您将查看N x Log N
比较链的创建,以比较是否要排序,或N
个实例(如果您要迭代并检查是否相等)。
如果可能的话,我会使用最新的Java 8 API或使用允许您执行此操作的Guava的Comparator
API创建静态Ordering
,这是Java 8的示例:
import java.util.Comparator;
import static java.util.Comparator.naturalOrder;
import static java.util.Comparator.nullsLast;
private static final Comparator<DomainObject> COMPARATOR=Comparator
.comparingInt(DomainObject::getId)
.thenComparing(DomainObject::getName,nullsLast(naturalOrder()));
@Override
public int compareTo(@NotNull DomainObject other) {
return COMPARATOR.compare(this,other);
}
以下是如何使用番石榴的Ordering
API:https://github.com/google/guava/wiki/OrderingExplained