java:equals

This is an old revision of the document!


A PCRE internal error occured. This might be caused by a faulty plugin

====== Σύγκριση Αντικειμένων ====== ===== Ο τελεστής == ===== Ο βασικός τελεστής της Java για σύγκριση ισότητας είναι ο ==. Όταν χρησιμοποιείται για σύγκριση ισότητας ανάμεσα σε βασικούς (primitive) τύπους όπως int, char κτλ. τότε επιστρέφει true αν οι τιμές προς σύγκριση είναι ίδιες, διαφορετικά false. Για παράδειγμα το παρακάτω θα εκτυπώσει true στην οθόνη, <code java> /* παράδειγμα 1 */ int x = 15; int y = 14 + 1; System.out.println(x == y); </code> Το ερώτημα είναι τι γίνεται όταν χρησιμοποιείται για σύγκριση ανάμεσα σε αντικείμενα: <code java> /* παράδειγμα 2 */ Point p1 = new Point(3, 4); Point p2 = new Point(3, 4); System.out.println(p1 == p2); </code> Στο παραπάνω κομμάτι κώδικα κατασκευάσαμε δύο αντικείμενα τύπου Point. Οι μεταβλητές p1 και p2 περιέχουν //αναφορές// προς δύο //διαφορετικά// αντικείμενα. Το γεγονός ότι και τα δύο έχουν τα ίδια χαρακτηριστικά δε σημαίνει ότι πρόκειται για το ίδιο αντικείμενο. Επομένως, αυτός ο κώδικας θα τυπώσει false. Πότε επιστρέφει true μια τέτοια σύγκριση? Όταν οι μεταβλητές που συγκρίνονται αναφέρονται στο ίδιο ακριβώς αντικείμενο, για παράδειγμα: <code java> /* παράδειγμα 3 */ Point p1 = new Point(3, 4); Point p2 = p1; System.out.println(p1 == p2); </code> Όμως τα σημεία p1 και p2 όπως έχουν οριστεί στο παράδειγμα 2 έχουν τις ίδιες συντεταγμένες και θα θέλαμε να τα θεωρούμε ίσα. Με άλλα λόγια, μας ενδιαφέρει να μπορούμε να συγκρίνουμε δύο αντικείμενα ως προς τα χαρακτηριστικά τους, την κατάστασή τους. Γι αυτό, χρησιμοποιούμε τη μέθοδο <code>equals</code>. ===== Η μέθοδος equals ===== Η μέθοδος equals παίρνει ως παράμετρο ένα οποιοδήποτε αντικείμενο και επιστρέφει true αν αυτό είναι ίσο με το αντικείμενο πάνω στο οποίο καλείται (το this), διαφορετικά επιστρέφει false: <code java> public boolean equals (Object obj) </code> Ακολουθεί ο συμβατικός τρόπος να υλοποιήσουμε την equals. Στο παράδειγμα που ακολουθεί θα θεωρήσουμε ότι η equals ορίζεται στην κλάση Point που έχετε δει στο μάθημα. * Ελέγχουμε αν η παράμετρος obj είναι υφιστάμενο αντικείμενο ή όχι. Αν δεν είναι, επιστρέφουμε άμεσα false: <code> if (obj == null) { return false; } </code> * Ελέγχουμε αν η παράμετρος obj είναι το ίδιο αντικείμενο με το this. Αν είναι, δεν υπάρχει λόγος να κάνουμε περαιτέρω συγκρίσεις. <code> if (obj == this) { return true; } </code> * Η παράμετρος μπορεί να είναι οποιουδήποτε τύπου, αλλά η σύγκριση έχει νόημα μόνο αν αυτός είναι συμβατός με τον τύπο του τρέχοντος αντικειμένου. Θα δούμε αργότερα τι ακριβώς εννοούμε με το "συμβατός". <code> if (!(obj instanceof Point)) { return false; } </code> * Αν έχουμε ξεπεράσει τους παραπάνω ελέγχους, ξέρουμε πια ότι το obj είναι κατ'εξοχήν τύπου Point και μπορούμε να κάνουμε σύγκριση των πεδίων του με τα αντίστοιχα του this. Προσοχή όμως: Επειδή ο compiler βλέπει τύπο Object στη λίστα παραμέτρων, αν γράψουμε obj.x θα παραπονεθεί ότι στην κλάση Object δεν υπάρχει πεδίο με όνομα x. Για να λύσουμε αυτό το πρόβλημα θα φτιάξουμε μια προσωρινή μεταβλητή τύπου Point στην οποία θα αντιγράψουμε το obj με κατάλληλο typecast: <code> Point other = (Point)obj; return (other.x == this.x && other.y == this.y); </code> Δεν είναι πάντα απαραίτητο να συγκρίνουμε όλα τα πεδία ένα προς ένα, αλλά μόνο αυτά που θεωρούμε ότι ισότητα μεταξύ τους σημαίνει ισότητα ανάμεσα στα δύο αντικείμενα. Επίσης, αν κάποια πεδία δεν είναι βασικοί τύποι όπως στο παράδειγμα, τότε θα πρέπει να χρησιμοποιήσουμε equals για τη σύγκριση. Δείτε το παράδειγμα εργαστηρίου με την κλάση Deck, όπου τα πεδία είναι τύπου String και τα συγκρίνουμε με equals.

java/equals.1488381516.txt.gz · Last modified: 2017/03/01 15:18 (external edit)