14. diel - Textové reťazce v Jave do tretice - Split a join
V predchádzajúcom cvičení, Riešené úlohy k 13. lekcii Javy, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V dnešnom Java tutoriále si vysvetlíme ďalšie metódy na reťazci, ktoré som vám zámerne zatajil, pretože sme nevedeli, že textový reťazec je vlastne pole
Metódy na reťazci
Keď si vytvoríme ľubovoľnú premennú a napíšeme za ňu potom bodku, zobrazí nám IDE ponuku všetkých metód a vlastností (a tiež premenných, ale k tomu sa dostaneme až pri objektoch), ktoré na ňu môžeme volať. Skúsme si to:
Tú istú ponuku je možné vyvolať aj stlačením klávesov Ctrl + Medzerník v prípade, že kurzor umiestnime na bodku.
Samozrejme to platí pre všetky premenné a triedy a budeme to využívať čoraz častejšie. Metódy sú radené abecedne a môžeme nimi listovať pomocou kurzorových šípok. Popis metód (čo robia) a aké vyžadujú parametre môžeme v IntelliJ vyvolať tým, že nabehneme šípkami na metódu, o ktorej chceme vedieť viac, a stlačíme klávesy Ctrl + Q.
Povedzme si niečo o nasledujúcich metódach a ukážme si ich na jednoduchých príkladoch.
Metóda substring()
Vráti podreťazec od danej počiatočnej pozície do danej koncovej pozície:
{JAVA_CONSOLE}
System.out.println("Wolfgang Amadeus Mozart".substring(9, 16));
{/JAVA_CONSOLE}
Výstup:
Konzolová aplikácia
Amadeus
Metóda compareTo()
Umožňuje porovnať dva reťazce podľa abecedy. Vracia hodnotu
-1
, ak je prvý reťazec pred reťazcom v parametri, hodnotu
0
, ak sú rovnaké, a hodnotu 1
, ak je za ním:
{JAVA_CONSOLE}
System.out.println("Argentina".compareTo("Barbados"));
{/JAVA_CONSOLE}
Výstup:
Konzolová aplikácia
-1
Poďme sa teraz pozrieť na ďalšie metódy, ktoré sú naozaj veľmi užitočné.
Metódy split()
a
join()
Z predchádzajúceho tutoriálu vieme, že parsovanie reťazca po znaku môže byť niekedy celkom zložité a to sme robili pomerne jednoduchý príklad. S reťazcami sa samozrejme budeme stretávať stále, a to ako na vstupe od používateľa (napr. z konzoly alebo z polí v okenných aplikáciách), tak v súboroch TXT a XML. Veľmi často máme zadaný jeden dlhší textový reťazec (riadok súboru alebo riadok konzoly), v ktorom je viac hodnôt oddelených tzv. separátormi, napr. čiarkou. V tomto prípade hovoríme o formáte CSV (Comma-Separated Values, teda hodnoty oddelené čiarkou). Aby sme si boli istí, že vieme, o čom hovoríme, pozrime sa na nejaké ukážkové reťazce:
Jessie,Brown,Wall Street 10,New York 3,130 00 .. ... .-.. .- -. -.. ... --- ..-. - (1,2,3;4,5,6;7,8,9)
Význam jednotlivých reťazcov:
- Prvý reťazec je očividne nejaký používateľ, takto by sme mohli napr. realizovať uloženie používateľov do CSV súboru, každý na jeden riadok.
- Druhý reťazec sú znaky Morseovej abecedy, separátorom (oddeľovačom) je tu medzera.
- Tretí reťazec je matica s 3 stĺpcami a 3 riadkami. Oddeľovačom stĺpcov je čiarka, riadkov bodkočiarka.
Na type String
môžeme volať metódu split()
,
ktorá berie ako parameter separátor. Následne pôvodný reťazec rozdelí
podľa separátorov na pole podreťazcov, ktoré vráti. To nám veľmi
uľahčí prácu pri rozdeľovaní hodnôt v reťazci.
Metóda join()
sa volá priamo na type String
a
umožňuje nám naopak pole podreťazcov spojiť oddeľovačom do jediného
reťazca, parametrami sú oddeľovač a pole. Výstupom metódy je výsledný
reťazec.
Keďže nevieme tvoriť objekty (používateľov) a ani pracovať s viacrozmernými poľami (matice), skúsime si naprogramovať dekóder správ z Morseovej abecedy.
Dekóder Morseovej abecedy
Poďme si opäť pripraviť štruktúru programu. Budeme potrebovať 2 reťazce, jeden so správou v Morseovej abecede, druhý zatiaľ prázdny, doňho budeme ukladať výsledok nášho snaženia. Ďalej budeme ako v prípade samohlások potrebovať nejaký vzor písmen. K písmenám samozrejme vzor ich znaku v morzeovke. Písmená môžeme opäť uložiť do obyčajného reťazca, pretože majú iba jeden znak. Znaky Morseovej abecedy majú už znakov viac, tie musíme dať do poľa. Štruktúra nášho programu by teraz mohla vyzerať nasledovne:
// the string which we want to decode String encryptedMessage = ".-.. . --- -. .- .-. -.. ---"; System.out.printf("The original message: %s%n", encryptedMessage); // the string with a decoded message String decodedMessage = ""; // array definitions String alphabetChars = "abcdefghijklmnopqrstuvwxyz"; String[] morseChars = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."};
Môžete si potom pridať ďalšie znaky ako čísla a interpunkčné znamienka, my ich tu vynecháme.
Teraz si reťazec encryptedMessage
rozbijeme metódou
split()
na pole podreťazcov obsahujúcich jednotlivé znaky
morzeovky. Rozdeľovať budeme podľa znaku medzery. Pole následne preiterujeme
cyklom foreach:
// splitting the string into Morse characters String[] characters = encryptedMessage.split(" "); // iterating over Morse characters for (String morseChar : characters) { }
Ideálne by sme sa mali nejako vysporiadať s prípadmi, kde používateľ
zadá napr. viac medzier medzi znakmi (to používatelia radi robia). Metóda
split()
potom vytvorí o jeden reťazec v poli viac, ktorý bude
prázdny. Ten by sme mali potom v cykle detekovať a ignorovať, my sa s tým v
tutoriáli nebudeme zaoberať.
V cykle sa pokúsime nájsť aktuálne čítaný znak morzeovky v poli
morseChars
. Bude nás zaujímať jeho index, pretože keď sa
pozrieme na ten istý index v poli alphabetChars
, bude tam
zodpovedajúce písmeno. To je samozrejme z toho dôvodu, že pole aj reťazec
obsahujú rovnaké znaky zoradené podľa abecedy. Umiestnime do tela cyklu
nasledujúci kód:
char alphabetChar = '?'; int index = -1; for (int i = 0; i < morseChars.length; i++) { if (morseChars[i].equals(morseChar)) index = i; } if (index >= 0) { // character was found alphabetChar = alphabetChars.charAt(index); } decodedMessage += alphabetChar;
Kód najskôr do abecedného znaku (alphabetChar) uloží znak
?
, pretože sa môže stať, že znak v našej sade nemáme.
Následne sa pokúsime zistiť jeho index. Pole v Jave bohužiaľ nemá metódu
indexOf()
a zatiaľ nechcem zabiehať do zložitejších dátových
štruktúr. Napíšeme si teda vyhľadanie typu String
v poli sami,
bude to celkom jednoduché.
Vyhľadanie reťazca v poli
Najprv nastavíme index na -1
, pretože nevieme, či pole daný
String
(Morseov znak) obsahuje. Následne pole prejdeme cyklom a
budeme kontrolovať jednotlivé reťazce s naším stringom (znakom). Už vieme,
že na porovnanie dvoch reťazcov musíme použiť metódu
equals()
. Ak reťazce súhlasia, uložíme si aktuálny index.
Ak sme znak našli (index >= 0
), dosadíme do premennej
alphabetChar
znak z abecedy pod týmto indexom. Nakoniec znak
pripojíme ku správe. Operátor +=
nahrádza
decodedMessage = decodedMessage + alphabetChar
.
Na záver samozrejme správu vypíšeme:
{JAVA_CONSOLE}
// the string which we want to decode
String encryptedMessage = ".-.. . --- -. .- .-. -.. ---";
System.out.printf("Original message: %s%n", encryptedMessage );
// the string with a decoded message
String decodedMessage = "";
// array definitions
String alphabetChars = "abcdefghijklmnopqrstuvwxyz";
String[] morseChars = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};
// splitting the string into Morse characters
String[] characters = encryptedMessage.split(" ");
// iterating over Morse characters
for (String morseChar : characters) {
char alphabetChar = '?';
int index = -1;
for (int i = 0; i < morseChars.length; i++) {
if (morseChars[i].equals(morseChar)) {
index = i;
}
}
// character was found
if (index >= 0) {
alphabetChar = alphabetChars.charAt(index);
}
decodedMessage += alphabetChar;
}
System.out.printf("Decoded message: %s%n", decodedMessage);
{/JAVA_CONSOLE}
Výstup programu:
Konzolová aplikácia
Original message: .-.. . --- -. .- .-. -.. ---
Decoded message: leonardo
Hotovo! Za úlohu máte naprogramovať si program opačný, ktorý naopak
zakóduje reťazec do morzeovky, kód bude veľmi podobný. S metódami
split()
a join()
sa stretneme počas Java kurzu ešte
niekoľkokrát.
Špeciálne znaky a escapovanie
Textový reťazec môže obsahovať špeciálne znaky, ktoré sú predsadené
spätnou lomkou \
. Je to najmä sekvencia \n
, ktorá
kdekoľvek v texte spôsobí odriadkovanie a potom \t
, kde sa
jedná o tabulátor. Sekvenciu \n
do kódu často nepíšeme a
využijeme radšej formátový špecifikátor %n
, ktorý spôsobí
správne odriadkovanie na špecifických platformách. Poďme si to
vyskúšať:
{JAVA_CONSOLE}
System.out.println("First line\nSecond line");
{/JAVA_CONSOLE}
Znak \
označuje nejakú špeciálnu sekvenciu znakov v reťazci
a je ďalej využívaný napr. na písanie Unicode znaku ako
"\uxxxx"
, kde xxxx
je kód znaku.
Problém môže nastať vo chvíli, keď chceme napísať samotné lomítko
\
, musíme ho tzv. odescapovať:
{JAVA_CONSOLE}
System.out.println("This is a backslash: \\");
{/JAVA_CONSOLE}
Rovnakým spôsobom môžeme odescapovať napr. úvodzovku tak, aby ju Java nechápala ako koniec reťazca:
{JAVA_CONSOLE}
System.out.println("This is a quotation mark: \"");
{/JAVA_CONSOLE}
Vstupy z konzoly a polí v okenných aplikáciách sa samozrejme escapujú
samy, aby používateľ nemohol zadať sekvenciu \n
a podobne. V
kóde to má programátor povolené a musí na to myslieť.
Týmto sme v podstate zakončili kurz o základnej štruktúre jazyka Java. V nasledujúcich lekciách si uvedieme viacrozmerné polia a matematické operácie. Zo základných konštrukcií jazyka vás tu ale už nič neprekvapí V podstate by ste už pokojne mohli ísť aj na objekty, odporúčam ale zvyšné tutoriály ešte aspoň prejsť, jedná sa predsa len o základné znalosti, ktoré by ste mali mať.
V nasledujúcom kvíze, Kvíz - Textové reťazce v Jave, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 14x (2.52 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java