В чем преимущество использования ComparisonChain над объектами.equal () & & объекты.равный () ... с гуавой

Я только начал использовать коллекцию гуавы google (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) и является более сложным для noob.

есть ли очевидные преимущества ComparisonChain мне не хватает ?

(Да, я также переопределяю хэш-код с помощью соответствующего Objects.hashcode())

3 ответов


ComparisonChain позволяет проверить, является ли объект меньше или больше, чем другой объект, сравнивая несколько свойств (например, сортировка сетки по нескольким столбцам).
Он должен использоваться при реализации Comparable или Comparator.

Objects.equal можно проверить только равенство.


ComparisonChain предназначен для использования в оказании помощи объектам в реализации интерфейсов Comparable или Comparator.

Если вы просто реализуете объект.equals (), тогда вы правы; объекты.равны все, что вам нужно. Но если вы пытаетесь реализовать 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, чем вы можете себе представить.)


в контексте переопределения методов в ваших POJOs я думаю о нескольких инструментах 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();
    }