Lekce 6 - Textové řetězce a referenční typy v Javě
V minulé lekci, Primitivní datové typy v Javě, jsme si podrobně probrali datové typy.
V dnešním Java tutoriálu se podíváme na referenční datové
typy. Popíšeme si vybrané metody datového typu String
a v průběhu tutoriálu se s nimi naučíme pracovat.
Referenční datové typy
K referenčním typům se dostaneme až u objektově orientovaného
programování, kde si také vysvětlíme zásadní rozdíly. Zatím budeme
pracovat jen s tak jednoduchými typy, že rozdíl nepoznáme. Spokojíme se s
informací, že referenční typy jsou složitější než ty primitivní. Jeden
referenční typ již známe – je jím String
. Možná vás
napadá, že String
nemá nijak omezenou délku. Je to tím, že s
referenčními typy se v paměti pracuje jinak. Referenční typy
začínají na rozdíl od typů primitivních velkým písmenem.
Datový typ String
Datový typ String
má na sobě řadu opravdu užitečných
metod. Nyní si některé probereme a vyzkoušíme.
Metody
startsWith()
, endsWith()
a
contains()
Pomocí těchto metod se můžeme jednoduše zeptat, zda řetězec začíná
či končí určitým podřetězcem (substringem) nebo zda řetězec substring
obsahuje. Podřetězcem myslíme část původního řetězce. Všechny tyto
metody budou jako parametr brát samozřejmě podřetězec a vracet hodnoty typu
boolean
(true
/false
). Na výstup zatím
neumíme reagovat, ale pojďme si ho alespoň vypsat:
{JAVA_CONSOLE}
String vstup = "Krokonosohroch";
System.out.println(vstup.startsWith("krok"));
System.out.println(vstup.endsWith("hroch"));
System.out.println(vstup.contains("nos"));
System.out.println(vstup.contains("roh"));
{/JAVA_CONSOLE}
Výstup programu:
Konzolová aplikace
false
true
true
false
Vidíme, že vše funguje podle očekávání. První výraz samozřejmě neprošel kvůli tomu, že řetězec ve skutečnosti začíná velkým písmenem.
Metoda isEmpty()
Někdy se nám hodí vědět, zda není řetězec prázdný. To znamená, že
jeho délka je 0
a že řetězec neobsahuje žádný znak, a to ani
např. mezeru. Takový řetězec můžeme získat např. tak, že uživatel nic
nezadá do nějakého vstupu. Metoda isEmpty()
nám vrátí
true
, pokud je řetězec prázdný, a false
, pokud
prázdný není:
{JAVA_CONSOLE}
String mezera = " ";
String prazdnyRetezec = "";
String retezec = "slovo";
System.out.println(mezera.isEmpty());
System.out.println(prazdnyRetezec.isEmpty());
System.out.println(retezec.isEmpty());
{/JAVA_CONSOLE}
Výstup programu:
Konzolová aplikace
false
true
false
Metody toUpperCase()
a
toLowerCase()
Rozlišování velkých a malých písmen může být někdy na obtíž.
Mnohdy se budeme potřebovat zeptat na přítomnost podřetězce bez ohledu na
velikost písmen. Situaci můžeme vyřešit pomocí metod
toUpperCase()
a toLowerCase()
, které vracejí
řetězec ve velkých či malých písmenech. Uveďme si reálnější
příklad, než je Krokonosohroch. V proměnné budeme mít řádek
konfiguračního souboru, který psal uživatel. Jelikož se na vstupy od
uživatelů nelze spolehnout, musíme se snažit eliminovat možné chyby, zde
např. s velkými písmeny:
{JAVA_CONSOLE}
String nastaveni = "Fullscreen shaDows autosave";
nastaveni = nastaveni.toLowerCase();
System.out.println("Poběží hra ve fullscreenu?");
System.out.println(nastaveni.contains("fullscreen"));
System.out.println("Budou zapnuté stíny?");
System.out.println(nastaveni.contains("shadows"));
System.out.println("Přeje si hráč vypnout zvuk?");
System.out.println(nastaveni.contains("nosound"));
System.out.println("Přeje si hráč hru automaticky ukládat?");
System.out.println(nastaveni.contains("autosave"));
{/JAVA_CONSOLE}
Výstup programu:
Konzolová aplikace
Poběží hra ve fullscreenu?
true
Budou zapnuté stíny?
true
Přeje si hráč vypnout zvuk?
false
Přeje si hráč hru automaticky ukládat?
true
Vidíme, že jsme schopni zjistit přítomnost jednotlivých slov v řetězci tak, že si nejprve řetězec převedeme celý na malá písmena (nebo na velká) a potom kontrolujeme přítomnost slova jen malými (nebo velkými) písmeny. Takto by mimochodem mohlo opravdu vypadat jednoduché zpracování nějakého konfiguračního skriptu.
Metoda trim()
Další nástrahou mohou být mezery a obecně všechny tzv. bílé znaky,
které nejsou vidět, ale mohou nám uškodit. Obecně může být dobré
trimovat všechny vstupy od uživatele. Zkusme si v následující aplikaci
před číslo a za číslo zadat několik mezer, které trim()
odstraní. Odstraňují se vždy bílé znaky kolem řetězce, nikoli
uvnitř:
{JAVA_CONSOLE}
Scanner scanner = new Scanner(System.in);
System.out.println("Zadejte číslo:");
String vstup = scanner.nextLine();
System.out.println("Zadal jste text: " + vstup);
System.out.println("Text po funkci trim: " + vstup.trim());
int cislo = Integer.parseInt(vstup.trim());
System.out.println("Převedl jsem zadaný text na číslo parsováním, zadal jste: " + cislo);
{/JAVA_CONSOLE}
Metoda replace()
Asi nejdůležitější metodou pro typ String
je nahrazení
určité jeho části jiným textem. Jako parametry zadáme dva podřetězce:
jeden, který chceme nahrazovat, a druhý, kterým chceme původní nahradit.
Metoda vrátí nový String
, ve kterém proběhlo nahrazení. Pokud
metoda daný podřetězec nenajde, vrátí původní řetězec.
V následující ukázce použijeme v textu mřížku
#
. Ta se na české klávesnici píše pomocí
Pravého Alt a klávesy X:
Pojďme tedy nahradit podřetězec metodou replace()
:
{JAVA_CONSOLE}
String veta = "C# je nejlepší!";
veta = veta.replace("C#", "Java");
System.out.println(veta);
{/JAVA_CONSOLE}
Výstup programu:
Konzolová aplikace
Java je nejlepší!
Metoda format()
Metoda format()
je velmi užitečná metoda, která nám
umožňuje vkládat do samotného textového řetězce zástupné značky. Ty
jsou reprezentovány jako procento a zkratka datového typu.
V následující ukázce použijeme znak %
. Na
české klávesnici ho píšeme pomocí Shift a =:
Metoda se volá na typu String
. Prvním parametrem je textový
řetězec se značkami, dále následují proměnné v pořadí, ve kterém se
mají do textu místo značek vložit. Všimněme si, že se metoda nevolá na
konkrétní proměnné (přesněji instanci, viz další díly), ale přímo na
typu String
:
{JAVA_CONSOLE}
int a = 10;
int b = 20;
int soucet = a + b;
String veta = String.format("Když sečteme %d a %d, dostaneme %d", a, b, soucet);
System.out.println(veta);
{/JAVA_CONSOLE}
Výstup programu:
Konzolová aplikace
Když sečteme 10 a 20, dostaneme 30
Značky jsou:
%d
pro celá čísla,%s
proString
,%f
profloat
nebodouble
(reálná čísla). Můžeme taktéž definovat délku desetinné části, např.%.2f
pro dvě desetinná místa.
Konzole sama umí přijímat text v takovémto formátu, jen musíme místo
metody println()
volat printf()
. Můžeme tedy
napsat:
{JAVA_CONSOLE}
int a = 10;
int b = 20;
int soucet = a + b;
System.out.printf("Když sečteme %d a %d, dostaneme %d", a, b, soucet);
{/JAVA_CONSOLE}
Toto je velmi užitečná a přehledná cesta, jak sestavovat
řetězce. Přesto se však v Javě řetězce spojují spíše pomocí
operátoru +
.
Metoda printf()
bere v potaz lokalizaci systému
a může namísto desetinné tečky vypsat desetinnou čárku. Dejte si tedy
pozor na to, že očekávaný výstup desetinných čísel na různých
platformách (v jazycích) nemusí být úplně totožný.
Metoda length()
Poslední, avšak nejdůležitější metodou je length()
, tedy
délka. Metoda vrací celé číslo, které představuje počet znaků v
řetězci:
{JAVA_CONSOLE}
Scanner scanner = new Scanner(System.in);
System.out.println("Zadejte vaše jméno:");
String jmeno = scanner.nextLine();
System.out.printf("Délka vašeho jména je: %d", jmeno.length());
{/JAVA_CONSOLE}
K vysvětlování toho zbývá ještě spoustu, navíc existují další datové typy, které jsme neprobrali. K řetězcům se proto ještě vrátíme později v kurzu 😉
V následujícím cvičení, Řešené úlohy k 5.-6. lekci Javy, si procvičíme nabyté zkušenosti z předchozích lekcí.