Στην Java, το Σειρά
class ενσωματώνει μια σειρά από απανθρακώνω
. Θεσω απλα, Σειρά
είναι μια σειρά χαρακτήρων που χρησιμοποιούνται για τη σύνθεση λέξεων, προτάσεων ή οποιωνδήποτε άλλων δεδομένων θέλετε.
Το Encapsulation είναι μια από τις πιο ισχυρές έννοιες στον αντικειμενοστραφή προγραμματισμό Λόγω της ενθυλάκωσης, δεν χρειάζεται να γνωρίζετε πως λειτουργεί η κλάση String. απλά πρέπει να ξέρετε τι μεθόδους για χρήση στη διεπαφή του.
Όταν κοιτάς το Σειρά
τάξη στην Java, μπορείτε να δείτε πώς ο πίνακας του απανθρακώνω
είναι ενθυλακωμένο:
δημόσια συμβολοσειρά (τιμή char []) {αυτό (τιμή, 0, value.length, null); }
Για να κατανοήσετε καλύτερα την ενθυλάκωση, σκεφτείτε ένα φυσικό αντικείμενο: ένα αυτοκίνητο. Πρέπει να γνωρίζετε πώς λειτουργεί το αυτοκίνητο κάτω από την κουκούλα για να το οδηγήσετε; Φυσικά όχι, αλλά πρέπει να γνωρίζετε τι κάνουν οι διεπαφές του αυτοκινήτου: πράγματα όπως το γκάζι, τα φρένα και το τιμόνι. Κάθε μία από αυτές τις διεπαφές υποστηρίζει ορισμένες ενέργειες: επιτάχυνση, φρένο, στροφή αριστερά, στροφή δεξιά. Είναι το ίδιο στον αντικειμενοστρεφή προγραμματισμό.
Το πρώτο μου blog στο Java Challengers η σειρά εισήγαγε μέθοδο υπερφόρτωσης, η οποία είναι μια τεχνική Σειρά
η τάξη χρησιμοποιεί εκτενώς. Η υπερφόρτωση μπορεί να κάνει τα μαθήματά σας πραγματικά ευέλικτα, όπως Σειρά
:
δημόσια συμβολοσειρά (αρχική συμβολοσειρά) {} δημόσια συμβολοσειρά (τιμή char [], int offset, int count) {} δημόσια συμβολοσειρά (int [] codePoints, int offset, int count) {} δημόσια συμβολοσειρά (byte byte [], int offset , int length, String charsetName) {} // Και ούτω καθεξής ... ...
Αντί να προσπαθούμε να καταλάβουμε πώς το Σειρά
τάξη λειτουργεί, αυτό το Java Challenger θα σας βοηθήσει να καταλάβετε τι το κάνει και πως για να το χρησιμοποιήσετε στον κωδικό σας.
Τι είναι μια πισίνα String;
Σειρά
είναι πιθανώς η πιο χρησιμοποιούμενη τάξη στην Java. Αν ένα νέο αντικείμενο δημιουργήθηκε στη μνήμη κάθε φορά χρησιμοποιούσαμε ένα Σειρά
, θα σπαταλήσαμε πολλή μνήμη. ο Σειρά
το pool επιλύει αυτό το πρόβλημα αποθηκεύοντας μόνο ένα αντικείμενο για κάθε ένα Σειρά
τιμή, όπως φαίνεται παρακάτω.
Αν και δημιουργήσαμε ένα Σειρά
μεταβλητή για το Δούκας
και Juggy
Σειρά
s, μόνο δύο αντικείμενα δημιουργούνται και αποθηκεύονται στο σωρό μνήμης. Για απόδειξη, δείτε το ακόλουθο δείγμα κώδικα. (Θυμηθείτε ότι το «==
Ο τελεστής στην Java χρησιμοποιείται για να συγκρίνει δύο αντικείμενα και να προσδιορίσει εάν είναι ίδια.)
String juggy = "Juggy"; String anotherJuggy = "Juggy"; System.out.println (juggy == anotherJuggy);
Αυτός ο κωδικός θα επιστρέψει αληθής
γιατί τα δύο Σειρά
s στο ίδιο αντικείμενο στο Σειρά
πισίνα. Οι αξίες τους είναι ίδιες.
Εξαίρεση: Ο «νέος» χειριστής
Τώρα κοιτάξτε αυτόν τον κώδικα - μοιάζει με το προηγούμενο δείγμα, αλλά υπάρχει μια διαφορά.
String duke = νέα String ("duke"); String anotherDuke = new String ("duke"); System.out.println (duke == anotherDuke);
Με βάση το προηγούμενο παράδειγμα, ίσως νομίζετε ότι αυτός ο κωδικός θα επιστρέψει αληθής
, αλλά είναι στην πραγματικότητα ψευδής
. Προσθήκη του νέος
ο χειριστής αναγκάζει τη δημιουργία ενός νέου Σειρά
στο σωρό της μνήμης. Έτσι, το JVM θα δημιουργήσει δύο διαφορετικά αντικείμενα.
Εγγενείς μέθοδοι
ΕΝΑ εγγενής μέθοδος Στην Java είναι μια μέθοδος που θα καταρτιστεί χρησιμοποιώντας τη γλώσσα C, συνήθως για τον χειρισμό της μνήμης και τη βελτιστοποίηση της απόδοσης.
String pools και η μέθοδος intern ()
Για να αποθηκεύσετε ένα Σειρά
στο Σειρά
πισίνα, χρησιμοποιούμε μια τεχνική που ονομάζεται Σειρά
πρακτική. Εδώ μας λέει ο Javadoc για το κρατώ()
μέθοδος:
/ ** * Επιστρέφει μια κανονική αναπαράσταση για το αντικείμενο συμβολοσειράς. * * Μια ομάδα συμβολοσειρών, αρχικά κενή, διατηρείται ιδιωτικά από το * class {@code String}. * * Όταν καλείται η μέθοδος intern, εάν η ομάδα περιέχει ήδη μια συμβολοσειρά * ίση με αυτό το αντικείμενο {@code String} όπως καθορίζεται από τη μέθοδο {@link #equals (Object)}, τότε η συμβολοσειρά από την ομάδα είναι * Επέστρεψαν. Διαφορετικά, αυτό το αντικείμενο {@code String} προστίθεται στην ομάδα * και επιστρέφεται μια αναφορά σε αυτό το αντικείμενο {@code String}. * * Ακολουθεί ότι για οποιεσδήποτε δύο συμβολοσειρές {@code s} και {@code t}, * {@code s.intern () == t.intern ()} είναι {@code true} * εάν και μόνο εάν { Το @code s.equals (t)} είναι {@code true}. * * Όλες οι κυριολεκτικές συμβολοσειρές και οι σταθερές εκφράσεις αξίας συμβολοσειράς είναι εσωτερικευμένες. Τα γράμματα συμβολοσειράς ορίζονται στην ενότητα 3.10.5 του * The Java ™ Language Specification. * * @ επιστρέφει μια συμβολοσειρά που έχει το ίδιο περιεχόμενο με αυτήν τη συμβολοσειρά, αλλά είναι εγγυημένη ότι προέρχεται από μια ομάδα μοναδικών συμβολοσειρών. * @jls 3.10.5 String Literals * / δημόσιος εγγενής String intern ();
ο κρατώ()
μέθοδος χρησιμοποιείται για την αποθήκευση Σειρά
s σε ένα Σειρά
πισίνα. Πρώτον, επαληθεύει εάν το Σειρά
έχετε δημιουργήσει υπάρχει ήδη στην πισίνα. Εάν όχι, δημιουργεί ένα νέο Σειρά
μέσα στην πισίνα. Πίσω από τα παρασκήνια, η λογική του Σειρά
η συγκέντρωση βασίζεται στο σχέδιο Flyweight.
Τώρα, παρατηρήστε τι συμβαίνει όταν χρησιμοποιούμε το νέος
λέξη-κλειδί για να αναγκάσει τη δημιουργία δύο Σειρά
μικρό:
String duke = new String ("duke"); String duke2 = new String ("duke"); System.out.println (duke == duke2); // Το αποτέλεσμα θα είναι ψευδές εδώ System.out.println (duke.intern () == duke2.intern ()); // Το αποτέλεσμα θα ισχύει εδώ
Σε αντίθεση με το προηγούμενο παράδειγμα με το νέος
λέξη-κλειδί, σε αυτήν την περίπτωση η σύγκριση αποδεικνύεται αληθινή. Αυτό συμβαίνει επειδή η χρήση του κρατώ()
μέθοδος εξασφαλίζει το Σειρά
s θα αποθηκευτούν στην πισίνα.
Ισούται με τη μέθοδο String
ο ισούται με ()
χρησιμοποιείται μέθοδος για την επαλήθευση εάν η κατάσταση των δύο τάξεων Java είναι η ίδια. Επειδή ισούται με ()
είναι από το Αντικείμενο
τάξη, κάθε κλάση Java την κληρονομεί. Αλλά το ισούται με ()
Η μέθοδος πρέπει να παρακαμφθεί για να λειτουργήσει σωστά. Φυσικά, Σειρά
παρακάμπτει ισούται με ()
.
Ρίξε μια ματιά:
public boolean ισούται με (Object anObject) {if (this == anObject) {return true; } if (anObject instanceof String) {String aString = (String) anObject; if (coder () == aString.coder ()) {return isLatin1 (); StringLatin1.equals (τιμή, aString.value): StringUTF16.equals (τιμή, aString.value); }} επιστροφή false; }
Όπως μπορείτε να δείτε, η κατάσταση του Σειρά
η τιμή της τάξης πρέπει να είναι ισούται με ()
και όχι η αναφορά αντικειμένου. Δεν έχει σημασία αν η αναφορά αντικειμένου είναι διαφορετική. η κατάσταση του Σειρά
θα συγκριθεί.
Οι πιο κοινές μέθοδοι συμβολοσειράς
Υπάρχει μόνο ένα τελευταίο πράγμα που πρέπει να γνωρίζετε πριν πάρετε το Σειρά
πρόκληση σύγκρισης. Εξετάστε αυτές τις κοινές μεθόδους του Σειρά
τάξη:
// Αφαιρεί κενά από την περιγράμματα περιθωρίων () // Παίρνει ένα υπόστρωμα με υπόστρωμα ευρετηρίου (int beginIndex, int endIndex) // Επιστρέφει το μήκος χαρακτήρων του μήκους συμβολοσειράς () // Αντικαθιστά τη συμβολοσειρά, μπορεί να χρησιμοποιηθεί regex. substitAll (String regex, String Replacement) // Επαληθεύει εάν υπάρχει ένα καθορισμένο CharSequence στο String περιέχει (CharSequences)
Πάρτε την πρόκληση σύγκρισης String!
Ας δοκιμάσουμε τι έχετε μάθει για το Σειρά
τάξη σε μια γρήγορη πρόκληση.
Για αυτήν την πρόκληση, θα συγκρίνετε έναν αριθμό Σειρά
χρησιμοποιώντας τις έννοιες που έχουμε διερευνήσει. Κοιτάζοντας τον παρακάτω κώδικα, μπορείτε να προσδιορίσετε την τελική τιμή του καθενός Αποτελέσματα μεταβλητός?
δημόσια τάξη ComparisonStringChallenge {public static void main (String ... doYourBest) {String result = ""; αποτέλεσμα + = "ισχυρό κώδικα" .trim () == "ισχυρό κώδικα"; "0": "1"; αποτέλεσμα + = "FlexibleCode" == "FlexibleCode"; "2": "3"; αποτέλεσμα + = νέα συμβολοσειρά ("doYourBest") == νέα συμβολοσειρά ("doYourBest"); "4": "5"; αποτέλεσμα + = νέα συμβολοσειρά ("noBugsProject"). Equals ("noBugsProject"); "6": "7"; αποτέλεσμα + = νέα συμβολοσειρά ("breakYourLimits"). intern () == new String ("breakYourLimits"). intern ()? "8": "9"; System.out.println (αποτέλεσμα); }}
Ποια έξοδος αντιπροσωπεύει την τελική τιμή της μεταβλητής αποτελεσμάτων;
ΕΝΑ: 02468
σι: 12469
ντο: 12579
ρε: 12568
Ελέγξτε την απάντησή σας εδώ.
Τι συνέβη μόλις τώρα? Κατανόηση της συμπεριφοράς του String
Στην πρώτη γραμμή του κώδικα, βλέπουμε:
αποτέλεσμα + = "ισχυρό κώδικα" .trim () == "ισχυρό κώδικα"; "0": "1";
παρόλο που το Σειρά
θα είναι το ίδιο μετά το τακτοποίηση()
καλείται μέθοδος, το Σειρά
"Ισχυρός κωδικός"
ήταν διαφορετικό στην αρχή. Σε αυτήν την περίπτωση η σύγκριση είναι ψευδής
, επειδή όταν το τακτοποίηση()
Η μέθοδος αφαιρεί κενά από τα όρια που αναγκάζει τη δημιουργία ενός νέου Σειρά
με τον νέο χειριστή.
Στη συνέχεια, βλέπουμε:
αποτέλεσμα + = "FlexibleCode" == "FlexibleCode"; "2": "3";
Δεν υπάρχει μυστήριο εδώ, το Σειρά
είναι τα ίδια στο Σειρά
πισίνα. Αυτή η σύγκριση επιστρέφει αληθής
.
Στη συνέχεια, έχουμε:
αποτέλεσμα + = νέα συμβολοσειρά ("doYourBest") == νέα συμβολοσειρά ("doYourBest"); "4": "5";
Χρησιμοποιώντας το νέος
Η δεσμευμένη λέξη-κλειδί αναγκάζει τη δημιουργία δύο νέων Σειρά
s, είτε είναι ίσοι είτε όχι. Σε αυτήν την περίπτωση η σύγκριση θα είναι ψευδής
ακόμα και αν το Σειρά
οι τιμές είναι ίδιες.
Το επόμενο είναι:
αποτέλεσμα + = νέα συμβολοσειρά ("noBugsProject"). Equals ("noBugsProject"); "6": "7";
Επειδή έχουμε χρησιμοποιήσει το ισούται με ()
μέθοδος, η τιμή του Σειρά
θα συγκριθεί και όχι η παρουσία αντικειμένου. Σε αυτήν την περίπτωση, δεν έχει σημασία εάν τα αντικείμενα είναι διαφορετικά επειδή συγκρίνεται η τιμή. Αυτή η σύγκριση επιστρέφει αληθής
.
Τέλος, έχουμε:
αποτέλεσμα + = νέα συμβολοσειρά ("breakYourLimits"). intern () == new String ("breakYourLimits"). intern ()? "8": "9";
Όπως έχετε ξαναδεί, το κρατώ()
μέθοδος βάζει το Σειρά
στο Σειρά
πισίνα. Και τα δυο Σειρά
s στο ίδιο αντικείμενο, οπότε σε αυτήν την περίπτωση η σύγκριση είναι αληθής
.
Πρόκληση βίντεο! Συγκρίσεις συμβολοσειράς εντοπισμού σφαλμάτων
Ο εντοπισμός σφαλμάτων είναι ένας από τους ευκολότερους τρόπους για να απορροφήσετε πλήρως τις έννοιες προγραμματισμού, βελτιώνοντας παράλληλα τον κώδικά σας. Σε αυτό το βίντεο μπορείτε να ακολουθήσετε ενώ εντοπίζω το σφάλμα και εξηγώ την πρόκληση Java Strings:
Συνηθισμένα λάθη με το Strings
Μπορεί να είναι δύσκολο να γνωρίζουμε αν δύο Σειρά
s δείχνουν προς το ίδιο αντικείμενο, ειδικά όταν το Σειρά
περιέχουν την ίδια τιμή. Σας βοηθά να θυμάστε ότι χρησιμοποιώντας την δεσμευμένη λέξη-κλειδί νέος
οδηγεί πάντα στη δημιουργία ενός νέου αντικειμένου στη μνήμη, ακόμα και αν οι τιμές είναι ίδιες.
Χρησιμοποιώντας Σειρά
μεθόδους σύγκρισης Αντικείμενο
οι αναφορές μπορεί επίσης να είναι δύσκολες. Το κλειδί είναι, εάν η μέθοδος αλλάξει κάτι στο Σειρά
, οι αναφορές αντικειμένων θα είναι διαφορετικές.
Μερικά παραδείγματα για διευκρίνιση:
System.out.println ("duke" .trim () == "duke" .trim ()) ;;
Αυτή η σύγκριση θα ισχύει επειδή το τακτοποίηση()
Η μέθοδος δεν δημιουργεί νέο Σειρά
.
System.out.println ("duke" .trim () == "duke" .trim ());
Σε αυτήν την περίπτωση, το πρώτο τακτοποίηση()
μέθοδος θα δημιουργήσει ένα νέο Σειρά
επειδή η μέθοδος θα εκτελέσει τη δράση της, έτσι οι αναφορές θα είναι διαφορετικές.
Τέλος, όταν τακτοποίηση()
εκτελεί τη δράση του, δημιουργεί ένα νέο Σειρά
:
// Εφαρμογή της μεθόδου trim στο String class String new (Arrays.copyOfRange (val, index, index + len), LATIN1);
Τι πρέπει να θυμάστε για το Strings
Σειρά
είναι αμετάβλητα, έτσι αΣειρά
Η κατάσταση δεν μπορεί να αλλάξει.- Για τη διατήρηση της μνήμης, το JVM διατηρεί
Σειρά
s σε έναΣειρά
πισίνα. Όταν ένα νέοΣειρά
δημιουργείται, το JVM ελέγχει την τιμή του και το δείχνει σε ένα υπάρχον αντικείμενο. Εάν δεν υπάρχειΣειρά
με αυτήν την τιμή στην ομάδα, τότε το JVM δημιουργεί ένα νέοΣειρά
. - Χρησιμοποιώντας το
==
τελεστής συγκρίνει την αναφορά αντικειμένου. Χρησιμοποιώντας τοισούται με ()
μέθοδος συγκρίνει την τιμή τουΣειρά
. Ο ίδιος κανόνας θα εφαρμοστεί σε όλα τα αντικείμενα. - Όταν χρησιμοποιείτε το
νέος
χειριστής, ένα νέοΣειρά
θα δημιουργηθεί στοΣειρά
πισίνα ακόμη και αν υπάρχειΣειρά
με την ίδια τιμή.
Κλειδί απάντησης
Η απάντηση σε αυτόν τον αμφισβητία Java είναι η επιλογή D. Η έξοδος θα ήταν 12568
.
Αυτή η ιστορία, "Σύγκριση χορδών στην Java" δημοσιεύθηκε αρχικά από το JavaWorld.