Próbuję przesłonić metodę równości w Javie. Mam klasę, People
która w zasadzie ma 2 pola danych name
i age
. Teraz chcę przesłonić equals
metodę, aby móc sprawdzić między 2 obiektami People.
Mój kod jest następujący
public boolean equals(People other){
boolean result;
if((other == null) || (getClass() != other.getClass())){
result = false;
} // end if
else{
People otherPeople = (People)other;
result = name.equals(other.name) && age.equals(other.age);
} // end else
return result;
} // end equals
Ale kiedy piszę, age.equals(other.age)
to daje mi błąd, ponieważ metoda equals może tylko porównać String, a wiek jest Integer.
Rozwiązanie
Użyłem ==
operatora zgodnie z sugestią i mój problem został rozwiązany.
java
overriding
equals
bóbr
źródło
źródło
Odpowiedzi:
Wynik:
źródło
hash = 53 * hash
dlaczego używasz takiego?getClass()
spowoduje problemy, jeśli klasa zostanie podklasy i zostanie porównana z obiektem nadklasy.hashCode()
instanceof
operatora lubisAssignableFrom
. Będzie to wymagało dokładnego dopasowania typu, a nie dopasowania podtypu. - Wymaganie symetryczne.String
Możesz także porównać lub inne typy obiektów, których możesz użyćObjects.equals(this.name,other.name)
.Wprowadzenie nowej sygnatury metody, która zmienia typy parametrów, nazywa się przeciążeniem :
Tutaj
People
jest inaczej niżObject
.Gdy sygnatura metody pozostaje identyczna z sygnaturą jej nadklasy, nazywa się ją nadpisywaniem, a
@Override
adnotacja pomaga rozróżnić te dwa elementy w czasie kompilacji:Nie widząc rzeczywistej deklaracji
age
, trudno powiedzieć, dlaczego pojawia się błąd.źródło
Nie jestem pewien szczegółów, ponieważ nie opublikowałeś całego kodu, ale:
hashCode()
takżeequals
metoda powinna miećObject
, a niePeople
jako jego typu argumentów. W tej chwili przeciążasz, a nie nadpisujesz, metodę equals, która prawdopodobnie nie jest tym, czego chcesz, zwłaszcza biorąc pod uwagę, że później sprawdzisz jej typ.instanceof
aby sprawdzić, czy jest to obiekt People, npif (!(other instanceof People)) { result = false;}
equals
jest używany dla wszystkich obiektów, ale nie prymitywów. Myślę, że masz na myśli wiek jestint
(prymitywny), w takim przypadku po prostu użyj==
. Zauważ, że liczba całkowita (przez duże „I”) to obiekt, który należy porównać z równymi.Zobacz Jakie problemy należy wziąć pod uwagę podczas zastępowania równości i hashCode w Javie? po więcej szczegółów.
źródło
źródło
Punkt 10: Przestrzegaj umowy generalnej, gdy ma pierwszeństwo
Każda instancja klasy jest z natury wyjątkowa . Dotyczy to klas, takich jak Thread, które reprezentują aktywne jednostki, a nie wartości. Implementacja equals dostarczona przez Object ma dokładnie właściwe zachowanie dla tych klas.
Klasa nie musi przeprowadzać testu „logicznej równości”. Na przykład java.util.regex.Pattern mógł przesłonić równa się, aby sprawdzić, czy dwa wystąpienia Patternu reprezentują dokładnie to samo wyrażenie regularne, ale projektanci nie sądzili, że klienci będą potrzebować lub chcieć tej funkcji. W takich okolicznościach implementacja equals odziedziczona po Object jest idealna.
Nadklasa już zastąpiła równa się i zachowanie nadklasy jest odpowiednie dla tej klasy. Na przykład większość implementacji Set dziedziczy implementacje equals z AbstractSet, implementacje List z AbstractList i implementacje Map z AbstractMap.
Klasa jest prywatna lub prywatna dla pakietu i masz pewność, że jej metoda equals nigdy nie zostanie wywołana. Jeśli jesteś wyjątkowo niechętny ryzyku, możesz zastąpić metodę equals, aby upewnić się, że nie zostanie wywołana przypadkowo:
equals
Sposób realizuje stosunek równoważności. Posiada następujące właściwości:Odruchowy: Dla każdej wartości referencyjnej niż null
x
,x.equals(x)
należy wrócić prawdziwe.Symetryczne: dla wszelkich wartości odniesienia niezerowych
x
iy
,x.equals(y)
musi zwracać wartość true wtedy i tylko wtedy, gdy y.equals (x) zwraca wartość true.Przechodni: Dla każdej wartości odniesienia nie zerowych
x
,y
,z
jeżelix.equals(y)
wracatrue
iy.equals(z)
zwrotówtrue
, tox.equals(z)
należy zwrócićtrue
.Spójne: w przypadku wszelkich niezerowych wartości odniesienia
x
iy
wielokrotne wywołaniax.equals(y)
muszą konsekwentnie zwracaćtrue
lub konsekwentnie zwracaćfalse
, pod warunkiem, że żadne informacje używane w porównaniach równości nie są modyfikowane.Dla każdej wartości referencyjnej niż null
x
,x.equals(null)
musi powrócićfalse
.Oto przepis na metodę równa się wysokiej jakości:
Użyj
==
operatora, aby sprawdzić, czy argument jest odniesieniem do tego obiektu. Jeśli tak, zwróć wartość true. To tylko optymalizacja wydajności, ale warto to zrobić, jeśli porównanie jest potencjalnie drogie.Użyj
instanceof
operatora, aby sprawdzić, czy argument ma poprawny typ. Jeśli nie, zwróć false. Zwykle prawidłowym typem jest klasa, w której występuje metoda. Czasami jest to jakiś interfejs zaimplementowany przez tę klasę. Użyj interfejsu, jeśli klasa implementuje interfejs, który udoskonala kontrakt equals, aby umożliwić porównania między klasami, które implementują interfejs. Tę właściwość mają interfejsy kolekcji, takie jak Set, List, Map i Map.Entry.Prześlij argument na właściwy typ. Ponieważ rzutowanie było poprzedzone testem instancji, gwarantujemy sukces.
Dla każdego „znaczącego” pola w klasie sprawdź, czy to pole argumentu pasuje do odpowiedniego pola tego obiektu. Jeśli wszystkie te testy zakończą się powodzeniem, zwraca true; w przeciwnym razie zwraca false. Jeśli typ w kroku 2 to interfejs, musisz uzyskać dostęp do pól argumentu za pomocą metod interfejsu; jeśli typ jest klasą, możesz mieć bezpośredni dostęp do pól, w zależności od ich dostępności.
W przypadku pól pierwotnych, których typem nie jest
float
lubdouble
,==
do porównań użyj operatora; w przypadku pól odwołań do obiektów wywołajequals
metodę rekurencyjnie; w przypadkufloat
pól użyjFloat.compare(float, float)
metody statycznej ; a nadouble
polach użyjDouble.compare(double, double)
. Szczególne traktowanie pływaka i podwójnych obszarach jest konieczne ze względu na istnienieFloat.NaN
,-0.0f
a analogicznymi wartościami podwójnych; Chociaż można porównaćfloat
idouble
pola za pomocą metod statycznychFloat.equals
iDouble.equals
, wiązałoby się to z automatycznym blokowaniem każdego porównania, co miałoby słabą wydajność. W przypadkuarray
pól zastosuj te wytyczne do każdego elementu. Jeśli każdy element w polu tablicy jest znaczący, użyj jednej zArrays.equals
metod.Niektóre pola odwołań do obiektów mogą zgodnie z prawem zawierać
null
. Aby uniknąć możliwościNullPointerException
, należy sprawdzić takie pola pod kątem równości przy użyciu metody statycznejObjects.equals(Object, Object)
.źródło
hashCode()
. Również pamiętać, że od Java7 piśmieequals()
ihashCode()
metod stało się znacznie łatwiejsze przy użyciuObjects.equals()
,Arrays.equals()
aObjects.hashCode()
,Arrays.hashCode()
.if (getClass() != obj.getClass()) ...
zamiast używania operatora instanceof. Będzie to wymagało dokładnego dopasowania typu, a nie dopasowania podtypu. - Wymaganie symetryczne.Ponieważ zgaduję,
age
jest typuint
:źródło
NullPointerException
jeśliname
jestnull
.name
nigdy nie ma przypisanejnull
wartości ...Porównując obiekty w Javie, wykonujesz kontrolę semantyczną , porównując typ i określając stan obiektów z:
null
Zasady:
a.equals(b) == b.equals(a)
equals()
zawsze ustępujetrue
lubfalse
, ale nigdyNullpointerException
,ClassCastException
ani żaden inny przedmiot do rzucaniaPorównanie:
instanceof
do porównywania typów (które działa tylko tak długo, jak nie ma podklas i narusza regułę symetrii, kiedyA extends B -> a instanceof b != b instanceof a)
.Dla Twojej
Person
klasy:Ogólna klasa użytkowa wielokrotnego użytku:
Dla swojej
Person
klasy, używając tej klasy użytkowej:źródło
jeśli wiek jest równy int, powinieneś użyć ==, jeśli jest to obiekt Integer, możesz użyć equals (). Musisz również zaimplementować metodę hashcode, jeśli nadpisujesz równa się. Szczegóły umowy są dostępne w javadoc of Object, a także na różnych stronach internetowych.
źródło
Oto rozwiązanie, z którego ostatnio korzystałem:
źródło