Programmēšana

Java objektu salīdzināšana ar vienādiem () un hashcode ()

Š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 izpildīt vienāds () ja hashcode ID ir atšķirīgs.

1. tabula. Hashcode salīdzinājumi

Ja hashcode () salīdzinājums ...Tad ...
atgriež patiesuizpildīt vienāds ()
atgriež falseneizpildi 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ībapatiesība vai meli
nepatiesanepatiesa

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ībataisnība
nepatiesapatiesī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.

$config[zx-auto] not found$config[zx-overlay] not found