使用 ComparisonChain 相对于 Objects.equal() && 有什么好处? Objects.equal() ...与番石榴

发布于 2024-11-28 01:31:39 字数 871 浏览 1 评论 0原文

我刚刚开始使用谷歌的番石榴集合(ComparisonChain对象)。在我的 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 。它有两个额外的方法调用(start 和 result),对于菜鸟来说更复杂。

我缺少的ComparisonChain 是否有明显的好处?

(是的,我还使用适当的 Objects.hashcode() 覆盖 hashcode)

I have just started using google's Guava collection (ComparisonChain and Objects). In my pojo I am overiding the equals method, so I did this first:

return ComparisonChain.start()
         .compare(this.id, other.id)
         .result() == 0;

However, I then realized that I could also use this :

return Objects.equal(this.id, other.id);

And I fail to see when comparison chain would be better as you can easily add further conditions like so:

return Objects.equal(this.name, other.name) 
       && Objects.equal(this.number, other.number);

The only benefit I can see if you specifically need an int returned. It has two extra method calls (start and result) and is more complex to a noob.

Are there obvious benefits of ComparisonChain I missing ?

(Yes, I am also overriding hashcode with appropriate Objects.hashcode())

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

墟烟 2024-12-05 01:31:39

ComparisonChain 允许您通过比较多个属性(例如按多列对网格进行排序)来检查一个对象是否小于或大于另一个对象。
它应该在实现ComparableComparator时使用。

Objects.equal 只能检查是否相等。

ComparisonChain allow you to check whether an object is less-than or greater-than another object by comparing multiple properties (like sorting a grid by multiple columns).
It should be used when implementing Comparable or Comparator.

Objects.equal can only check for equality.

沧笙踏歌 2024-12-05 01:31:39

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;

...更不用说正确执行该操作的技巧了,这比您想象的要高。 (我见过比你想象的更多搞乱compareTo的方法。)

ComparisonChain is meant to be used in helping objects implement the Comparable or Comparator interfaces.

If you're just implementing Object.equals(), then you're correct; Objects.equal is all you need. But if you're trying to implement Comparable or Comparator -- correctly -- that is much easier with ComparisonChain than otherwise.

Consider:

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();
   }
 }

as opposed to implementing compareTo as

 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;

...let alone the trickiness of doing that correctly, which is higher than you'd guess. (I have seen more ways to mess up compareTo than you can imagine.)

岛徒 2024-12-05 01:31:39

使用 Guava 的 ComparisonChain 时要小心,因为它会为每个比较的元素创建一个实例,因此您将看到创建的 N x Log N 比较链只是为了如果您正在排序,则比较;如果您正在迭代并检查相等性,则比较 N 个实例。

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);
}

如果可能的话,我会使用最新的 Java 8 API 或 Guava 的 Ordering API 创建一个静态 Comparator ,它允许您执行此操作,这里是 如何使用 Guava 的 Ordering API:https://github.com/google/guava/wiki/OrderingExplained

I would be careful when using Guava's ComparisonChain because it creates an instance of it per element been compared so you would be looking at a creation of N x Log N comparison chains just to compare if you are sorting, or N instances if you are iterating and checking for equality.

I would instead create a static Comparator using the newest Java 8 API if possible or Guava's Ordering API which allows you to do that, here is an example with 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);
}

Here is how to use the Guava's Ordering API: https://github.com/google/guava/wiki/OrderingExplained

金兰素衣 2024-12-05 01:31:39

在 POJO 中重写方法的上下文中,我想到了一些 Guava 的工具与一些标准方法相匹配。

  • Object.equals 使用 Objects.equals 进行处理,大致与您提到的
  • Object.hashCode 使用 Objects.hashCode like return Objects.hashCode(id, name);
  • Comparable.compareTo 使用 ComparisonChain 处理,如下所示:

    public intcompareTo(Chimpsky chimpsky) {
        返回ComparisonChain.start()
            .compare(this.getId(), chimpsky.getId())
            .compare(this.getName(), chimpsky.getName())
            。结果();
    }
    

In the context of overriding methods in your POJOs, I think of a few of Guava's tools matching with a few standard methods.

  • Object.equals is handled using Objects.equals in roughly the manner you mentioned
  • Object.hashCode is handled with Objects.hashCode like return Objects.hashCode(id, name);
  • Comparable.compareTo is handled with ComparisonChain as below:

    public int compareTo(Chimpsky chimpsky) {
        return ComparisonChain.start()
            .compare(this.getId(), chimpsky.getId())
            .compare(this.getName(), chimpsky.getName())
            .result();
    }
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文