Skip to the content.

1.4 Συμβολοσειρές

© Γιάννης Κωστάρας


<- Δ ->

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

jshell> String name = "Αγαμέμνων" 
name ==> "Αγαμέμνων"
jshell> // <=> char data[] = {'Α', 'γ', 'α', 'μ', 'έ', 'μ', 'ν', 'ω', 'ν'}
jshell> String name = "Οδυσσέας" 
name ==> "Οδυσσέας"
jshell> String surname = "Ελύτης" 
name ==> "Ελύτης"
jshell> name + " " + surname
$1==> "Οδυσσέας Ελύτης"

Στο παραπάνω παράδειγμα είδαμε πώς μπορούμε να ορίσουμε αλφαριθμητικά καθώς και τη συγχώνευσή τους με τον τελεστή +.

Πράξεις συμβολοσειρών

Πίνακας 1.4.1 Πράξεις/μέθοδοι συμβολοσειρών

+, concat() Συγχώνευση (δημιουργεί ένα νέο String)
+= Συγχώνευση και εκχώρηση
equals() Έλεγχος για ισότητα
equalsIgnoreCase() Έλεγχος για ισότητα αγνοώντας πεζά/κεφαλαία
toLowerCase() Μετατροπή σε πεζά
toUpperCase() Μετατροπή σε κεφαλαία
contains(s) Περιέχει το s;
indexOf(s) Σε ποιο δείκτη ξεκινά το s, ή -1 αν δε βρέθηκε
length() Μήκος συμβολοσειράς
substring(αρχή, τέλος) Eξαγωγή συμβολοσειράς
split() Διαχωρισμός αλφαριθμητικών
join() Συνένωση συμβολοσειρών με κάποιο συνενωτικό χαρ.
toCharArray() Μετατροπή σε ακολουθία χαρακτήρων
trim() Αφαίρεση κενών χαρακτήρων από εμπρός/πίσω
replace(s1, s2) Αντικατάσταση του s1 με το s2
repeat(n) π.χ. "*".repeat(3) επιστρέφει "***"
charAt(n) n-στός χαρακτήρας
startsWith(s) Αρχίζει με τη συμβολοσειρά s
endsWith(s) Τελειώνει με τη συμβολοσειρά s
isEmpty() Είναι κενή συμβολοσειρά;
valueOf() Μετατρέπει το όρισμα σε συμβολοσειρά

Παραδείγματα:

jshell> String s1="Καλήν εσπέραν άρχοντες"
s1 ==> "Καλήν εσπέραν άρχοντες"

jshell> String s2=" άρχοντες"
s2 ==> "άρχοντες"

jshell> s1.equals(s2)
$3 ==> false

jshell> s1.length()
$4 ==> 15

jshell> s1.toLowerCase()
$5 ==> "καλήν εσπέραν άρχοντες"

jshell> s1.contains("Καλήν")
$6 ==> true

jshell> s1.indexOf(s2)
$7 ==> 13

jshell> s1.substring(6,13)
$8 ==> "εσπέραν"

jshell> s1.split(" ")
$9 ==> String[3] { "Καλήν", "εσπέραν", "άρχοντες" } // θα μιλήσουμε για πίνακες στο μάθημα 7

jshell> String.join(" + ", "1", "2", "3")
$10 ==> "1 + 2 + 3"

jshell> s2.trim()
$11 ==> "άρχοντες"

jshell> s2.charAt(0)
$12 ==> ' '

jshell> s1.replace("εσπ", "ημ")
$13 ==> "Καλήν ημέραν άρχοντες"

jshell> s1
s1 ==> "Καλήν εσπέραν άρχοντες"

jshell> String s3 = s1.replace("εσπ", "ημ")
s3 ==> "Καλήν ημέραν άρχοντες"

jshell> s2.endsWith("ες")
$14 ==> true

jshell> String.valueOf(0b100)
$15 ==> "4"

jshell> Integer.toString(0b100)
$16 ==> "4"

jshell> String empty = ""
empty ==> ""

jshell> String quotedStr = "\""
quotedStr ==> """

jshell> String multilineStr= "Σε γνωρίζω από την κόψη\n του σπαθιού την τρομερή"
multilineStr ==> "Σε γνωρίζω από την κόψη
 του σπαθιού την τρομερή"

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

Ποιο αναλυτικά, όταν δημιουργείτε ένα αλφαριθμητικό χρησιμοποιώντας τη σύνταξη:

jshell> String s1 = "Γιάννης";
s1 ==> "Γιάννης"

τότε το s1 δημιουργείται μέσα στο λεγόμενο σύνολο αλφαριθμητικών (string pool). Σ’ αυτήν την περίπτωση μπορείτε να γράψετε:

jshell> String s2 = "Γιάννης";
s2 ==> "Γιάννης"

jshell> s1 == s2
$3 ==> true

Αν όμως χρησιμοποιήσετε τη λέξη κλειδί new της γλώσσας, όπως θα δούμε στα μαθήματα της επόμενης εβδομάδας, για να δημιουργήσουμε ένα νέο αντικείμενο τύπου String, τότε το αλφαριθμητικό δημιουργείται εκτός του string pool με αποτέλεσμα:

jshell> String s3 = new String("Γιάννης");
s3 ==> "Γιάννης"

jshell> s1 == s3
$4 ==> false

jshell> s2 == s3
$5 ==> false

jshell> s1.equals(s3)
$6 ==> true

Γι’ αυτό το λόγο, πάντα χρησιμοποιείτε τη μέθοδο equals() για σύγκριση συμβολοσειρών.

Πίνακας 1.4.2 Ειδικοί χαρακτήρες

\" Διπλό εισαγωγικό
\' Μονό εισαγωγικό
\\ Χαρακτήρας backslash ()
\n Νέα γραμμή (newline ή LF – line feed)
\r Νέα γραμμή (CR – carriage return)
\t Στηλοθέτης (tab)
\f Χαρακτήρας FF (form feed)
\b Χαρακτήρας backspace (BS)
\<octal> Οκταδικός κωδικός (0-255)
\uΧΧΧΧ Χαρακτήρας unicode (16-bit) όπου κάθε Χ είναι ένα δεκαεξαδικό ψηφίο

Μπλοκ κειμένου

Στην έκδοση 13 εμφανίστηκε η δυνατότητα ορισμού μπλοκ κειμένου (text blocks) που επιτρέπουν να δημιουργούμε συμβολοσειρές με την μορφοποίηση που θέλουμε. Τα text blocks έγιναν κανονικό χαρακτηριστικό της γλώσσας στην έκδοση 15 (οπότε δεν απαιτείται πλέον να δώσετε --enable-preview στο jshell). Πριν την έκδοση 13, για να μπορέσετε να γράψετε ένα μορφοποιημένο κείμενο στη γλώσσα θα ‘πρεπε να το γράψετε κάπως έτσι:

String html = "<html>\n" +
              "  <body>\n" +
              "    <p>Hello, world</p>\n" + 
              "  </body>\n" +
              "</html>";

Από την έκδοση 13 και μετά μπορούμε να γράψουμε:

jshell> String html = """
     <html>
        <body>
            <p>Hello, world</p>
        </body>
     </html>
""";
html ==> "     <html>\n        <body>\n            <p>Hell ...   </body>\n     </html>\n"

Τα 3 εισαγωγικά πρέπει να είναι μόνα τους σε ξεχωριστή γραμμή. Δηλ. """<html> είναι λάθος. Αν δεν θέλουμε να υπάρχει αλλαγή γραμμής μετά από κάθε γραμμή τότε μπορούμε να γράψουμε \ για να αποτρέψουμε την αλλαγή γραμμής, π.χ.

jshell> String html = """
     <html>
        <body>
            <p>Hello, \
				world</p>
        </body>
     </html>
""";
html ==> "     <html>\n        <body>\n            <p>Hell ...   </body>\n     </html>\n"

Το \s, τέλος, αποτρέπει να αποκοπούν τα κενά που ακολουθούν το κείμενο (σβήνονται εξ’ ορισμού).

Ασκήσεις

  1. Να γράψετε ένα πρόγραμμα που επιστρέφει τα αρχικά ενός ονοματεπώνυμου (π.χ. αν String name = "Γιάννης Κωστάρας";, επιστρέφει "Γ.Κ.")
  2. Ο αλγόριθμος κρυπτογράφησης του Καίσαρα (Caesar Cipher) αντικαθιστά κάθε γράμμα της αλφαβήτου με ένα άλλο γράμμα της αλφαβήτου το οποίο βρίσκεται κάποιες θέσεις πιο κάτω. Π.χ. δοθέντος του αλφαριθμητικού “ΑΒΓ” και του κλειδιού 3, αυτό μετατρέπεται στο “ΔΕΖ” (“Α”+3 = “Δ”). Γράψτε ένα πρόγραμμα Java το οποίο θα κρυπτογραφεί το αλφαριθμητικό “ΑΒΓ” με βάση ένα ακέραιο κλειδί (int key) και θα εμφανίζει το κρυπτογραφημένο αλφαριθμητικό.
  3. Δοθέντος του αλφαριθμητικού days="ΚυρΔευΤριΤετΠεμΠαρΣαβ" γράψτε ένα πρόγραμμα στο οποίο θα δίνετε τον δείκτη της ημέρας, π.χ. (0 = Κυριακή, 1 = Δευτέρα κ.ο.κ.) και το πρόγραμμά σας θα επιστρέφει τη σωστή ημέρα, π.χ. αν δώσετε 1 θα πρέπει να σας επιστρέψει "Δευ".
  4. Να γραφτεί ένα πρόγραμμα που να εκτυπώνει το παρακάτω σχήμα της τρίλιζας:
    +---+---+---+ 
    |   |   |   |
    +---+---+---+ 
    |   |   |   | 
    +---+---+---+
    |   |   |   | 
    +---+---+---+
    

5) Να γραφτεί ένα πρόγραμμα που να εκτυπώνει τα παρακάτω σχήματα:

     *                  *
    ***                ***
   *****              *****
  *******            *******
 *********          ********* 
    ***              *******  
    ***               ***** 
 *********             ***
                        *

Πηγές

  1. Laskey J. & Marks S. (2019), “Programmer’s Guide To Text Blocks”.

<- Δ ->