Wpis z mikrobloga

Mirki, proszę Was pomóżcie mi z metodami equals i hashcode bo czytam i trochę mi się to miesza. Napisałem w podpunktach jak to rozumiem, jeśli coś jest źle mówić. :)

1. Podstawowa implementacja metody equals w klasie Object sprawdza czy referencje są takie same.
Czyli object1.equals(object2) zwroci true tylko jesli obie zmienne będą wskazywały na ten sam adres w pamięci.
Czyli np. Gdy zrobimy Klasa object1 = new Klasa(); Klasa object2 = object1;
Jak sprawdza czy są równe? Przez operator porównania return (this == obj);
Wyjątkiem są tutaj klasa String i klasy opakowujące jak Integer, Double, metoda equals w tych klasach jest nadpisana i sprawdza zawartosc.
PYTANIE: dlaczego w takim razie operator porównania nie zwraca true, skoro gdzieś czytałem, ze jeśli 2 stringi są równe pod względem zawartości to referencje wskazują na to samo miejsce w pamięci?
2. Jeśli chcemy sprawdzić czy dwa obiekty są równe pod względem zawartości, musimy nadpisać metodę equals() i napisać tam pod względem jakich pól chcemy obiekty porównywać.
3. Jeśli nadpisujemy equals musimy nadpisac metodę hashcode(zgodnie z kontraktem). Jeśli nie nadpiszemy to nie będziemy mogli używać poprawnie zbiorów, hashmapy itp.
PYTANIE: co jeśli nie korzystamy z obiektów jako np. kluczy w zbiorze? Można złamać kontrakt? Metoda equals będzie działała bez napisania hashcode?
4. PYTANIE: W drugą stronę, co jeśli nadpiszemy hashCode a nie nadpiszemy equals. Jak zachowa się hashmapa?
5. Operator porównania „==” używamy do porównania typów podstawowych aby sprawdzić czy są równe, a w przypadku obiektów sprawdzamy czy są równe referencje. (zresztą tak wygląda metoda equals z klasy Object)

#naukaprogramowania #java
  • 22
@nick230: ad 1. Stringi mogą wskazywać na to samo miejsce ale w wiekszości przypadków nie będą. Nie mam jak przetestowac ale:

Maja ta sama referencje, == zadziala
String c = "lol"
String b = c

Nie maja tej samej referencji, tylko equals dziala
String c = "lol"
String b = "lol"

Ad2 i reszta : tak, ale przydaloby sie zmienic metode hashcode, ponieważ
Wiele bibliotek, api zanim wywola metode equals najpierw
#jprdl to jest wlasnie klasyczny przyklad jak ucza ksiazki a sprawa jest banalna

hashcode jest intem, ktory zbiera wiedze o obiekcie do kupy i mowi ci o nim wszystko, tak jak go widzisz. Jak porownujesz dwoch Jankow Kowalskich to bedzie true.

Equals bierze pod uwage pozycje obiektu w pamieci, wiec jak porownasz (Usera) Janka Kowalskiego i nowego (Usera) Janka Kowalskiego to sie nie beda zgadzac.
@variableisnotinitialized: Na potrzeby wytlumaczenia banalu nie trzeba sie bawic w przypadek gdzie dwa obiekty beda mialy ten sam hashcode, a jak trzeba to sa od tego stackoverflowy i inne javaranche a nie strona ze smiesznymi imigrantami.

A co do ogarniania to przyznam ci racje jak mi pokazesz nowszy certyfikat Javy od Oracla niz moj. ; )
@nick230:
Ad. 1 W javie ze względu na oszczędności pamięci zaimplementowane zostały dla niektórych klas (koniecznie immutable) tzw. poole. I tak String ma String pool w którym przechowywane są wszystkie Stringi. Jeżeli będziemy porównywać przy pomocy == stringi które znajdują się w tym poolu to dostaniemy wartość true. Problem polega na tym, że nie możemy być tego pewni. Programista może wymusić utworzenie Stringa poza poolem przy pomocy konstruktora new String(""). Można
@Hatespinner: jesteś absolutnie najgorszym nauczycielem którego posty kiedykolwiek czytałem, jeżeli faktycznie masz certyfikat od Oracle'a to źle o nim świadczy.

hashcode jest intem, ktory zbiera wiedze o obiekcie do kupy i mowi ci o nim wszystko, tak jak go widzisz. Jak porownujesz dwoch Jankow Kowalskich to bedzie true.


to zdanie to jakiś bełkot, co to znaczy że "int zbiera wiedze o obiekcie do kupy", co to znaczy że "będzie true"?

Equals
@nick230: Odpowiedź @Legol jest pełna także możesz na niej bazować. Co do samego kontraktu przeczytaj sobie to co wrzuciła @NiebieskaSowa żeby ugruntować wiedzę ;) @Hatespinner i @variableisnotinitialized to typowe krzykacze - juniorzy przerzucający się certyfikatami i wytykający sobie błędy słowne.
Na takich nie zwracaj uwagi ( ͡° ͜ʖ ͡°)

Na przyszłość dla reszty czytających - to jest dobrze sformułowane pytanie, na które można bez problemu udzielać odpowiedzi.
@Legol: Świetna odpowiedź, zwłaszcza ta część o poolach. Wielu o tym zapomina :) i przez to są skołowani kiedy teoria się rozmija z tym co widzą w kodzie.
@nick230: Bardzo dobrze wiedzieć jak to wszystko dokłądnie działa, ale w praktyce zazwyczaj się albo generuje tego typu metody (większość IDE ma taką możliwość), albo (lepiej) używa się narzędzi typu Lombok, które automatycznie dołączają wygenerowane metody equals+hashcode podczas kompilacji.
Czemu Lombok jest
albo (lepiej) używa się narzędzi typu Lombok

@Mirkostatbot: jak w IDE (eclipse/idea) wygląda wsparcie dla Lomboka i refactoringu? Jeśli mamy jakieś pole klasy i używamy lombokowych adnotacji, a później zauważamy, że w nazwie zrobiliśmy literówkę lub chcemy całkiem zmienić nazwę tego pola to IDE automatycznie poprawi wszystkie wystąpienia getterów w kodzie, czy trzeba to jakoś obchodzić?

Druga rzecz, jest jakieś obejście wstawiania breakpointów na poziomie settera/gettera?

Trzecie chyba najważniejsze jak to