Šajā Java Challenger jūs uzzināsiet, kā vienāds ()
un hashcode ()
apvienojiet, lai objektu salīdzināšana būtu efektīva un vienkārša jūsu Java programmās. Vienkārši sakot, šīs metodes darbojas kopā, lai pārbaudītu, vai diviem objektiem ir vienādas vērtības.
Bez vienāds ()
un hashcode ()
mums būtu jāizveido ļoti lieli "ja
"salīdzinājumi, salīdzinot katru objekta lauku. Tas padarītu kodu patiešām mulsinošu un grūti lasāmu. Kopā šīs divas metodes palīdz mums izveidot elastīgāku un saliedētāku kodu.
Iegūstiet Java Challengers avota kodu.
Vienkārša () un hashcode () ignorēšana Java valodā
Metode ir svarīgāka ir paņēmiens, kurā vecāku klases vai saskarnes uzvedība atkal tiek ierakstīta (ignorēta) apakšklasē, lai izmantotu polimorfisma priekšrocības. Katrs Objekts
Java satur vienāds ()
un a hashcode ()
metodi, taču tie ir jāpārskata, lai tie darbotos pareizi.
Lai saprastu, kā darbojas primārais vienāds ()
unhashcode ()
, mēs varam izpētīt to ieviešanu Java pamatklasēs. Zemāk ir vienāds ()
metodi Objekts
klasē. Metode ir pārbaude, vai pašreizējais gadījums ir tāds pats kā iepriekš nodotais Objekts
.
publiskais būla skaitlis ir vienāds (Object obj) {return (this == obj); }
Kad hashcode ()
metode netiek ignorēta, noklusējuma metode Objekts
klase tiks izsaukta. Tas ir vietējā metode, kas nozīmē, ka tas tiks izpildīts citā valodā, piemēram, C, un atgriezīs kodu par objekta atmiņas adresi. (Nav tik svarīgi precīzi zināt, kā darbojas šī metode, ja vien jūs nerakstāt JDK kodu.)
@HotSpotIntrinsicCandidate public native int hashCode ();
Kad vienāds ()
un hashcode ()
metodes netiek ignorētas, tā vietā redzēsit izsauktas iepriekš minētās metodes. Šajā gadījumā metodes neatbilst faktiskajam mērķim vienāds ()
un hashcode ()
, kas ir jāpārbauda, vai diviem vai vairākiem objektiem ir vienādas vērtības.
Parasti, kad jūs ignorējat vienāds ()
jums arī jāatsakās hashcode ()
.
Objektu salīdzināšana ar vienādiem ()
Mēs izmantojam vienāds ()
metode objektu salīdzināšanai Java. Lai noteiktu, vai divi objekti ir vienādi, vienāds ()
salīdzina objektu atribūtu vērtības:
public class EqualsAndHashCodeExample {public static void main (String ... equalsExplanation) {System.out.println (new Simpson ("Homer", 35, 120) .equals (new Simpson ("Homer", 35,120))); System.out.println (jauns Simpsons ("Bart", 10, 120). Ir vienāds (jauns Simpsons ("El Barto", 10, 45))); System.out.println (jauns Simpsons ("Lisa", 54., 60.). Ir vienāds (jauns objekts ())); } statiskā klase Simpsons {privātās virknes nosaukums; privāts int vecums; privāts int svars; public Simpson (Stīgas nosaukums, int vecums, int svars) {this.name = name; tas.vecums = vecums; tas.svars = svars; } @ Pārvarēt publisko būla skaitli vienāds ar (Object o) {if (this == o) {return true; } if (o == null || getClass ()! = o.getClass ()) {return false; } Simpsons simpsons = (Simpsons) o; atgriešanās vecums == simpson.age && weight == simpson.weight && name.equals (simpson.name); }}}
Pirmajā salīdzinājumā vienāds ()
salīdzina pašreizējo objekta gadījumu ar nodoto objektu. Ja abiem objektiem ir vienādas vērtības, vienāds ()
atgriezīsies taisnība
.
Otrajā salīdzinājumā vienāds ()
pārbauda, vai nodotais objekts ir nullevai ja tā ir ierakstīta kā cita klase. Ja tā ir cita klase, tad objekti nav vienādi.
Visbeidzot, vienāds ()
salīdzina objektu laukus. Ja diviem objektiem ir vienādas lauka vērtības, tad objekti ir vienādi.
Analizējot objektu salīdzinājumus
Apskatīsim šo salīdzinājumu rezultātus mūsu galvenais ()
metodi. Pirmkārt, mēs salīdzinām divus Simpsons
objekti:
System.out.println (jauns Simpsons ("Homer", 35, 120). Ir vienāds (jauns Simpsons ("Homer", 35, 120)));
Objekti šeit ir identiski, tāpēc rezultāts būs taisnība
.
Tālāk mēs salīdzinām divus Simpsons
atkal objekti:
System.out.println (jauns Simpsons
("Bart", 10, 45). Ir vienāds (jauns Simpsons
("El Barto", 10, 45)));
Objekti šeit ir gandrīz identiski, bet to nosaukumi ir atšķirīgi: Barts un El Barto. Tāpēc rezultāts būs nepatiesa
.
Visbeidzot, salīdzināsim a Simpsons
objekts un objekta klases instance:
System.out.println (jauns Simpsons
("Lisa", 54, 60) .vienāds (jauns Objekts
()));
Šajā gadījumā rezultāts būs nepatiesa
jo klases veidi ir atšķirīgi.
ir vienāds () pret = =
No pirmā acu uzmetiena ==
operators un vienāds ()
Šķiet, ka šī metode dara to pašu, bet patiesībā viņi darbojas citādi. The ==
operators salīdzina, vai divas objekta atsauces norāda uz vienu un to pašu objektu. Piemēram:
System.out.println (homer == homer2);
Pirmajā salīdzinājumā mēs parādījām divus dažādus Simpsons
gadījumi, izmantojot jauns
operators. Tāpēc mainīgie homers
un Homer2
norādīs uz dažādiem Objekts
atsauces atmiņas kaudzē. Tātad mums būs nepatiesa
kā rezultātā.
System.out.println (homer.quals (homer2));
Otrajā salīdzinājumā mēs ignorējam vienāds ()
metodi. Šajā gadījumā tiks salīdzināti tikai nosaukumi. Jo abu nosaukums Simpsons
objekti ir “Homer” rezultāts būs taisnība
.
Objektu unikāla identificēšana ar hashcode ()
Mēs izmantojam hashcode ()
metode, lai optimizētu veiktspēju, salīdzinot objektus. Izpildahashcode ()
atgriež unikālu ID katram jūsu programmas objektam, kas ievērojami atvieglo visa objekta stāvokļa salīdzināšanu.
Ja objekta jaukšanas kods nav tāds pats kā cita objekta jaukšanas kods, nav pamata to izpildīt vienāds ()
metode: jūs vienkārši zināt, ka abi objekti nav vienādi. No otras puses, ja hashcode ir tas pats, tad jums ir jāizpilda vienāds ()
metodi, lai noteiktu, vai vērtības un lauki ir vienādi.
Šeit ir praktisks piemērs hashcode ()
.
public class HashcodeConcept {public static void main (String ... hashcodeExample) {Simpson homer = new Simpson (1, "Homer"); Simpsona barts = jaunais Simpsons (2, "Homērs"); boolean isHashcodeEquals = homer.hashCode () == bart.hashCode (); if (isHashcodeEquals) {System.out.println ("Arī jāsalīdzina ar metodi equals."); } else {System.out.println ("Nevajadzētu salīdzināt ar metodi equals, jo" + "id ir atšķirīgs, tas nozīmē, ka objekti noteikti nav vienādi."); }} statiskā klase Simpsons {int id; Stīgas nosaukums; publiskais Simpsons (int id, virknes nosaukums) {this.id = id; this.name = nosaukums; } @ Pārvarēt publisko būla skaitli vienāds ar (Object o) if (this == o) return true; if (o == null @ Pārvarēt publisko int hashCode () {atgriešanās ID;}}}
A hashcode ()
kas vienmēr atgriež to pašu vērtību, ir derīga, bet ne pārāk efektīva. Šajā gadījumā salīdzinājums vienmēr atgriezīsies taisnība
, tāpēc vienāds ()
metode vienmēr tiks izpildīta. Šajā gadījumā veiktspējas uzlabojumu nav.
Izmantojot vienādus () un hashcode () ar kolekcijām
The Iestatiet
interfeiss ir atbildīgs par to, lai a Iestatiet
apakšklase. Tālāk ir norādītas dažas klases, kurās tiek ieviests Iestatiet
interfeiss:
- HashSet
- TreeSet
- LinkedHashSet
- CopyOnWriteArraySet
A. Var ievietot tikai unikālus elementus Iestatiet
, tāpēc, ja vēlaties pievienot elementu HashSet
klases (piemēram), vispirms jāizmanto vienāds ()
un hashcode ()
metodes, lai pārbaudītu, vai elements ir unikāls. Ja vienāds ()
un hashcode ()
metodes šajā gadījumā netika ignorētas, jūs riskējat kodā ievietot elementu dublikātus.
Tālāk esošajā kodā mēs izmantojam pievienot
metode jauna elementa pievienošanai a HashSet
objekts. Pirms jaunā elementa pievienošanas HashSet
pārbauda, vai elements jau pastāv attiecīgajā kolekcijā:
if (e.hash == hash && ((k = e.key) == atslēga || (key! = null && key.equals (k)))) break; p = e;
Ja objekts ir tas pats, jaunais elements netiks ievietots.
Hash kolekcijas
Iestatiet
nav vienīgā kolekcija, kuru izmanto vienāds ()
un hashcode ()
. HashMap, Hashtable un LinkedHashMap arī nepieciešamas šīs metodes. Parasti, ja redzat kolekciju, kuras prefikss ir “Hash”, varat būt drošs, ka tai ir nepieciešams ignorēt hashcode ()
un vienāds ()
metodes, lai to funkcijas darbotos pareizi.
Vienādojuma () un hashcode () izmantošanas vadlīnijas
Jums vajadzētu izpildīt tikai vienāds ()
metode objektiem, kuriem ir tāds pats unikālais hashcode ID. Jums vajadzētu nē izpildīt vienāds ()
ja hashcode ID ir atšķirīgs.
1. tabula. Hashcode salīdzinājumi
Ja hashcode () salīdzinājums ... | Tad ... |
---|---|
atgriež patiesu | izpildīt vienāds () |
atgriež false | neizpildi vienāds () |
Šis princips galvenokārt tiek izmantots Iestatiet
vai Hash
kolekcijas veiktspējas apsvērumu dēļ.
Noteikumi objektu salīdzināšanai
Kad hashcode ()
salīdzinājums atgriež nepatiesa
, vienāds ()
metodi jāatgriežas arī nepatiesi. Ja jaukšanas kods ir atšķirīgs, tad objekti noteikti nav vienādi.
2. tabula. Objekta salīdzinājums ar hashcode ()
Kad atgriežas hashcode salīdzinājums ... | The vienāds () metodei jāatgriežas ... |
---|---|
taisnība | patiesība vai meli |
nepatiesa | nepatiesa |
Kad vienāds ()
metode atgriež taisnība
, tas nozīmē, ka objekti ir vienādi visās vērtībās un atribūtos. Šajā gadījumā arī hashcode salīdzinājumam jābūt patiesam.
3. tabula. Objektu salīdzinājums ar vienādiem ()
Kad vienāds () metode atgriež ... | The hashcode () metodei jāatgriežas ... |
---|---|
taisnība | taisnība |
nepatiesa | patiesība vai meli |
Veikt izaicinājumu vienāds ar () un hashcode ()!
Ir pienācis laiks pārbaudīt savas prasmes vienāds ()
un hashcode ()
metodes. Jūsu mērķis šajā izaicinājumā ir noskaidrot abu rezultātu vienāds ()
metožu salīdzinājumi un uzminiet Iestatiet
kolekcija.
Lai sāktu, uzmanīgi izpētiet šo kodu:
public class EqualsHashCodeChallenge {public static void main (String ... doYourBest) {System.out.println (jauns Simpsons ("Bart"). vienāds (jauns Simpsons ("Bart"))); Simpsons overriddenHomer = jauns Simpsons ("Homers") {public int hashCode () {return (43 + 777) + 1; }}; System.out.println (jauns Simpsons ("Homers"). Ir vienāds ar (overriddenHomer)); Set set = new HashSet (Set.of (jauns Simpsons ("Homers"), jauns Simpsons ("Māržs"))); set.add (jauns Simpsons ("Homer")); set.add (overriddenHomer); System.out.println (set.size ()); } statiskā klase Simpsons {Stīgas nosaukums; Simpsons (virknes nosaukums) {this.name = name; } @Orride public Boolean equals (Object obj) {Simpson otherSimpson = (Simpson) obj; atgriezt this.name.equals (otherSimpson.name) && this.hashCode () == otherSimpson.hashCode (); } @Orride public int hashCode () {return (43 + 777); }}}
Atcerieties, vispirms analizējiet kodu, uzminiet rezultātu, un pēc tam palaidiet kodu. Jūsu mērķis ir uzlabot savas prasmes, izmantojot kodu analīzi, un apgūt Java pamatjēdzienus, lai padarītu kodu jaudīgāku. Pirms pārbaudāt pareizo atbildi zemāk, izvēlieties atbildi.
A) true true 4 B) true false 3 C) true false 2 D) false true 3
Kas tikko notika? Izpratne par vienādu () un hashcode ()
Pirmajā vienāds ()
metodes salīdzinājums, rezultāts ir taisnība
jo objekta stāvoklis ir tieši tāds pats un hashcode ()
metode abiem objektiem atgriež to pašu vērtību.
Otrajā vienāds ()
metodes salīdzinājums hashcode ()
metode tiek ignorēta overridenHomer
mainīgais. Abiem vārds ir “Homērs” Simpsons
priekšmetus, bet hashcode ()
metode atgriež citu vērtību overridridHomer
. Šajā gadījumā galīgais rezultāts no vienāds ()
metode būs nepatiesa
jo metode satur salīdzinājumu ar hashcode.
Iespējams, pamanīsit, ka kolekcijas lielums ir noteikts trīs Simpsons
objektiem. Pārbaudīsim to detalizēti.
Pirmais objekts komplektā tiks ievietots parasti:
jaunais Simpsons ("Homer");
Arī nākamais objekts tiks ievietots normāli, jo tam ir atšķirīga vērtība nekā iepriekšējam objektam:
jaunais Simpsons ("Marge");
Visbeidzot sekojošais Simpsons
objektam ir tāda pati vērtība kā pirmajam objektam. Šajā gadījumā objekts netiks ievietots:
set.add (jauns Simpsons ("Homer"));
Kā mēs zinām, overridenHomer
objekts izmanto citu hashcode vērtību nekā parasti Simpsons (“Homers”)
acumirklība. Šī iemesla dēļ šis elements tiks ievietots kolekcijā:
overriddenHomer;
Atbildes atslēga
Atbilde šim Java izaicinātājam ir B. Rezultāts būtu:
patiesa nepatiesa 3
Video izaicinājums! Atkļūdošana ir vienāda () un hashcode ()
Atkļūdošana ir viens no vienkāršākajiem veidiem, kā pilnībā absorbēt programmēšanas koncepcijas, vienlaikus uzlabojot arī kodu. Šajā video jūs varat sekot līdzi, kamēr es atkļūdoju un izskaidroju Java vienāds ()
un hashcode ()
izaicinājums.