Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Vaše jistota na trhu IT Kontejnery Rudolf Pecinovský

Podobné prezentace


Prezentace na téma: "Vaše jistota na trhu IT Kontejnery Rudolf Pecinovský"— Transkript prezentace:

1 Vaše jistota na trhu IT Kontejnery Rudolf Pecinovský

2 Vaše jistota na trhu IT Obsah s odkazy ► Dědění rozhraní Dědění rozhraní ► Úvod do typových parametrů Úvod do typových parametrů ► Třída Object a její metody Třída Object a její metody ► Kontejnery – kolekce, množiny, seznamy Kontejnery – kolekce, množiny, seznamy ► Návrhový vzor Iterátor Návrhový vzor Iterátor ► Pole Pole ► Rozhraní Comparable a Comparator Rozhraní Comparable a Comparator

3 Vaše jistota na trhu IT Balíčky ►Problémy velkých aplikací ►Balíčky v jazyku Java ►Příkaz package ►Kořenový balíček ►Plný název třídy a příkaz import ►Balíčky a BlueJ ►Implicitní modifikátor přístupu ►Pravidla pro tvorbu balíčků ►Statický import 310–334 25–26

4 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 4 Problémy velkých aplikací ►Rozsáhlé aplikace používají velké množství názvů objektů a jejich zpráv, které různé části programu sdílí ►V rozsáhlých programátorských týmech se těžko zaručovalo, že někdo z jedné skupiny nezavede objekt se stejným názvem jako někdo z jiné skupiny ►Pro řešení tohoto problému se v 70. letech začaly používat jmenné prostory ►V rámci jmenného prostoru je možné používat názvy svobodně, názvy z jiného jmenného prostoru je třeba kvalifikovat názvem jejich jmenného prostoru ►Jmenné prostory mají hierarchickou stromovou strukturu obdobnou struktuře složek (adresářů) na disku

5 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 5 Balíčky v jazyku Java ►Java zavádí ekvivalent jmenných prostorů pod názvem package – balíček, balík ►Balíček může obsahovat podbalíčky ● Balíček obsahující podbalíčky označujeme jako rodičovský ● Podbalíčky označujeme jako dceřiné balíčky či potomky svého rodiče ►Název balíčku se skládá z názvu rodičovského balíčku následovaného tečkou a vlastním názvem daného balíčku ►Příklady: ● java.lang.reflect, java.util.concurrent Balíčky standardní knihovny a podbalíčky balíčku java

6 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 6 Balíčky a uložení na disku ►Při uložení přeložených souborů na disku musí umístění souborů ve složkách odpovídat jejich umístění v balíčku => ● Každému balíčku je přiřazena jeho složka ● Složka se musí jmenovat přesně stejně jako daný balíček (včetně velikosti písmen) ● Podbalíčku daného balíčku je přiřazena podsložka rodičovského balíčku ►Třída může patřit pouze do jediného balíčku ►(Pra)rodičovský balíček celého stromu nemá jméno a označujeme jako kořenový balíček Rozbalené balíčky java.lang a java.util

7 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 7 Balíčky v jazyku Java ►Aplikace může mít kořenový balíček umístěný v několika složkách; obsah všech těchto složek je pak považován za obsah kořenového balíčku aplikace ►Obdobně se slučují obsahy párových složek v různých stromech ►Seznam složek s kořenovými balíčky je třeba předat překladači a virtuálnímu stroji v proměnné CLASSPATH ►Vývojová prostředí od této povinnosti osvobozují, informaci vygenerují a dodají sama Na obrázku vpravo je kořenovou složkou standardní knihovny složka C:\Java\JDK.1.5.0\src

8 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 8 Příkaz package ►Zdrojový kód každé třídy musí začínat příkazem package deklarujícím název balíčku, do nějž třída patří; před ním smí být jen bílé znaky a komentáře ►Příkaz_package: package název_balíčku ; ►Výjimkou jsou pouze třídy z kořenového balíčku, které příkazem package naopak začínat nesmí ►Kořenový balíček není plnohodnotný, řada konstrukcí v něm není použitelná  používá se proto jen pro rychlé testy proveditelnosti některých nápadů (a v prvních lekcích výuky)

9 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 9 Příkaz import 1/2 ►Název třídy sestává z názvu jejího balíčku následovaného tečkou a vlastním názvem třídy ● Příklad: java.lang.String (třída String je v balíčku lang, který je podbalíčkem balíčku java, jenž je podbalíčkem kořenového balíčku ►Uvnitř balíčku se na třídu lze odvolávat jejím vlastním názvem bez kvalifikace názvem jejího balíčku ►Bez kvalifikace se lze odvolávat i na třídy z balíčku java.lang ►Při posílání zprávy třídě z jiného balíčku je třeba uvádět její plný název včetně kvalifikace balíčkem ( java.util.List ) ►Z předchozího pravidla se lze „vylhat“ uvedením názvu třídy v příkazu import

10 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 10 Příkaz import 2/2 Příkaz_import: import název_balíčku. vlastní_název_třídy ; import název_balíčku. * ; ►Druhá verze příkazu import importuje všechny třídy z daného balíčku ►Každý příkaz import může importovat pouze jedinou třídu nebo všechny třídy z jediného balíčku ►Příkaz import musí být uveden na počátku zdrojového kódu, před ním smí být pouze příkaz package nebo jiný import ►Příklad: import java.io.File; //Třída File z balíčku java.io import java.util.*; //Všechny třídy z balíčku java.util

11 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 11 Příklad použití package a import package adventura.rup; import java.util.Arrays; import adventura.rámec.ABatoh; import adventura.rámec.AHra; import adventura.rámec.AMístnost; import adventura.rámec.KrokTestu; import adventura.rámec.TestHry; /***************************************************** * Instance třídy Hra_RP} představují hru, * při níž se hráč ocitne v malém bytě, který je třeba * projít a najít v něm ledničku. */ public class Hra_RP extends AHra { //== KONSTANTNÍ ATRIBUTY TŘÍDY =======================

12 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 12 Balíčky a BlueJ1/2 ►BlueJ považuje každý balíček za samostatný projekt; pro každý balíček tedy otevře samostatné aplikační okno ►Mezi balíčky/projekty není možné natahovat čáry závislostí ani dědičnosti – příslušné informace je třeba zadat „ručně“ přímo do zdrojového kódu ►Každý balíček/projekt musí mít ve své složce svůj vlastní soubor package.bluej a/nebo bluej.pkg ● BlueJ původně používal soubor bluej.pkg, ale ten nebylo možno asociovat s aplikací, protože přípona byla již blokována jiným programem. Proto autoři zvolili jinou příponu a soubor s informacemi o vzhledu aplikačního okna a diagramu tříd se nyní jmenuje package.bluej. V zájmu zpětné kompatibility však BlueJ reaguje i na starší soubor. ►Kořenovým balíčkem/projektem stromu projektů je projekt, v jehož rodičovské složce se již soubor package.bluej ani bluej.pkg nenachází

13 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 13 Balíčky a BlueJ2/2 ►Balíčky mají v diagramu tříd vlastní ikony připomínající ikony složek ►Balíček lze vytvořit zadáním příkazu z místní nabídky plochy ►Balíček lze odstranit zadáním příkazu z místní nabídky balíčku ►S ikonou rodičovského balíčku není možno nijak hýbat ►V místní nabídce rodičovského balíčku je seznam názvů rodičovských balíčků až ke kořeni; klepnutím na název se přesuneme do projektu příslušného danému balíčku

14 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 14 Příklad

15 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 15 Implicitní modifikátor přístupu ►Vedle modifikátorů přístupu public a private existuje i implicitní modifikátor přístupu, který se uplatní, když žádný modifikátor přístupu neuvedeme ►Entity s implicitním modifikátorem přístupu jsou viditelné a dosažitelné pouze v rámci daného balíčku ►Implicitní modifikátor přístupu bývá označován jako package private; je to ale pouze označení pro doprovodné texty, v programu se nijak neoznačuje ►Zdrojové kódy tříd s implicitním přístupem nemusejí být v souborech, které mají stejné jméno jako třída => těchto tříd může být i několik v jednom souboru ►Jako neveřejné je vhodné deklarovat opravdu jen třídy určené pro interní potřebu celého daného balíčku

16 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 16 Pravidla pro tvorbu balíčků ►Balíček by měl být „jednoúčelový“, tj. obsahovat pouze třídy a rozhraní přímo se vážící k řešení stejného problému ►Název balíčku má být dle konvencí jen malými písmeny ►U prodávaných aplikací by měl začátek názvu balíčku odpovídat internetové adrese výrobce ● Kdyby katedra informačních technologií dodávala aplikace, měly by být v podbalíčcích balíčku cz.vse.kit ►Tato konvence zabezpečí jedinečnost názvu použitých tříd na celém světě (za podmínky, že výrobce zaručí jedinečnost názvu v rámci svého webu)

17 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 17 Statický import ►Java 5.0 zavedla možnost importovat i statické členy jiných tříd a používat je pak bez kvalifikace Statický_import: import static balíček. třída. člen ; import static balíček. třída. * ; ►Používání statického importu znepřehledňuje program ►Má smysl pouze u členů, které se používají velice často a u nichž nehrozí vyvolání dojmu, že se jedná o členy dané třídy

18 Vaše jistota na trhu IT Úvod do typových parametrů ►Knihu je možno stáhnout ve formátu PDF na adrese

19 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 19 Učebnice ke kurzu ►Vydal Computer Press 2005, ISBN ►Podrobně vysvětluje řadu konstrukcí, které jinde podrobně česky vysvětlené nenajdete: ● Parametrizované typy a typové parametry ● Výčtové typy ● Anotace ● Kódování znaků rozšířené sady Unicode ►Je vyprodaná, ale můžete si ji legálně zdarma stáhnout ve formátu PDF na adrese

20 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 20 Řešený problém ►Kontejner = objekt určený k ukládání jiných objektů ►Do verze 5.0 nebylo v Javě možno definovat obecný kontejner (datový typ) tak, abychom typ skutečně ukládaných hodnot mohli zadat až při vytváření jeho konkrétní instance ►Kontejnery ze standardní knihovny byly ochotny ukládat objekty libovolného objektového typu; typovou kontrolu bylo možno provést až za běhu ►Autoři Javy se inspirovali řešením v jazyku C++ a ve verzi 5.0 zavedli do jazyka typové parametry a parametrizované typy ►Parametrizované typy jsou často označovány jako generické typy ● angl. generic = 1. obecný, obecně použitelný, 2. rodový, 3. neznačkový (např. lék) umožňující generovat celou řadu

21 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 21 Parametrizované typy a metody ►Své parametry mají nejenom metody, ale i typy (rozhraní a třídy) – hovoříme o parametrizovaných typech ►Parametry třídy uvádějí typy použitých objektů – označujeme proto jako typové parametry ►Typové parametry uvádíme ve špičatých závorkách za názvem třídy – např. List ►Jako typové parametry je možno použít pouze objektové typy ►Používané zkratky: ● PT– parametrizovaný typ / parametrizované typy ● PM– parametrizovaná metoda / parametrizované metody ● PTM– parametrizované typy a metody ● TP– typový parametr ►Parametrizovaná (generická) metoda != metoda s parametry

22 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 22 Typově parametry a překlad ►Typové parametry slouží jako informace o typech objektů pouze pro překladač ● Rozhoduje o přípustnosti použitého typu ● V případě potřeby vloží potřebné přetypování ►Přeložený kód je od těchto informací „očištěn“ (erasure) a žádné dodatečné typové informace již neobsahuje – překladač upozorňuje na možné kolize v přeloženém kódu ►Ve zdrojovém kódu můžeme použít parametrizovaný typ i bez typových parametrů, překladač ale ohlásí varování

23 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 23 Definice vlastního parametrizovaného typu public class FrontaP { List prvky = new ArrayList (); public FrontaP() {} public void zařaď( E prvek ) { prvky.add( prvek ); } public boolean isPrázdná() { return (prvky.size() == 0); } public E další() { E ret = prvky.get(0); prvky.remove(0); return ret; } public String toString() { return prvky.toString(); } ►Třída FrontaP pracuje s objekty typu E ● FrontaP = Fronta s typovým Parametrem ►Pomocí typového parametru definujeme skutečný typ objektů ve frontě ● FrontaP ►Hodnota TP specifikuje typ parametru či typ návratové hodnoty

24 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 24 Omezení hodnot typových parametrů ►Občas potřebujeme, aby typové parametry vyhovovaly daným omezením – např. aby implementovaly nějaké rozhraní public class IntervalU > { private final T dolní, horní; public IntervalU( T dolní, T horní ) { if( dolní.compareTo( horní ) > 0 ) throw new IllegalArgumentException( "Dolní mez nemůže být větší než horní" ); this.dolní = dolní; this.horní = horní; } public T getDolní() { return dolní; } public T getHorní() { return horní; } public boolean uvnitř( T t ) { return (dolní.compareTo( t ) <= 0) && (t.compareTo( horní ) <= 0); } I pro implementaci rozhraní se používá extends

25 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 25 Žolíky ►Slouží k řešení problémů způsobených omezeními dědičnosti parametrizovaných typů ►Může-li na daném místě být objekt libovolného typu, použijeme žolík ? ►Může-li být na daném místě objekt libovolného typu vyhovujícího zadanému omezení, použijeme žolík s příslušným omezením ● Jakákoliv třída: ● Třída implementující rozhraní X, resp. potomek X: ● Omezení lze kombinovat: >

26 Vaše jistota na trhu IT Kontejnery ►Obecně o kontejnerech ►Architektura knihovny kolekcí ►Rozhraní Collection

27 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 27 Obecně o kontejnerech ►Kontejnery = objekty sloužící k uložení jiných objektů ►Kontejnery dělíme na ● Statické – „narodí se“ s kapacitou, která jim zůstane až do smrti ●Přepravka ●Pole ● Dynamické – mohou se přizpůsobovat okamžitým potřebám ●Množina ●Seznam ●Fronta ●Strom ●Mapa (slovník) ●… ►I dynamické kontejnery mohou definovat „konstanty“, které pak již počet ani hodnoty uchovávaných prvků nemění

28 Knihovna kolekcí v Javě 6 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 28

29 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 29 Knihovna kolekcí – architektura

30 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 30 Zjednodušená knihovna kolekcí

31 Vaše jistota na trhu IT Kolekce, množiny, seznamy

32 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 32 Rozhraní Collection – kolekce1/2 ► boolean add( E o ) Přidá zadaný prvek, vrátí informaci, zda se kolekce změnila ► boolean addAll( Collection c ) Přidej všechny prvky ze zadané kolekce, vrátí zda se kolekce změnila ► void clear() Vyprázdni kolekci ► boolean contains( Object o ) Zjistí, zda kolekce obsahuje zadaný prvek ► boolean containsAll( Collection c ) Zjistí, zda kolekce obsahuje všechny prvky ze zadané kolekce ► boolean isEmpty() Zjistí, zda je kolekce prázdná

33 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 33 Rozhraní Collection – kolekce2/2 ► boolean remove( Object o ) Odstraní zadaný objekt z kolekce a vrátí informaci, zda se kolekce změnila ► boolean removeAll( Collection c ) Odstraní z kolekce všechny prvky ze zadané kolekce; vrátí, zda se tím změnila ► int size() Vrátí počet prvků v kolekci ► Object[] toArray() Vrátí pole s prvky kolekce ► Object[] toArray( Object[] a ) Vrátí pole prvků zadaného typu s prvky kolekce; vejdou-li se do pole v parametru, vrátí toto pole, nevejdou-li se, vytvoří nové ►Potomek rozhraní Iterable => Iterator iterator() Vrátí iterátor zpřístupňující prvky uložené v kolekci

34 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 34 Rozhraní Set – množina ►Množiny jsou zvláštním druhem kolekcí, v nichž může být každý prvek uložen pouze jednou ►Přebírá všechny metody svého rodiče, nic vlastního nepřidává ►Upřesňuje pouze kontrakt: v množině se nesmějí vyskytovat dva stejné prvky, tj. prvky, pro něž platí e1.equals(e2) == true ►Množiny se (obecně) nezajímají o pořadí uložených prvků, a proto o něm ani neinformují ►Implementace jsou optimalizovány na rychlost vyhledávání uložených instancí ►Konkrétní implementace budou ukázány po probrání iterátorů

35 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 35 Příklad: Molekuly public void animace { Set vyhodit = new HashSet (); for(;;) { for (Molekula m1 : molekuly) { if (vývěva.vcucne(m1)) { vyhodit.add(m1); //Nemohu vyhodit hned break; } for (Molekula m2 : molekuly) { if ((m1 != m2) && m1.kolize(m2)) odraž(m1, m2); } //for m2 odrazOdStěn(); } //for m1 for (Molekula m : vyhodit) { molekuly.remove(m); //Dodatečné vyhození } porodnice.zkusNovou(); } //for(;;) } //animace

36 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 36 Rozhraní List – seznam1/2 ►Oproti množině uchovává pořadí uložených prvků ►Díky pořadí umožňuje uložit několikrát týž objekt ►Oproti Collection přidává metody reagující na umístění (= indexy) uložených/ukládaných prvků ►Počáteční prvek v seznamu má index 0 ►Poslední prvek má index size()-1 ► void add(int index, E element) Přidá zadaný prvek na zadanou pozici, pozice následujících se zvětší ► boolean addAll(int index, Collection c) Přidá prvky zadané kolekce na zadanou pozice a pozice následující ► E remove(int index) Odstraní instanci na zadané pozici

37 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 37 Rozhraní List – seznam2/2 ► E get(int index) Vrátí instanci uloženou na zadané pozici ► int indexOf(Object o) Vrátí pozici prvního výskytu zadané instance ► int lastIndexOf(Object o) Vrátí pozici posledního výskytu zadané instance ► E set(int index, E element) Nahradí prvek na zadané pozici zadaným prvkem ► List subList(int fromIndex, int toIndex) Vrátí seznam obsahující prvky na pozicích od fromIndex do toIndex-1 včetně

38 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 38 Implementace seznamu ►Třída ArrayList ● Úspornější na paměť ● Běžné přidání prvku je rychlejší ● Umí rychle přistupovat ke kterémukoliv prvku ● Umí rychle přidávat a odebírat prvky pouze na konci seznamu ►Třída LinkedList ● Náročnější na paměť (prvek si pamatuje odkazy na předchůdce a následníka) ● Běžné přidání je pomalejší (musí se vytvořit odkazy) ● Umí rychle přistupovat pouze k prvkům na začátku a konci ● Umí rychle přidávat a odebírat prvky kdekoliv v seznamu ►Závěr ● Většinou je výhodnější ArrayList ● Je-li prvků hodně (> 16) a potřebujeme-li často přidávat či odstraňovat prvky z prostředku seznamu a málo náhodně přistupovat, je lepší LinkedList

39 Vaše jistota na trhu IT Návrhový vzor Iterátor ►Problémy zapouzdření kontejnerů ►Návrhový vzor Iterátor ►Interface Iterator ►Použití iterátoru ve standardní knihovně ►Porovnání cyklu s iterátorem a bez něj ►Iterovatelné třídy 532–538

40 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 40 Problémy zapouzdření kontejnerů ►Instance, které ukládáme do kontejneru, neodkládáme jako do popelnice – budeme je chtít v budoucnu použít ►Kontejner nás však nemůže nechat se ve svých útrobách přehrabovat – to by nám musel prozradit svou implementaci ►Potřebujeme mít možnost se kdykoliv dostat k uloženým datům, aniž by kontejner byl nucen cokoliv prozradit o své implementaci ►Problém řeší aplikace návrhového vzoru Iterátor

41 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 41 Návrhový vzor Iterátor – princip ►Kontejner definuje speciální třídu – iterátor, jejíž instance ví, jak jsou svěřená data uložena ►Tomu, kdo chce pracovat s uloženými daty vrátí na požádání instanci iterátoru, který mu přístup k uloženým datům zprostředkuje ►Instance iterátoru na požádání vrátí odkaz na další z instancí uložených v kontejneru ►Až iterátor všechna data vyčerpá, oznámí, že už další nejsou ►Tazatel se tak dostane ke všem uloženým datům, aniž by se dozvěděl, jak jsou vlastně uložena

42 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 42 interface Iterator package java.util; public interface Iterator { /** Je ještě nějaká instance k dispozici? */ boolean hasNext(); /** Vrátí odkaz na další instanci. */ E next(); /** Odebere z kolekce * naposledy vrácenou instanci. * Metoda nemusí být plně implementována. */ void remove(); }

43 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 43 Ukázka použití public static void println( String název, Collection kolekce ) { System.out.print( název + ": (" ); String oddělovač = ""; for( Iterator it = kolekce.iterator(); it.hasNext(); /* nic */ ) { Object o = it.next(); String s = o.toString(); System.out.print( oddělovač + s ); oddělovač = ", "; } System.out.println( ")" ); }

44 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 44 Totéž s novou verzí cyklu public static void println( String název, Collection kolekce ) { System.out.print( název + ": (" ); String oddělovač = ""; for( Object o : kolekce ) { //Objekt již mám přiřazen String s = o.toString(); System.out.print( oddělovač + s ); oddělovač = ", "; } System.out.println( ")" ); }

45 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 45 Použití ve třídě AbstractCollection public abstract Iterator iterator(); public boolean contains(Object o) { Iterator ie = iterator(); if (o==null) { while (ie.hasNext()) if (ie.next()==null) return true; } else { while (ie.hasNext()) if (o.equals(ie.next())) return true; } return false; }

46 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 46 Totéž s novou verzí cyklu public abstract Iterator iterator(); public boolean contains(Object o) { if (o==null) { for(E e : this ) if (e == null) return true; } else { for( E e : this ) if (o.equals(e)) return true; } return false; }

47 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 47 Porovnání cyklu s iterátorem a bez něj //Zjednodušený for = „for each“ for( E e : kont ) { //Tělo cyklu pracující s prvkem e } //Klasická verze cyklu for( Iterator ie = kont.iterator; ie.hasNext(); ) { E e = ie.next(); //Tělo cyklu pracující s prvkem e } ►Zjednodušenou verzi nelze použít, pokud chceme v těle pracovat s kontejnerem (např. z něj prvek vyhodit či přidat)

48 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 48 Iterovatelné třídy ►Zjednodušenou verzi cyklu můžeme použít v případě, že třída sloužící jako zdroj dat je iterovatelná, tj. implementuje rozhraní Iterable ►Rozhraní požaduje implementaci jediné metody: public Iterator iterator() ►Metoda bývá většinou implementována tak, že vrací instanci vnořené nebo vnitřní třídy

49 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 49 Implementace množiny a hešové tabulky ►Jsou postaveny na hešových tabulkách ► HashSet ● Nepatrně rychlejší ukládání nového prvku do množiny ● Maličko pomalejší procházení množiny iterátorem ● Nezaručuje pořadí, v němž bude iterátor poskytovat uložené prvky ► LinkedHashSet ● Nepatrně pomalejší ukládání nového prvku do množiny ● Maličko rychlejší procházení množiny iterátorem ● Iterátor bude vracet prvky ve stejném pořadí, v jakém byly do množiny ukládány ● Pokud prvek odstraním a zase vložím, bude do vložení dalšího prvku považován za naposledy vložený

50 Vaše jistota na trhu IT Množiny a mapy ►Množina ►Mapa ►Rozhraní java.util.Map ►Implementace množin a map ►Metody hashCode() a equals(Object) ►Implementace hashCode() ►Příklad mapy: příkazy pro CPU 522–531 82–96 45–49 36–41

51 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 51 Mapa ►Mapa je kontejner, který spolu s ukládanou informací ukládá i tzv. klíč, podle kterého se bude daná informace hledat ● Ukládám-li informace o osobách, budu je vyhledávat buď podle příjmení a jména, nebo ještě lépe podle rodného čísla ►Klíče se uvnitř ukládají do množiny a každý klíč zná odkaz na s ním spřaženou hodnotu ● Ukládání do množiny vynucuje jedinečnost klíče, tj. nesmí se vyskytnout dva stejné klíče pro různé hodnoty ►Některé operace: ● Uložit dvojici ● Získat uloženou hodnotu zadám-li klíč ● Získat množinu klíčů uložených hodnot ● Získat kolekci uložených hodnot (stejná hodnota může být uložena se dvěma klíčí – pak bude v mapě dvakrát => hodnoty nemohou být v množině)

52 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 52 Rozhraní java.util.Map 1/2 ► static interface Map.Entry Rozhraní definované jako interní datový typ v rozhraní Map ► void clear() Vyprázdní danou mapu ► boolean containsKey(Object key) ► boolean containsValue(Object value) ► Set > entrySet() Mapa je vlastně množina přepravek, i když tak není definovaná ► Collection values() Vrátí kolekci hodnot v mapě (jedna hodnotu v ní může být vícekrát). ► V get(Object key) Vrátí hodnotu přiřazenou danému klíči K = key – třída klíče V = value – třída hodnoty

53 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 53 Rozhraní java.util.Map 2/2 ► boolean isEmpty() ► Set keySet() Vrátí množinu všech použitých klíčů ► V remove(Object key) Vyjme klíč s přidruženou hodnotou z mapy a vrátí hodnotu ► V put(K key, V value) Přiřadí zadanému klíči zadanou hodnotu, měl-li již předtím klíč nějakou hodnotu přiřazenou, vrátí ji jako návratovou hodnotu. ► void putAll(Map t) ► int size()

54 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 54 Implementace množin a map ►Množiny a mapy se většinou implementují prostřednictvím hešových tabulek ►Do hešové tabulky se hodnota ukládá na pozici odvozenou z hodnoty heš-kódu dané instance ►Jsou-li hodnoty v tabulce rovnoměrně rozprostřeny, je jejich vyhledávání nesmírně rychlé ►Je-li heš-kód vypočítáván nešikovně, kumulují se hodnoty v tabulce na jednom místě a při hledání hodnoty se musí procházet seznam všech hodnot, které patří v tabulce na danou pozici ►Abychom byla práce s hešovými tabulkami do nejefektivnější, musíme umět správně spočítat heš-kód

55 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 55 Metody hashCode() a equals(Object) ►Metoda hashCode() přiřazuje instanci celé číslo – její heš-kód ►Platí kontrakt: a.equals(b) => a.hashCode() == a.hashCode() ►Další požadavky ● Hodnota musí být co nejrovnoměrněji rozprostřena ● Hodnota musí být spočtena dostatečně rychle ►Předchozí požadavky si trochu odporují, proto si řada instancí jednou spočtenou hodnotu pamatuje, aby ji příště nepočítala ►Doporučení, jak počítat heš-kód: ● J. Bloch: Effective Java, Addison-Wesley, ISBN ● J. Bloch: Java efektivně, Grada 2002, ISBN

56 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 56 Implementace hashCode() ►U referenčních objektových typů můžeme akceptovat implementaci obdrženou od systému ►U hodnotových objektových typů, tj. u těch, pro něž jsme definovali metodu equals(Object), musíme k této metodě definovat i vlastní verzi metody hashCode() ►Metodu musíme naprogramovat tak, aby byl dodržen kontrakt a aby se navíc hodnoty co nejlépe rozprostřely public int hashCode() { if( hashCode == 0 ) hashCode = 37*( x) + y; return hashCode; } Možná podoba definice metody hashCode() pro třídu Pozice Deklarace: private int hashCode;

57 Vaše jistota na trhu IT Pole ►Základní charakteristikaZákladní charakteristika ►Pole jako objektPole jako objekt ►Výhody a nevýhodyVýhody a nevýhody ►Inicializace políInicializace polí ►Vícerozměrná poleVícerozměrná pole ►Proměnný počet parametrůProměnný počet parametrů 563–586 97–102

58 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 58 Základní charakteristika ►Pole je typ kontejneru, který je implementován přímo ve strojovém kódu většiny procesorů a současně v syntaxi prakticky všech jazyků ►Ostatní kontejnery jsou proto velmi často implementovány jako pole ►Každý prvek v poli má svoji přesnou adresu – index ►Indexy v polích jsou stejné jako v seznamech ● Index „prvního“ prvku je 0 (tj. jedná se o „nultý“ prvek) ● Index posledního prvku = počet prvků – 1

59 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 59 Pole jako objekt V Javě je pole standardní objekt se všemi vlastnostmi objektu ►Vytváří se pomocí operátoru new ►Můžete jej použít všude, kde lze použít objekt ►Má definovány všechny metody, které objekty získávají od systému ►Má veřejný konstantní atribut length, který vrací počet jeho prvků ● Na rozdíl od metody size() dříve probraných kontejnerů nevrací počet prvků, které jsme do pole uložili, ale kolik prvků se do pole vejde

60 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 60 Výhody a nevýhody ►Výhody ● Maximálně efektivní (má přímou podporu v jazyku i procesoru) ● Je možné je jednoduše inicializovat ● Umožňuje ukládat i hodnoty primitivních typů ● Lze je použít všude tam, kde je možno/nutno použít objekt ● Pro pole, ze kterého jen čtu, lze použít příkaz for(:) ►Nevýhody ● Má pevnou velikost zadávanou při jeho vytváření ● Nelze poznat, které prvky jsme do něj již vložili ● Na rozdíl od seznamu nepodporuje vkládání prvku mezi existující ● Na rozdíl od mapy používá jako klíč vždy číselný index ►+ / – ● Index prvků je neměnný

61 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 61 Deklarace a inicializace1/2 Deklarace_pole: [ Modifikátor… ] Typ [] Název [ = Inicializace_pole ] ; Inicializace_pole: { Výraz [, Výraz ] [, ] } Vytvoření_pole: new Typ [] [ Inicializace_pole ] public static int součet( int[] ii ) { int součet = 0; for( int i : ii ) součet += i; return součet; } public static void test() { int is = součet( new int[] { 1,2,3,4,5 } ); int[] ii = {9, 8, 7, 6}; int is = součet( ii ); } Vytvoření a inicializace pole „na poslední chvíli“ Cyklus „for each“

62 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 62 Deklarace a inicializace2/2 ►Vytvořené pole je (na rozdíl od některých jiných jazyků) inicializované nulami / prázdnými odkazy / … ►Chci-li do pole ukládat, musím použít klasickou podobu cyklu ►Metoda může vracet pole stejně jako jiný objekt public static String[] číslaSlovy( int počet ) { String[] ret = new String[počet]; for( int i=0; i < ret.length; i++ ) { ret[i] = Slovy.číslo( i ); } return ret; }

63 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 63 Vícerozměrná pole ►Typ prvků pole může být cokoliv, tedy i jiné pole ►Pole, jehož prvky jsou jiná pole, označujeme jako vícerozměrné pole ►Počet rozměrů (tj. hloubka vnoření) není omezen (leda pamětí) ►Vícerozměrné pole nemusí být obdélníkové, každé z polí, které je prvkem pole vyššího řádu, může mít svůj rozměr

64 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 64 Příklad s vícerozměrným polem public static void vícerozměrné() { int[][] ip2 = { { 1, 2, 3, 4, 5 }, { 10, 20, 30, 40 } }; for( int[] ip1 : ip2 ) { for( int i : ip1 ) System.out.print( i + " - " ); System.out.println(); } System.out.println(); for( int i1=0; i1 < ip2.length; i1++ ) for( int i2=0; i2 < ip2[i1].length; i2++ ) System.out.print( ip2[i1][i2] + " - " ); } Výsledek činnosti metody Inicializace vícerozměrného pole dvěma jednorozměrnými poli Parametrem vnějšího cyklu je pole Parametrem vnitřního cyklu je celočíselná proměnná Parametrem obou cyklů jsou celočíselné proměnné – indexy prvků pole Na prvek pole se odkazujeme prostřednictvím jeho indexů

65 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 65 Proměnný počet parametrů ►Java 5.0 umožnila definovat metody, které nemají předem daný počet parametrů ►Všechny parametry, o nichž předem nevíme, kolik jich bude, musejí být stejného typu ►V deklaraci metody označujeme proměnný (=předem neznámý) počet parametrů trojtečkou za názvem jejich typu ►Deklarace proměnného počtu parametrů musí být poslední deklarací v seznamu parametrů (=> smí být jen jedna) ►Metoda přebírá parametry, jejichž počet nezná, v poli

66 VŠE – 05 Copyright © 2006, Rudolf Pecinovský 66 Příklad na proměnný počet parametrů public static int max( int... ii ) { if( (ii==null) || (ii.length==0) ) return CHYBA(); int max = ii[0]; for( int i=1; i < ii.length; i++ ) { if( ii[i] > max ) max = ii[i]; } return max; } public static void testMax() { int m = max( 1, 6, 4, 5 ); } Parametr ii je chápán jako pole

67 Vaše jistota na trhu IT Děkuji za pozornost ►Rudolf Pecinovský mail: ICQ:


Stáhnout ppt "Vaše jistota na trhu IT Kontejnery Rudolf Pecinovský"

Podobné prezentace


Reklamy Google