Προγραμματισμός

Σύγκριση αντικειμένων Java με ίσο () και hashcode ()

Σε αυτό Java Challenger θα μάθετε πώς ισούται με () και κωδικός κατακερματισμού () συνδυάστε για να κάνετε τις συγκρίσεις αντικειμένων αποτελεσματικές και εύκολες στα προγράμματα Java. Με απλά λόγια, αυτές οι μέθοδοι συνεργάζονται για να επαληθεύσουν εάν δύο αντικείμενα έχουν τις ίδιες τιμές.

Χωρίς ισούται με () και κωδικός κατακερματισμού () θα έπρεπε να δημιουργήσουμε πολύ μεγάλα "αν"συγκρίσεις, σύγκριση κάθε πεδίου από ένα αντικείμενο. Αυτό θα έκανε τον κώδικα πραγματικά σύγχυση και δύσκολο να διαβαστεί. Μαζί, αυτές οι δύο μέθοδοι μας βοηθούν να δημιουργήσουμε έναν πιο ευέλικτο και συνεκτικό κώδικα.

Αποκτήστε τον πηγαίο κώδικα Java Challengers.

Η παράκαμψη ισούται με () και hashcode () στην Java

Παράκαμψη μεθόδου είναι μια τεχνική όπου η συμπεριφορά της γονικής τάξης ή της διεπαφής γράφεται ξανά (αντικαθίσταται) στην υποκατηγορία προκειμένου να επωφεληθεί από τον Πολυμορφισμό. Κάθε Αντικείμενο στην Java περιλαμβάνει ένα ισούται με () και ένα κωδικός κατακερματισμού () μέθοδος, αλλά πρέπει να παρακαμφθούν για να λειτουργήσουν σωστά.

Για να καταλάβετε πώς λειτουργεί η παράκαμψη ισούται με () καικωδικός κατακερματισμού (), μπορούμε να μελετήσουμε την εφαρμογή τους στις βασικές τάξεις Java. Παρακάτω είναι το ισούται με () μέθοδος στο Αντικείμενο τάξη. Η μέθοδος ελέγχει εάν η τρέχουσα παρουσία είναι ίδια με την προηγούμενη Αντικείμενο.

 public boolean ισούται με (Object obj) {return (this == obj); } 

Οταν ο κωδικός κατακερματισμού () η μέθοδος δεν παρακάμπτεται, η προεπιλεγμένη μέθοδος στο Αντικείμενο θα κληθεί η τάξη. Αυτό είναι ένα εγγενής μέθοδος, που σημαίνει ότι θα εκτελεστεί σε άλλη γλώσσα όπως το C και θα επιστρέψει κάποιο κωδικό σχετικά με τη διεύθυνση μνήμης του αντικειμένου. (Δεν είναι τόσο σημαντικό να γνωρίζετε ακριβώς πώς λειτουργεί αυτή η μέθοδος εκτός εάν γράφετε κώδικα JDK.)

 @HotSpotIntrinsicCandidate δημόσιος εγγενής int hashCode (); 

Οταν ο ισούται με () και κωδικός κατακερματισμού () οι μέθοδοι δεν παρακάμπτονται, θα δείτε αντίθετα τις παραπάνω μεθόδους. Σε αυτήν την περίπτωση, οι μέθοδοι δεν πληρούν τον πραγματικό σκοπό του ισούται με () και κωδικός κατακερματισμού (), δηλαδή να ελέγξετε αν δύο ή περισσότερα αντικείμενα έχουν τις ίδιες τιμές.

Κατά κανόνα, όταν παρακάμπτετε ισούται με () πρέπει επίσης να παρακάμψετε κωδικός κατακερματισμού ().

Σύγκριση αντικειμένων με ίσο ()

Χρησιμοποιούμε το ισούται με () μέθοδος σύγκρισης αντικειμένων σε Java. Προκειμένου να προσδιοριστεί εάν δύο αντικείμενα είναι ίδια, ισούται με () συγκρίνει τις τιμές των χαρακτηριστικών των αντικειμένων:

 δημόσια τάξη EqualsAndHashCodeExample {public static void main (String ... equalsExplanation) {System.out.println (new Simpson ("Homer", 35, 120). equals (new Simpson ("Homer", 35,120))); System.out.println (νέο Simpson ("Bart", 10, 120). Equals (νέο Simpson ("El Barto", 10, 45))); System.out.println (νέο Simpson ("Lisa", 54, 60). Equals (νέο αντικείμενο ())); } στατική τάξη Simpson {όνομα συμβολοσειράς; ιδιωτική ηλικία ιδιωτικό βάρος int? δημόσιο Simpson (όνομα συμβολοσειράς, int age, int weight) {this.name = name; this.age = ηλικία; this.weight = βάρος; } @Override public boolean ισούται με (Object o) {if (this == o) {return true; } εάν (o == null || getClass ()! = o.getClass ()) {return false; } Simpson simpson = (Simpson) o; ηλικία επιστροφής == simpson.age && weight == simpson.weight && name.equals (simpson.name); }}} 

Στην πρώτη σύγκριση, ισούται με () συγκρίνει την τρέχουσα παρουσία αντικειμένου με το αντικείμενο που έχει περάσει. Εάν τα δύο αντικείμενα έχουν τις ίδιες τιμές, ισούται με () θα επιστρέψει αληθής.

Στη δεύτερη σύγκριση, ισούται με ()ελέγχει αν είναι το αντικείμενο που έχει περάσει μηδενικόή εάν έχει πληκτρολογηθεί ως διαφορετική τάξη. Αν είναι διαφορετική τάξη, τότε τα αντικείμενα δεν είναι ίδια.

Τελικά, ισούται με () συγκρίνει τα πεδία των αντικειμένων. Εάν δύο αντικείμενα έχουν τις ίδιες τιμές πεδίου, τότε τα αντικείμενα είναι ίδια.

Ανάλυση συγκρίσεων αντικειμένων

Τώρα, ας δούμε τα αποτελέσματα αυτών των συγκρίσεων στο δικό μας κύριος() μέθοδος. Πρώτον, συγκρίνουμε δύο Σίμπσον αντικείμενα:

 System.out.println (νέο Simpson ("Homer", 35, 120). Equals (νέο Simpson ("Homer", 35, 120))); 

Τα αντικείμενα εδώ είναι πανομοιότυπα, οπότε το αποτέλεσμα θα είναι αληθής.

Στη συνέχεια, συγκρίνουμε δύο Σίμπσον αντικείμενα ξανά:

 System.out.println (νέο Σίμπσον("Bart", 10, 45). Ίσα (νέα Σίμπσον("El Barto", 10, 45))); 

Τα αντικείμενα εδώ είναι σχεδόν πανομοιότυπα αλλά τα ονόματά τους είναι διαφορετικά: Bart και El Barto. Επομένως το αποτέλεσμα θα είναι ψευδής.

Τέλος, ας συγκρίνουμε ένα Σίμπσον αντικείμενο και μια παρουσία της κλάσης Object:

 System.out.println (νέο Σίμπσον("Lisa", 54, 60). Ίσοι (νέο Αντικείμενο())); 

Σε αυτήν την περίπτωση το αποτέλεσμα θα είναι ψευδής επειδή οι τύποι τάξεων είναι διαφορετικοί.

ισούται με () έναντι ==

Με την πρώτη ματιά, το == χειριστής και ισούται με () μέθοδος μπορεί να φαίνεται να κάνει το ίδιο πράγμα, αλλά στην πραγματικότητα λειτουργούν διαφορετικά. ο == τελεστής συγκρίνει εάν δύο αναφορές αντικειμένων δείχνουν το ίδιο αντικείμενο. Για παράδειγμα:

 System.out.println (homer == homer2); 

Στην πρώτη σύγκριση, δημιουργήσαμε δύο διαφορετικά Σίμπσον περιπτώσεις που χρησιμοποιούν το νέος χειριστής. Εξαιτίας αυτού, οι μεταβλητές Όμηρος και ομηρος2 θα δείξει σε διαφορετικό Αντικείμενο αναφορές στο σωρό μνήμης. Έτσι θα έχουμε ψευδής ως αποτέλεσμα.

System.out.println (homer.equals (homer2)); 

Στη δεύτερη σύγκριση, παρακάμπτουμε το ισούται με () μέθοδος. Σε αυτήν την περίπτωση θα συγκριθούν μόνο τα ονόματα. Επειδή το όνομα και των δύο Σίμπσον τα αντικείμενα είναι "Όμηρος" το αποτέλεσμα θα είναι αληθής.

Μοναδική αναγνώριση αντικειμένων με hashcode ()

Χρησιμοποιούμε το κωδικός κατακερματισμού () μέθοδος για τη βελτιστοποίηση της απόδοσης κατά τη σύγκριση αντικειμένων. Εκτελείκωδικός κατακερματισμού () επιστρέφει ένα μοναδικό αναγνωριστικό για κάθε αντικείμενο στο πρόγραμμά σας, το οποίο καθιστά την εργασία σύγκρισης ολόκληρης της κατάστασης του αντικειμένου πολύ πιο εύκολη.

Εάν ο κωδικός hash ενός αντικειμένου δεν είναι ίδιος με τον hashcode ενός άλλου αντικειμένου, δεν υπάρχει κανένας λόγος για την εκτέλεση του ισούται με () μέθοδος: απλά γνωρίζετε ότι τα δύο αντικείμενα δεν είναι τα ίδια. Από την άλλη πλευρά, εάν ο κωδικός κατακερματισμού είναι το ίδιο, τότε πρέπει να εκτελέσετε το ισούται με () μέθοδος για να προσδιορίσετε εάν οι τιμές και τα πεδία είναι ίδια.

Ακολουθεί ένα πρακτικό παράδειγμα με κωδικός κατακερματισμού ().

 δημόσια τάξη HashcodeConcept {public static void main (String ... hashcodeExample) {Simpson homer = new Simpson (1, "Homer"); Simpson bart = νέο Simpson (2, "Όμηρος"); boolean isHashcodeEquals = homer.hashCode () == bart.hashCode (); if (isHashcodeEquals) {System.out.println ("Πρέπει να συγκρίνουμε με τη μέθοδο ίσο επίσης."); } αλλιώς {System.out.println ("Δεν πρέπει να συγκρίνουμε με τη μέθοδο ίσο επειδή" + "το αναγνωριστικό είναι διαφορετικό, αυτό σημαίνει ότι τα αντικείμενα δεν είναι ίσα με σιγουριά."); }} στατική τάξη Simpson {int id; Όνομα συμβολοσειράς; δημόσιο Simpson (int id, όνομα συμβολοσειράς) {this.id = id; this.name = όνομα; } @Override public boolean ισούται με (Object o) εάν (αυτό == o) επιστρέψει true; εάν (o == null @Override public int hashCode () {return id;}}} 

ΕΝΑ κωδικός κατακερματισμού () που επιστρέφει πάντα η ίδια τιμή είναι έγκυρη αλλά όχι πολύ αποτελεσματική. Σε αυτήν την περίπτωση η σύγκριση θα επιστρέφει πάντα αληθής, έτσι το ισούται με () η μέθοδος θα εκτελείται πάντα. Δεν υπάρχει βελτίωση απόδοσης σε αυτήν την περίπτωση.

Η χρήση ισούται με () και hashcode () με συλλογές

ο Σειρά η διεπαφή είναι υπεύθυνη για τη διασφάλιση ότι δεν θα εισαχθούν διπλά στοιχεία στο a Σειρά υποδιαίρεση τάξεως. Τα παρακάτω είναι μερικές από τις τάξεις που εφαρμόζουν το Σειρά διεπαφή:

  • HashSet
  • TreeSet
  • LinkedHashSet
  • CopyOnWriteArraySet

Μόνο μοναδικά στοιχεία μπορούν να εισαχθούν στο α Σειρά, οπότε αν θέλετε να προσθέσετε ένα στοιχείο στο HashSet τάξη (για παράδειγμα), πρέπει πρώτα να χρησιμοποιήσετε το ισούται με () και κωδικός κατακερματισμού () μεθόδους για την επαλήθευση ότι το στοιχείο είναι μοναδικό. Εάν το ισούται με () και κωδικός κατακερματισμού ()Σε αυτήν την περίπτωση, οι μέθοδοι δεν παρακάμπτονται, ενδέχεται να διακινδυνεύσετε την εισαγωγή διπλών στοιχείων στον κώδικα.

Στον παρακάτω κώδικα, χρησιμοποιούμε το Προσθήκη μέθοδος για να προσθέσετε ένα νέο στοιχείο σε ένα HashSet αντικείμενο. Πριν προστεθεί το νέο στοιχείο, HashSet ελέγχει αν το στοιχείο υπάρχει ήδη στη δεδομένη συλλογή:

 if (e.hash == hash && ((k = e.key) == κλειδί || (κλειδί! = null && key.equals (k)))) διακοπή; p = ε; 

Εάν το αντικείμενο είναι το ίδιο, το νέο στοιχείο δεν θα εισαχθεί.

Hash συλλογές

Σειρά δεν είναι η μόνη συλλογή που κάνει χρήση ισούται με () και κωδικός κατακερματισμού (). Τα HashMap, Hashtable και LinkedHashMap απαιτούν επίσης αυτές τις μεθόδους. Κατά κανόνα, εάν δείτε μια συλλογή που έχει το πρόθεμα του "Hash", μπορείτε να είστε σίγουροι ότι απαιτεί παράκαμψη του κωδικός κατακερματισμού () και ισούται με () μεθόδους για να λειτουργούν σωστά τα χαρακτηριστικά τους.

Οδηγίες για τη χρήση ίσων () και κατακερματισμού ()

Θα πρέπει να εκτελέσετε μόνο ένα ισούται με () μέθοδος για αντικείμενα που έχουν το ίδιο μοναδικό αναγνωριστικό κωδικού κατακερματισμού. Θα έπρεπε δεν εκτέλεση ισούται με () όταν το αναγνωριστικό κωδικού κατακερματισμού είναι διαφορετικό.

Πίνακας 1. Συγκρίσεις Hashcode

Εάν το κωδικός κατακερματισμού () σύγκριση ...Επειτα …
επιστρέφει αλήθειαεκτέλεση ισούται με ()
επιστρέφει ψευδέςμην εκτελείτε ισούται με ()

Αυτή η αρχή χρησιμοποιείται κυρίως στο Σειρά ή Χασίσι συλλογές για λόγους απόδοσης.

Κανόνες για σύγκριση αντικειμένων

Όταν ένα κωδικός κατακερματισμού () επιστροφές σύγκρισης ψευδής, ο ισούται με () μέθοδος πρέπει επίσης να επιστρέψει ψευδής. Εάν ο κωδικός κατακερματισμού είναι διαφορετικός, τα αντικείμενα σίγουρα δεν είναι ίδια.

Πίνακας 2. Σύγκριση αντικειμένων με hashcode ()

Όταν επιστρέφει η σύγκριση κωδικού ...ο ισούται με () η μέθοδος πρέπει να επιστρέψει ...
αληθήςσωστό ή λάθος
ψευδήςψευδής

Οταν ο ισούται με () επιστρέφει η μέθοδος αληθής, σημαίνει ότι τα αντικείμενα είναι ίδια σε όλες τις τιμές και τα χαρακτηριστικά. Σε αυτήν την περίπτωση, η σύγκριση του κωδικού κατακερματισμού πρέπει να ισχύει επίσης.

Πίνακας 3. Σύγκριση αντικειμένων με ίσο ()

Οταν ο ισούται με () η μέθοδος επιστρέφει ...ο κωδικός κατακερματισμού () η μέθοδος πρέπει να επιστρέψει ...
αληθήςαληθής
ψευδήςσωστό ή λάθος

Πάρτε την πρόκληση ίσο () και hashcode ()!

Ήρθε η ώρα να δοκιμάσετε τις δεξιότητές σας με το ισούται με () και κωδικός κατακερματισμού () μεθόδους. Ο στόχος σας σε αυτήν την πρόκληση είναι να καταλάβετε την απόδοση των δύο ισούται με () συγκρίσεις μεθόδου και μαντέψτε το μέγεθος του Σειρά συλλογή.

Για να ξεκινήσετε, μελετήστε προσεκτικά τον ακόλουθο κώδικα:

 δημόσια τάξη EqualsHashCodeChallenge {public static void main (String ... doYourBest) {System.out.println (new Simpson ("Bart"). ισούται με (νέο Simpson ("Bart"))); Simpson overriddenHomer = νέο Simpson ("Homer") {public int hashCode () {return (43 + 777) + 1; }} System.out.println (νέο Simpson ("Homer"). Ισούται με (overriddenHomer)); Set set = νέο HashSet (Set.of (νέο Simpson ("Homer"), νέο Simpson ("Marge"))); set.add (νέο Simpson ("Όμηρος")); set.add (overriddenHomer); System.out.println (set.size ()); } στατική τάξη Simpson {String name; Simpson (Όνομα συμβολοσειράς) {this.name = name; } @Override δημόσια boolean ισούται με (Object obj) {Simpson otherSimpson = (Simpson) obj; επιστρέψτε αυτό.name.equals (otherSimpson.name) && this.hashCode () == otherSimpson.hashCode (); } @Override public int hashCode () {return (43 + 777); }}} 

Θυμηθείτε, αναλύστε πρώτα τον κώδικα, μαντέψτε το αποτέλεσμα, και στη συνέχεια εκτελέστε τον κωδικό. Ο στόχος σας είναι να βελτιώσετε την ικανότητά σας με ανάλυση κώδικα και να απορροφήσετε βασικές έννοιες Java για να κάνετε τον κώδικα πιο ισχυρό. Επιλέξτε την απάντησή σας πριν ελέγξετε τη σωστή απάντηση παρακάτω.

 A) true true 4 B) true true 3 C) true true 2 D) false true 3 

Τι συνέβη μόλις τώρα? Η κατανόηση ισούται με () και hashcode ()

Κατά την πρώτη ισούται με () σύγκριση μεθόδου, το αποτέλεσμα είναι αληθής επειδή η κατάσταση του αντικειμένου είναι ακριβώς η ίδια και η κατάσταση κωδικός κατακερματισμού () Η μέθοδος επιστρέφει την ίδια τιμή και για τα δύο αντικείμενα.

Στο δεύτερο ισούται με () σύγκριση μεθόδου, το κωδικός κατακερματισμού () η μέθοδος παρακάμπτεται για το overridenHomer μεταβλητός. Το όνομα είναι "Όμηρος" και για τους δύο Σίμπσον αντικείμενα, αλλά το κωδικός κατακερματισμού () Η μέθοδος επιστρέφει μια διαφορετική τιμή για αντικατέστησε το Homer. Σε αυτήν την περίπτωση, το τελικό αποτέλεσμα από το ισούται με () η μέθοδος θα είναι ψευδής επειδή η μέθοδος περιέχει μια σύγκριση με τον κωδικό κατακερματισμού.

Μπορεί να παρατηρήσετε ότι το μέγεθος της συλλογής έχει οριστεί να διατηρεί τρία Σίμπσον αντικείμενα. Ας το ελέγξουμε λεπτομερώς.

Το πρώτο αντικείμενο στο σετ θα εισαχθεί κανονικά:

 νέο Simpson ("Όμηρος") · 

Το επόμενο αντικείμενο θα εισαχθεί επίσης κανονικά, επειδή έχει διαφορετική τιμή από το προηγούμενο αντικείμενο:

 νέο Simpson ("Marge") · 

Τέλος, τα ακόλουθα Σίμπσον αντικείμενο έχει την ίδια τιμή με το πρώτο αντικείμενο. Σε αυτήν την περίπτωση το αντικείμενο δεν θα εισαχθεί:

 set.add (νέο Simpson ("Όμηρος")); 

Όπως γνωρίζουμε, το overridenHomer το αντικείμενο χρησιμοποιεί διαφορετική τιμή κωδικού από τον κανονικό Σίμπσον ("Όμηρος") οργάνωση. Για αυτόν τον λόγο, αυτό το στοιχείο θα εισαχθεί στη συλλογή:

 overriddenHomer; 

Κλειδί απάντησης

Η απάντηση σε αυτόν τον αμφισβητία Java είναι σι. Η έξοδος θα ήταν:

 αληθινό ψευδές 3 

Πρόκληση βίντεο! Ο εντοπισμός σφαλμάτων ισούται με () και hashcode ()

Ο εντοπισμός σφαλμάτων είναι ένας από τους ευκολότερους τρόπους για να απορροφήσετε πλήρως τις έννοιες προγραμματισμού, βελτιώνοντας παράλληλα τον κώδικά σας. Σε αυτό το βίντεο μπορείτε να ακολουθήσετε ενώ πραγματοποιώ εντοπισμό σφαλμάτων και εξήγηση της Java ισούται με () και κωδικός κατακερματισμού () πρόκληση.