2011-08-04 10 views
9

Właśnie zacząłem używać kolekcji Guava Google (ComparisonChain i Objects). W moim POJO ja overiding metody equals, więc zrobiłem ten pierwszy:Co to jest korzyść używania ComparisonChain przez Objects.equal() i& Objects.equal() ... z Guava

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

Jednak ja wtedy zrozumiałem, że mogę również użyć tego:

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

I nie widzę, gdy łańcuch porównania byłoby lepiej, ponieważ możesz łatwo dodać dodatkowe warunki, takie jak:

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

Jedyna korzyść, którą mogę zobaczyć, jeśli specjalnie potrzebujesz zwrotu int. Ma dwa dodatkowe wywołania metod (start i result) i jest bardziej skomplikowany dla nooba.

Czy istnieją oczywiste korzyści z ComparisonChain Brakuje mi?

(tak, ja też nadrzędnymi hashcode z odpowiednim Objects.hashcode())

+7

Nigdy nie ma powodu, aby pisać "?true: false' w Javie. – SLaks

+0

o tak, edytowane – NimChimpsky

Odpowiedz

18

ComparisonChain pozwalają sprawdzić, czy obiekt jest mniejszy niż lub większa niż innego obiektu porównując wiele właściwości (jak sortowanie siatkę według wielu kolumn).
Powinny być używane podczas wdrażania Comparable lub Comparator.

Może sprawdzać tylko pod kątem równości.

1

W kontekście nadpisywania metod w twoich POJO, myślę o kilku narzędziach Guavy pasujących do kilku standardowych metod.

  • Object.equals jest obsługiwane za pomocą Objects.equals w przybliżeniu sposób pan wspomniał
  • Object.hashCode jest obsługiwany z Objects.hashCode jak return Objects.hashCode(id, name);
  • Comparable.compareTo jest obsługiwane z ComparisonChain jak poniżej:

    public int compareTo(Chimpsky chimpsky) { 
        return ComparisonChain.start() 
         .compare(this.getId(), chimpsky.getId()) 
         .compare(this.getName(), chimpsky.getName()) 
         .result(); 
    } 
    
9

ComparisonChain jest podły t do wykorzystania w pomaganiu obiektom w implementacji interfejsów Comparable lub Comparator.

Jeśli dopiero wdrażasz Object.equals(), to masz rację; Objects.equal to wszystko, czego potrzebujesz. Ale jeśli próbujesz zaimplementować Comparable lub Comparator - poprawnie - to jest znacznie łatwiejsze w porównaniuChain niż inaczej.

Rozważmy:

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

w przeciwieństwie do realizacji compareTo jak

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; 

... nie mówiąc już o trickiness prowadzenia że prawidłowo, która jest wyższa niż można by odgadnąć. (Widziałem więcej sposobów na zepsucie porównań niż można sobie wyobrazić.)

+0

Co, jeśli inny jest pusty? – jon077

+1

Nie możesz mieć 'Porównywalnego' akceptującego 'null', ale jeśli używasz' Komparatora', to zapisanie go jako 'Zamawiania' pozwala ci na' Ordering.nullsFirst() 'lub' Ordering.nullsLast () ', aby określić, w jaki sposób należy uporządkować wartości puste. –

Powiązane problemy