
Java pro LotusScriptové programátory 3. 
Jan Krejcárek, 03.09.2010
|
Kategorie: Články\Lotus Notes
Řízení toku programu pomocí příkazů if a switch a způsoby porovnávání řetězců.
Pro rozhodování směru, kterým se bude program ubírat, se používají stejně jako v LotusScriptu příkazy 'if' a 'switch' (ve skriptu Select).
Příkaz if
Na příkazu if není co komplikovat a tak jen syntaxe pro úplnost:
Java | LotusScript |
| if (podmínka) { blok příkazů; } else if (podmínka) { blok příkazů; } else { blok příkazů; } | If podmínka Then blok příkazů Else If podmínka Then blok příkazů Else blok příkazů End If |
- Závorky kolem podmínky jsou v Javě povinné, ve skriptu volitelné.
- čáti else if a else mohou být stejně jako ve skriptu vypuštěny
- složené závorky se nemusí psát, pokud následuje pouze jeden řádek kódu. Jejich přidáním lze ale předejít nejasnostem a možným budoucím chybám.
Příkaz switch
Příkaz switch plní stejnou funkci jako Select a Case ve skriptu. Při jeho použití je kód čitelnější než při mnohonásobném rozhodování pomocí if ...else if..... else if....else if příkazu.
Switch v Javě má jednu nevýhodu - ve výběru lze použít jen primitivní datové typy jako byte, short, char, a int, nelze použít řetězec. Od Javy verze 5 lze použít nový datový typ - enumeraci.
Syntaxe:
Java | LotusScript |
| switch (co) { case x: blok příkazů; break; case y: blok příkazů; break; case z: blok příkazů; break: default: blok příkazů; break; } | Select (co) Case x blok příkazů Case y blok příkazů Case z blok příkazů Case Else blok příkazů End Select |
Příkaz break u každého case příkazu je nutný, jinak by kód proplul k bloku příkazů za dalším case. Někdy toho lze využít, jindy to vede k na první pohled hůře odhalitelným chybám.
Situaci ilustruje příklad pro určení počtu dnů v určitém měsíci v roce:
int month = 2;
int year = 2000;
int numDays = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDays = 31;
break;
case 4:
case 6:
case 9:
case 11:
numDays = 30;
break;
case 2:
[výpočet pro přestupný rok odstraněn]
default:
System.out.println("neplatný měsíc");
break;
}
Poslední break u příkazu default technicky vzato nutný není, ale doporučuje se ho psát.
Jen pro úplnost - stejného efektu se v LotusScriptu dosáhne tímto zápisem:
Select (month)
Case 1,3,5,7,8,10,12
numDays = 31
case 4,6,9,11
numDays = 30
case 2
.....atd
Porovnávání řetězců
Narazili jsme na to, že příkaz switch neumí pracovat s řetězci. V praxi je právě ale porovnání řetězců velmi časté (např. archivace dokumentu se provede pouze tehdy, když hodnota pole status v takovém dokumentu je "ArchivePending").
Porovnávat lze v Javě několika způsoby, některým způsobům je lepší se vyhnout.
Porovnání pomocí ==
Obecně se hodnoty porovnávají pomocí dvou rovnítek == (např. i == 0, isClosed == true apod.). Porovnávat takto dva řetězce ale není možné, protože se v takovém případě zjišťuje jestli reference ukazují na stejný objekt (objekt se nachází na nějakém místě v paměti a reference je zjednodušeně řečeno údaj, který místo v paměti identifikuje). Pokud se tedy načte řetězec z dokumentu a porovnává se pomocí dvou rovnítek s řetězcem zapsaným přímo v kódu nebo načteným např. z profilového dokumentu, nikdy nebudou takové dva řetězce odkazovat na stejné místo v paměti.
V případě řetězců se tedy musí porovnávat jinak.
Porovnání pomocí metody compareTo
Třída String obsahuje metodu compareTo(), která jako parametr přebírá jiný String a porovnává je abecedně. Výsledkem je číslo, které říká, jestli jsou řetězce shodné (výsledek je 0), jestli je řetězec menší než parametr (tj. je dříve v abecedě - výsledek je menší než 0) nebo větší než parametr (tj. je dále v abecedě - výsledek je větší než 0).
Metoda compareTo má svůj smysl při seřazení množství řetězců podle abecedy. Pokud se testuje obsah pole Notesového dokumentu k určitému řetězci, pak je údaj o tom, který řetězec je dříve v abecedě, zbytečný. V takovém případě stačí metoda equals...
Porovnání pomocí metody equals
Metoda equals je definována v třídě java.lang.Object, je tedy k dispozici v každé třídě v Javě (objekt sedí na vrcholku hiearchie dědičnosti). Metoda equals() přijímá jako parametr jinou instanci třídy Object (tedy jakoukoliv třídu) a porovnává, jestli se shodují. Implementace pak záleží na každé třídě (např. instance třídy Obdelnik se bude shodovat s jinou instanci Obdelniku, pokud strany A a B budou stejně dlouhé).
V případě třídy String se testuje, jestli oba řetězce obsahují stejné znaky. Pokud obsahují, vrací metoda true, jinak vrací false.
Toto je tedy nejvhodnější metoda pro porovnání shodnosti řetězců. Kód pak může vypadat takto:
String status = doc.getItemValueString("Status")
if (status.equals("ArchivePending")) {
blok příkazů;
}
Porovnávat lze i tak, že se nebere ohled na velikost znaků - pomocí metody equalsIgnoreCase().
Třída String obsahuje i metody pro porovnání části řetězec. Použít lze např. metody startsWith(), endsWith(), matches(), regionMatches(). Popis metod se nachází v API dokumentaci k třídě String.
Ještě poznámka k metodě compareTo...
Vzhledem ke způsobu, jakým metoda compareTo() řetězce porovnává, je použitelná pouze v jednom případě - pokud se porovnávají řetězce obsahující pouze velká písmena z první poloviny ASCII tabulky. V ostatních případech je k ničemu.
Důvodem je to, že metoda používá Unicode hodnotu znaků pro určení řazení. A malá písmena mají vyšší hodnotu Unicode než písmena velká, písmena s háčky a čárkami mají ještě vyšší Unicode hodnotu.
Příklad:
Těchto pět řetězců
áuto
Brzda
auto
Auto
brzda
je seřazeno pomocí metody compareTo() takto:
Auto
Brzda
auto
brzda
áuto
což je chybně (v češtině velikost písmen nerozhoduje, písmeno s diakritikou následuje po písmeni bez diakritiky)
Řešením pro správné seřazení je použití třídy java.text.Collator. Třídě se při vytvoření instance předá instance třídy Locale popisující národní prostředí - podle zvyklostí předaného prostředí bude pozdějí třída Collator řetězce porovnávat. Bez uvedení instance Locale bude použito výchozí prostředí nastavené pro danou Java Virtual Machine. Požadované národní prostředí se udává při vytvoření instance dvěma řetězci - kódem jazyka podle ISO 639 a kódem země podle ISO 3166. V případě českého národního prostředí stačí uvést kód jazyka "cs".
Použitím kódu:
ArrayList<String> strings = new ArrayList<String>();
strings.add("auto");
strings.add("brzda");
strings.add("áuto");
strings.add("Auto");
strings.add("Brzda");
Collator coll = Collator.getInstance(new Locale("cs"));
Collections.sort(strings, coll);
se pak docílí správného seřazení podle národních zvyklostí:
auto
Auto
áuto
brzda
Brzda
Ještě poznámka ke kódu...
Zápis ArrayList<String> strings = new ArrayList<String>(); vytváří instanci třídy sloužící jako dynamicky rostoucí pole, do kterého budou ukládány řetězce. Není třeba tedy znát dopředu množství řetězců, které budou do seznamu vloženy ani není třeba hlídat kapacitu pole a zvětšovat ji pomocí Redim jako v LotusScriptu.
Seznam komentářů (1)
