290 likes | 381 Views
Programozás I. 8. gyakorlat. Kollekciók. objektumokat tartalmaznak Előnyei: a tömbbel szemben itt nincs meghatározott méretük, bármennyi objektumot pakolhatunk bele hatékonyabb fejlesztés (gyorsabb is) kész, hatékony kereső, rendező algoritmusok Fajtái: Collection: Set, List, Queue
E N D
Programozás I. 8. gyakorlat
Kollekciók • objektumokat tartalmaznak • Előnyei: • a tömbbel szemben itt nincs meghatározott méretük, bármennyi objektumot pakolhatunk bele • hatékonyabb fejlesztés (gyorsabb is) • kész, hatékony kereső, rendező algoritmusok • Fajtái: • Collection: • Set, List, Queue • Map: • SortedMap
List • Listák (konkrét megvalósítások) - Egy elem többször is szerepelhet benne • ArrayList: tömbbel megvalósított lista • elemek elérése gyors (konstans idő) • beszúrás lassú • LinkedList: láncolt lista • (minden csomóponthoz tartozik egy mutató előre és hátra, valamint az érték) • elérése lassabb • beszúrás gyorsabb mint az ArrayList-nél
Set • Egy elem nem szerepel benne többször (hiába tesszük bele többször) • HashSet • hash táblában tárol • keresés gyors • TreeSet • fastruktúrában tárol mindig(!) rendezett a halmaz
Map • Kulcs-érték párok (kulcsokat párosít értékekkel) • A kulcsokra gyors keresés biztosított • Kulcs nem ismétlődhet, de érték igen! • Fajtái • HashMap: bejáráskor véletlenszerű sorrend • TreeMap: bejáráskor meghatározott sorrend • piros-fekete fa
Kollekció kezelése • Kollekció létrehozása az ArrayList példáján (de a többi is hasonló): List lista = new ArrayList(); lista.add(new Integer(3)); lista.add(4); // Wrapper objektum képződik! • Kollekcióba csak objektumot tehetünk!
Kollekció kezelése • Hozzáadás kollekcióhoz: • lista.add(objektum); • lista.add(index, objektum); • ha nem adunk meg indexet, akkor értelemszerűen a következő üres helyre teszi! • Törlés: • lista.remove(objektum); • lista.remove(index); • Kollekció mérete: lista.size(); • Kollekció kiürítése: lista.clear();
Kollekció kezelése • Elemek lekérése: • lista.get(index); • Object objektumot ad vissza • Downcastolni kell a megfelelő típusra típuskényszerítés Kutya kutyus = new Kutya(); lista.add(1, kutyus); Kutya masikKutya = (Kutya) lista.get(1);
Típuskényszerítés • „Veszélyes művelet” lehet, mivel ClassCastException-t dobhat • De mivel tudjuk mit tettünk bele, így tudjuk azt is, mivé kell castolni a kivett elemet • Emiatt érdemes csak egy fajta objektumot tárolni egy kollekcióban (pl. csak Kutya objektumokat, csak Stringet, stb) • Különben könnyen összekavarhatjuk a dolgokat downcastnál • Generikus kollekciók(!) ...
Kollekció kezelése • A kollekció tartalmaz-e egy adott objektumot: • lista.contains(objektum) - igazzal tér vissza, ha benne van az elem a kollekcióban • Üres-e egy adott kollekció: • lista.isEmpty() - igazzal tér vissza, ha üres (létezik a kollekció, de nincs benne elem!)
Kollekció kezelése • Lista bejárása for ciklussal: • „hagyományos” módon: for int i = 0; i < lista.size(); i++) { Kutya kutyus = (Kutya) lista.get(i); kutyus.ugat(); } • for-each ciklussal: for ( Object kutyuli : lista ) { Kutya k = (Kutya) kutyuli; k.ugat(); }
Bejárás iterátorral • Igazán hatékony bejárást biztosít • Előnyei: • sokkal gyorsabb, mint a „mezei” ciklus használata • nem kell ismernünk a bejárt dolgok belső szerkezetét • használatával csak ellenőrzött módon módosítható a kollekció (remove() metódus)
Bejárás iterátorral • Az előző lista példáján hozzunk létre egy iterátort • Iterator it = lista.iterator(); • it.hasNext() : megmondja, hogy van-e következő elem • it.next() : a következő elemet adja vissza (Objectként) Példaprogram: Kollekciok.java , Kollekciok2.java
Map-ek kezelése • A példában HashMap van, de minden Map-re hasonló • Map map = new HashMap(); • Hozzáadás: • map.put(kulcs, érték); • a kulcshoz és az értékhez is egy-egy objektumot vár (van autoboxing) • több azonos kulcs nem lehet! (de érték igen)
Map-ek kezelése • Egy adott kulcshoz tartozó érték: • map.get(kulcs) - egy Object típusú objektummal tér vissza, castolni kell • Egy adott kulcsot tartalmaz-e • map.containsKey(kulcs) - igaz, ha tartalmazza a Map az adott kulcsot • Egy adott értéket tartalmaz-e: • map.containsValue(kulcs) - igaz, ha tartalmazza a Map az adott kulcsot
Map-ek kezelése • Adott Map méretének lekérdezése: • map.size(); • Adott Map üres-e • map.isEmpty(); - igaz, ha a Map üres (de ettől még létezik, csak nincs benne elem!) • Adott Map kiürítése: • map.clear();
Bejárás iterátorral • Közvetlenül Map-et nem lehet bejárni iterátorral, ezért át kell alakítanunk halmazzá: • Set mSet = map.entrySet(); • Ezek után létrehozhatunk ennek a halmaznak egy iterátort: • Iterator iter = mSet.iterator(); • Iterator iterMas = map.entrySet().iterator(); • az iter.next() által visszaadott objektumot Map.Entry típusra kell kényszeríteni Példaprogram: Mapek.java
Generikus kollekciók • Java 1.5-től létezik (Jelenleg Java 1.8) • Lényege, hogy egy kollekcióban csak adott típusú elemeket tároljunk • A Collection-öknél is szó volt róla, hogy célszerű azonos típusú objektumokat tárolni csak, de így kötelezővé tesszük • meghatározzuk, hogy milyen objektumokat tárolunk benne • rengeteg hibalehetőségtől kíméljük meg magunkat • manapság nem igazán használunk NEM generikus kollekciókat
Generikus kollekciók • Integereket tároló lista: • List<Integer> intList = new ArrayList<Integer>(); • Előnye, hogy listából való kivételkor nem kell típuskényszerítenünk: • Integer a = intList.get(2); //Integert ad vissza, nem Object-et • Bejárás generikus iterátorral • Iterator<Integer> it = intList.iterator();
Generikus kollekciók • Bejárás for ciklussal: for(int i=0; i < intList.size(); i++) { Integer a = intList.get(i); //Nincs downcast } • Bejárás for-each ciklussal: for(Integer myInt : intList) { Integer a = myInt; //Nincs downcast }
Generikus Map-ek • A kollekciókhoz hasonlóan Map is lehet generikus: • Map<Integer, Kutya> map = new HashMap<Integer, Kutya>(); • Bejárás iterátorral (hasonlóan mint a „sima” Map) • Iterator<Map.Entry<Integer, Kutya>> it = map.entrySet().iterator();
Egymásba ágyazhatóság • A Map-eket, illetve a kollekciókat egymásba is ágyazhatjuk, néhány példa: • HashMap<String, ArrayList> m = new HashMap<String, ArrayList>(); • HashMap<String, ArrayList<String>> m = new HashMap<String, ArrayList<String>>(); Példaprogram: CollectionsAndIOGenerics.java GenerikusKollekciok.java
Puffer kezelése Writer ki = new FileWriter(new File("uj.txt")); ki.write("szöveg, valami blabal"); ki.flush(); ki.write("Másvalami szöveg, valami blabal"); ki.close(); • flush() metódus: Ürítjük a puffert, azaz, amit eddig átadtunk neki, az biztosan kiíródik a fájlba • lassú művelet
Puffer kezelése • a close() által mindenképpen meghívásra kerül a puffert kiürítő függvény • Ha nem szükséges azonnali, adott időbeni kiírás, akkor nem szükséges flush()-t használnunk, hiszen a close() meghívásakor minden kiíródik • ennek feltétele viszont, hogy a close()-t használni kell • a flush() nem zár le, csak puffert ürít, így a close()-ra mindenképpen szükség van!
RandomAccessFile osztály • Hasznos, ha ~egyidőben szeretnénk olvasni, és írni egyazon fájlból/fájlba • Metódusai hasonlóak az eddigiekhez: • read() • readLine() • write() • close() Bővebben: http://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html
StringTokenizer osztály • Stringeket darabolhatunk fel vele részekre • Alapértelmezetten 5 esetben darabol: • Szóköz • Tab • Újsor karakter • Carriage return (kocsi vissza) karakter • Line feed http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html Példaprogram: StringTokenizerPelda.java CollectionAndIO.java
StringTokenizer osztály • Létrehozás: • String s = ”sor amit tordelni kell”; • StringTokenizer st = new StringTokenizer(s); • Egyéni karakter mentén történő darabolás: • st = new StringTokenizer(s, ”;”); • Bejárás while ciklussal a legegyszerűbb: while(st.hasMoreElements()) { String resz = st.nextElement().toString(); }
Stringek hatékony összefűzése • függvények segítségével kezelhető a String hossza, tartalma • StringBuffer (szinkronizált), StringBuilder • A sima Stringek + jellel való konkatenálása is StringBuffer-re fordul le. StringBuffer szoveg= new StringBuffer(); szoveg.append("első rész"); szoveg.append("fűzzük hozzá ezt is").append("meg ezt is"); System.out.println(szoveg.toString());