2012-08-01 6 views
5

Czy istnieje mechanizm Equalatora, taki jak Komparator, więc mogę mieć różne wartości dla list współdziałających?Mechanizm dla różnych równań (fizyczne równe i logiczne równe) na obiektach w kolekcji

EDIT: Moim celem jest, aby odróżnić bieżących list1.equals (lista2), który sprawdza jeśli jego kopia lub płytkie również głęboka kopia ze wszystkich obiektów a.equals (b) i list1.identical (lista2), który sprawdza, czy jest to po prostu płytka kopia z niezmodyfikowanym wykazem. Wszystkie te listy pochodzą z tego samego modelu. Niektóre z nich są kopiami samych siebie, więc posiadają wskaźnik do tych samych obiektów, a inne są kopiami głębokimi, więc hierarchia jest całkowicie powielana, ponieważ mają one aktualizacje w treści, a nie tylko w strukturze.

Często znajduję się na liście list1.equals (list2), ale potrzebuję mechanizmu informującego, czy oba są kopiami TOTAL (te same obiekty w tej samej kolejności dla kolekcji), czy czasem, jeśli są to kopie LOGICZNE (przez moją własną zaimplementowaną logikę jest równa), więc lista wywoła równe wartości, a obiekty powinny zaimplementować coś więcej niż a == b.

Moim problemem jest brak połączenia Equalator, a jeśli zastąpić obiektów wynosi stracę możliwość porównywania przez całkowite równe (a == b)

Dla przykładu, to byłoby miło;

Collections.equal(l1,l2,new Equalator(){ 
    @Override public boolean equals(Obj1,Obj2){ 
      //Default lists comparison plus commparison of objects based on 
      return (obj1.propertyX() == obj2.propertyX()); 
    } 
}); 

i jeszcze mógłbym zrobić list1.equals (lista2), więc używać domyślnych equals (obj1 == obj2) i byłoby to prawdą, jeśli tylko zawarte obiekty są dokładnie takie same.

Pierwsza operacja jest przydatna do sprawdzenia, czy lista (która może być zaktualizowaną listą z całkowicie odtworzonymi obiektami z modelu) nadal jest równa starej liście.

Druga operacja jest przydatna do sprawdzenia, czy lista (która była płytką kopią starej bieżącej wersji modelu danych), nie zawiera żadnej transcendentnej zmiany z przeniesienia jej wewnątrz kodu, gdy była to udpdated wersja.

EDYCJA: Bardzo dobrym przykładem może być lista punktów (x, y). Powinniśmy wiedzieć, czy obie listy są równe, ponieważ są dokładnie tym samym zbiorem punktów lub równe, ponieważ punkty, które zawierają, są równe w logiczny sposób. Gdybyśmy mogli zaimplementować zarówno phyEqual, jak i logEqual do obiektu, i mieć obie metody w dowolnym obiekcie, tak więc list.phyEqual (list2) lub list1.logEqual (list2)

+0

Masz dużo kontekstu, ale jakie jest twoje aktualne * pytanie * tutaj? –

+0

Pierwsza linia. Następnie definiuję swój problem. Przepraszam, zacząłem od 'isn't there' zamiast 'is there' i myślę, że to dlatego jego myląca lista co najmniej – Whimusical

Odpowiedz

2

Twoje pytanie nie jest zbyt jasne, przynajmniej dla mnie . Jeśli to nie odpowiada poprawnie, czy mógłbyś coś powiedzieć na nowo?

W danym typie kolekcji kolekcji, najbardziej równe implementacje robią już to, o czym wspominasz. Na przykład:

public boolean equals(Object o) { 
     if (o == this) 
      return true; 

W tym przypadku coś takiego może mieć sens.
można łatwo zastąpić to:

@Override 
    public boolean equals(Object o) { 
     if (o.getPrimaryKey() == this.getPrimaryKey()) 
      return true; 
     return super().equals(o); 

[test null powinny zostać dodane] Jeśli tworzysz standardowe kolekcje, można nawet anonimowo przesłonić metodę equals podczas budowy.

Jeśli nie zrobi się tego, czego chcesz, możesz samodzielnie powiększyć kolekcje i zastąpić każdą z metod, które wykonują w podobny sposób.

Czy to pomaga?

+0

ma taką samą wartość, która wygląda tak, że obie listy mają ten sam rozmiar, te same elementy i tę samą kolejność. Problem polega na tym, że używa równa się do powiedzenia, czy oba obiekty są takie same, więc oznacza to, że bez interfejsu równika, muszę zmienić całą strukturę, aby mieć dodatkowy łańcuch równości. Mogę zaimplementować równe w moich obiektach jako logiczne lub fizyczne równe, ale potem nie mogę przejść do innego typu. – Whimusical

+0

Istnieje bardzo niewiele przypadków w świecie rzeczywistym, w których istnieje więcej niż jedna definicja równości, która jest faktycznie użyta dla każdego. –

+0

Lista. list.equals (list2), jeśli oba mają ten sam rozmiar, elementy i kolejność (biorąc pod uwagę elementy są równe, jeśli spełniają a.equals (b)). Ale list.equals2 (list2) może oznaczać zarówno ten sam rozmiar, elementy i porządek (biorąc pod uwagę 2 obj są równe, jeśli a == b). Oczywiście, zakładając, że nie możemy zagwarantować, że a.equals (b) nie jest nadpisany, to nie idzie dalej niż a == b – Whimusical

2

Późne odpowiedź, ale może to być przydatne dla kogoś ...

Guava Equivalence klasa jest taka sama dla równoważności jako komparatora do porównania. Będziesz musiał napisać własną metodę porównywania list (nie ma w niej wsparcia w Guava), ale możesz nazwać tę metodę różnymi definicjami równoważności.

Albo można toczyć swój własny interfejs:

interface Equalator<T> { 
    boolean equals(T o1, T o2); 
} 

Znowu trzeba napisać metodę swojego (trywialne)

boolean <T> listEquals(List<T> list1, List<T> list2, Equalator<T> equalator) { 
    ... 
} 

... ale potem można używać go z różnymi implementacjami ListEqualator .

Powiązane problemy