Segédanyag: Java alkalmazások gyakorlat
Készítette: Szabó Attila 2010/2011-2 félév, 5. gyakorlat
1 . Java generic-ek
A Java generic-ek, azaz generikus osztályok valamilyen típussal paraméterezett osztályok. Mikor érdemes ezeket használni? Segítségükkel problémafüggetlenül lehet algoritmusokat, adatszerkezeteket definiálni:
● Például a maximumkeresés értelmezhető egész számokon, lebegőpontos számokon, vagy szavakon is (pl. a szóhossz felhasználásával) – azaz bármilyen rendezett halmazon. Ha az összehasonlítás függvénye ismert visszatérési értékkel rendelkezik (például int), akkor a maximumkeresés – az összehasonlító függvény ismeretében – típusfüggetlenül implementálható.
● A lista, vektor, halmaz, stb. típusok műveletei (új elem berakása, elem lekérdezése, stb.) függetlenek attól, milyen típusú elemet tárolnak. Ezek implementációja is történhet típusfüggetlenül.
Java-ban a (beépített) listák, vektorok, halmazok definiálásakor nem kötelező megadni a tárolt elemek típusát, de hasznos: fordításkor segít kiszűrni a potenciális hibákat.
Példa vektor használatára:
Vector<Integer> v = new Vector<Integer>();
v.add(1); //elem hozzaadasa v.add(2); //elem hozzaadasa
for (int i=0, n=v.size(); i<n; ++i) {
Integer act = v.get(i); //elem kivetele System.out.println(act);
}
Csak objektum referenciákat tárolhatnak, ezért primitív típusok helyett ún. csomagoló (wrapper) osztályokat (Integer, Character, Double, stb.) kell használnunk - azonban ezek ilyen esetekben automatikusan konvertálódnak (ld. fenti példa, ahol az 1-ből és a 2-ből automatikusan Integer példányok készülnek).
2 . Gyűjtemény keretrendszer
A gyűjtemény keretrendszer (Collections Framework, java.util.* csomag) objektumok memóriában tárolására, lekérdezése, manipulálása alkalmas (v.ö. A C++ Standard Template Library- jével). Általános célú adatszerkezetek vannak benne, pl. List, Set, Map.
Jellemző műveletek:
1. Alapvető műveletek: size(), isEmpty(), contains(), add(), remove()
2. Elemek együttes kezelése: addAll(), containsAll(), removeAll(), clear(), retainAll()
3. Tömbbé konvertálás (csúnya):
A[] array = (A[]) list.toArray(new A[list.size()]);
1
// Kicsit egyszerubb, bar kevesbe hatekony, biztonsagos:
A[] array = (A[]) list.toArray();
4. Iterátorokkal rendelkeznek, használhatók for-each ciklusokban:
List<Integer> list = new ArrayList<Integer>();
// …
for( Integer elem : list ){
// … }
2.1 Halmaz
Duplikált elemeket nem tartalmazhat, kell hozzá az objektumon az equals() és hashCode()
(hash-elő implementációi vannak, nem számít az elemek sorrendje, 2 halmaz egyenlő, ha ugyanazokat az elemeket tartalmazzák). HashSet, TreeSet: előbbi hatékonyabb, utóbbi rendezett.
2.2 Lista
Elemek pozíció szerinti elérését, iterációt, részlista kezelését támogató adatszerkezet. A remove()
az elem 1. előfordulását távolítja el, az add(), addAll() a lista végéhez fűz hozzá. Két lista egyenlő, ha ugyanazokat az elemeket tartalmazzák, ugyanabban a sorrendben. A lista iterátora a
ListIterator, 2 irányban is bejárható: hasNext(), next(), ill. hasPrevious(), previous(). Részlista: balról zárt, jobbról nyílt intervallumot kell megadni. Két implementáció adott:
ArrayList, LinkedList, előbbi a pozícionális műveleteknek kedvez, utóbbi akkor hasznos, ha a lista elejére kell sokat beszúrni, és iteráció közben törölni (általában az ArrayList használata a célravezetőbb).
2.3 Leképezés
Kulcs-érték párokat tároló adatszerkezet: van HashMap, és Hashtable (minimális különbség van köztük: utóbbi szinkronizált, megengedi a null értékeket is). Minden kulcshoz egy érték tartozhat.
Nem iterálható, azonban lekérdezhető a keySet(), entrySet(), ami már igen.
2.4 Rendezés
Beépített típusoknak értelemszerű a relációja - felhasználói típusok esetében a programozó dönti el, hogy két példány közül melyik a nagyobb (ha egyáltalán létezik értelmes rendezés az adott típusra). Ahhoz, hogy pl. a fenti adatszerkezeteken értelmezett rendezés működhessen, szükség van arra, hogy a felhasználói típusok (osztályok) implementálják a Comparable interfészt, és annak
compareTo() metódusát, melynek eredménye int típusú:
● 0, ha a két objektum egyenlő
● <0, ha az adott objektum kisebb a paraméternél
● >0, ha fordítva Implementálás:
public class Foo implements Comparable<Foo> { ...
public int compareTo(final Foo foo) { return ...;
} }
2
2.5 Kényelmi lehetőségek
● A java.util.Arrays osztályban definiált asList() tömbből listát csinál
● Algoritmusok:
○ Rendezés, összefésüléses módszerrel: sort()
○ Összekeverés: shuffle()
○ Megfordítás, feltöltés, másolás: reverse(), fill(), copy()
○ Minimum, maximum elem: min(), max()
3 . Feladatok
A +/- feladatok megoldásának .java fájljait majd a gyakorlat napján éjfélig lehet beküldeni, a kisuf (at) inf.elte.hu címre, <monogram>_bJAG-2_gy<gyakorlat száma> subjecttel. Tehát pl. az 5.
gyakorlat +/- feladatát a 2-es csoportba járó Gipsz Jakab a következő subject-tel küldené: GJ_bJAG- 2_gy5_+-.
A feladatok megoldásait a gyak5 csomagba rakjátok!
1. Készíts egy programot, amely megszámolja a parancssori argumentumokra, hogy azokban hány különböző betű van! A megvalósításhoz használj halmazt (Set<Character>, segít a
String osztály toCharArray() metódusa is)! Példa output:
> java gyak5.CharCounter asdfasd jkl asdfasd -> 4
jkl -> 3
2. Készíts egy programot, amely a parancssori argumentumaként megkapott szavakat lexikografikusan lerendezi, majd kiírja a képernyőre. A megvalósításhoz használj egy tetszőleges lista adatszerkezetet (ArrayList, LinkedList, Stack, Vector), valamint a
java.util.Collections osztály sort() függvényét! Példa output:
> java gyak5.StringSorter ad df vc y a [a, ad, df, vc, y]
3. Készíts egy programot, amely megszámolja a paraméterben az egyes karakterek előfordulásainak számát! A megvalósításhoz használj egy String → Integer leképezést (HashMap<String,Integer>)! Példa output:
> java gyak5.WordCounter aaabbcd {d=1, b=2, c=1, a=3}
4. Készítsetek egy Date osztályt, amely tartalmazza az év, hónap, nap adatokat (mind számok).
Implementáljátok vele a Comparable<Date> interfészt, és ennek megfelelően valósítsátok meg a compareTo() függvényt! Hozzatok létre kódból 3 objektumot, és tároljátok el ezeket egy tetszőleges lista adatszerkezetben. Ezt aztán rendezzétek le kronológiai sorrend szerint a Collections osztály sort() függvényével, és írjátok ki az eredményt!
3