Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
1
Programozási technológiák
Előadó: dr. Nagy Mihály PHD, főiskolai tanár Programozási technológiák 2007/2008
2
1. Az Objektumorientált programozás (OOP) főbb jellemzői
3
Objektum, osztály Objektum: Információkat tárol, és kérésre feladatokat hajt végre. Logikailag összetartozó adatok és rajtuk dolgozó algoritmusok összessége: adatok metódusok Az objektumot üzenetek (kérelmek) által lehet megkérni a feladatok elvégzésére. (Ez egy metódus végrehajtását jelenti.) Osztály (class): Objektumtípus, amely alapján példá-nyokat, azaz objektumokat hozhatunk létre.
4
Előnyök, célok A szoftverfejlesztés során az együtt változó részek elkülöníthetők Projektek közötti újrahasznosíthatóság növelése
5
Konstruktor, példánytag, osztálytag
Az objektumot létre kell hozni, és inicializálni kell. Az inicializálást végző metódust konstruktornak nevezzük. További fogalmak: példányváltozó, példánymetódus, osztályváltozó (közös változó), osztálymetódus (objektum létrehozása nélkül is tud dolgozni, csak az osztályváltozókat manipulálhatja)
6
OOP jellemzők Bezárás, az információ elrejtése: az adatokat csak interfészeken (metódusok) keresztül lehet elérni. Öröklődés: az utód osztály örökli az ős adatait, metódusait, valamint tartalmazhat újakat, és felülírhat régi metódusokat. Polimorfizmus – többalakúság: ugyanarra az üzenetre (kérelemre), azaz metódus hívásra, különböző objektumok különbözőképpen reagál-hatnak.
7
Láthatóság Az osztály deklarálásakor megadhatjuk, hogy mely adatokat lehet az objektumon kívülről elérni Nyilvános (public): kívülről elérhető Védett (protected): hozzáférés csak saját és az örökös metódusok számára Privát (private): hozzáférés csak saját metó-dusok számára
8
2. A Java nyelv
9
OO nyelvek Simula-67 Smalltalk (70’ eleje, XEROX)
Hibrid nyelvek: C++, Turbo Pascal Java: ’91-96, SUN MicroSystem
10
A Java főbb jellemzői C++-- kevesebb nyelvi eszköz, szigorúbb, kötöttebb, kevesebb hibalehetőség Hordozható kód: egy virtuális gépen (JVM, Java Virtual Machine) futó ún. bájtkód. Nincsenek implementációfüggő elemek. Rohamos fejlődés kulcsa a JVM beépítése a Web böngészőkbe. Fejleszthető: Alkalmazás (application) Applet Servlet JSP (Java Server Pages)
11
JDK (Java Development Kit)
Fejlesztői és futtató környezet (java.sun.com) Részei: API (Application Programming Interface) – osztály-könyvtár (a Java egyik ereje a rengeteg kész osztály) Fordító Értelmező Appletnéző Help, stb Újabb neve: pl. J2SE (Java 2 Platform, Standard Edition) Csomag: logikailag összetartozó osztályok. Csomag struktúra – könyvtár struktúra.
12
A Hello nevű osztály publikus, más csomagokból is látni lehet.
public class Hello{ public static void main(String[] args){ System.out.println("Hello World!"); } } A Hello nevű osztály publikus, más csomagokból is látni lehet. A main metódus a program belépési pontja. Publikus A static kulcsszó azt jelenti, hogy ez osztálymetódus void: nincs visszatérési értéke, azaz eljárás String[] args: a parancssor paraméterek A System egy osztály, amelyben található egy out objektum, melynek a println egy metódusa.
13
Kiírás, beolvasás import extra.*;
//importálni kell azon osztályokat, csomagokat, //amelyekre hivatkozunk ... int egysegar, mennyiseg, ar; //4 b. egész típus egysegar=Console.readInt("Egységár: "); mennyiseg=Console.readInt("Mennyiség: "); ar=egysegar*mennyiseg; System.out.println("Ön " + mennyiseg + " l benzint tankolt összesen " + ar + "Ft értékben"); //a System osztály a java.lang csomagban van //benne, amit nem kell importálnunk
14
Kiírás, beolvasás A Console osztály metódusai (függvényei):
int readInt() int readInt(String str) Hasonlóan: readLong, readDouble, readChar, readLine A print és println metódusoknak egyetlen paramé-terük lehet, de az többféle típusú. Ha egyszerre több dolgot is ki szeretnénk íratni, akkor ezeket össze kell adnunk. A Java automatikusan szöveggé konvertál. Pl. print("a+b=" + a + b) Pl. print("a+b=" + (a + b))
15
A program alkotóelemei
Azonosítóban betűk, számjegyek, a _ jel és a valuta szimbólumok szerepelhetnek. Számjeggyel nem kezdődhet. Akár ékezetes betűt is tartalmazhat (unikód), de ezt inkább kerüljük. Kulcsszó Literál: állandó, amely beépül a program kódjába. Lehet: egész (automatikusan int típusú, lehet hexad., decimális, oktális), valós (pl: e23), logikai (true, false), karakter (pl. '?', '\u1ac5' ), szöveg (pl. "valami"), null. Vezérlő szekvenciák: \n \t \" \' \\ pl. println("Egy idézet: \"Talpra magyar!\"")
16
Java típusok Primitív típusok: (numerikus vagy logikai)
byte 1 b short 2 b int 4 b. kb -2* *109 long 8 b. kb float 4 b. double 8 b. char 2 b. boolean Referencia típus: olyan mutató, mely egy objektum hivatkozását tartalmazza. Numerikus típusok
17
A char is numerikus típus
char c; int a; c=65; System.out.println(c); c='A'+1; a=c+1; System.out.println(a);
18
float double 4 bájt Kb. 1.4E-45 … 3.4E+38 6-7 jegy pontosság 8 bájt
19
Változó deklarálás Deklaráló utasítás
Adható kezdőérték is (inicializálás). Pl: int a, b; double x, y = 2.4;
20
Forrásprogram szerkezete
A forrásállomány (fordítási egység) egy vagy több osztályból állhat. A forrásállomány neve a main metódust tartalmazó egyetlen publikus osztály neve lesz. Fordításkor több class kiterjesztésű állo-mány keletkezhet.
21
import java.utils.*; import extra.*; //Egy vagy több osztály deklarálása, a sorrend mindegy class C1{ ... } class C2{ public class Prog{ public static void main(String[] args){
22
Operátorok Unáris postfix és prefix operátorok [ ] tömbképző
. minősítő ( ) metódus képző ~, ! bitenkénti, ill. logikai tagadás00 new példányosító (típus)kifejezés típuskényszerítő +, előjel ++, -- léptető, pl. i++ vagy ++i mindkettő növeli i értékét, de az első értéke i eredeti, míg a második i megnövelt értéke lesz.
23
++, -- int a = 0, b, c; b = ++a; a = 0; c = a++; c = ++b + a++;
c = a+++++b; c = a b;
24
Multiplikatív operátorok
*, / % maradékos osztás Ha az operandusok egészek, akkor az eredmény is egész, ha legalább az egyik operandus valós, akkor az eredmény is valós. Pl. int ossz = 2 + 3; double atlag = ossz / 2; Megj. A maradékképzés valós számokra is alkalmazható
25
Relációs operátorok (az eredmény boolean típusú lesz)
Additív operátorok +, - Relációs operátorok (az eredmény boolean típusú lesz) <, <=, >, >=,==, != Logikai operátorok ! nem &, && és (teljes, ill. rövid kiértékelésű) |, || vagy ^ kizáró vagy Bitenkénti operátorok ~ komplementálás &, |, ^ <<,>>,>>> léptetések (>>>: minden esetben 0 lép be)
26
Feltételes operátorok Értékadó operátorok
(feltétel) ? kifejezés1: kifejezés2 pl. kamat = (fiz>200000)?10:0; Értékadó operátorok =, +=, -=, *=, /=, %= … Az összetett értékadás szintaktikája: változó operátor = kifejezés a += b szemantikája: változó = (típus) változó operátor kifejezés a = a + b ahol típus a változó típusa, amelyet rákényszerí-tünk a jobboldalra.
27
Értékadó operátorok Vigyázzunk az összetett ill. a „hagyományos értékadó utasítások nem minden esetben teljesen egyformák! int a=10; a+=5; megegyezik az a=a+5 ut.-al, mindkét oldal int a+=1.5; nem egyezik meg az a=a+1.5 ut.-al, mely szintaktikai hibás, hiszen a jobb oldal double Lehetséges a többszörös értékadás, pl: a=b=5;
28
Kiértékelés Egy kifejezés kiértékelési sorrendjét meg-határozzák:
zárójel prioritás asszociativitás (balról – jobbra vagy jobbról – balra szabály)
30
Java utasítások deklaráló; pl. int a; értékadó; pl. a = b * 2;
postfix és prefix növelő és csökkentő; pl. a++; metódushívás, pl. System.out.println("Hahó!"); példányosítás, pl. auto = new Auto("ABC123"); Programvezérlő, pl. elágazások, ciklusok üres: ;
31
Java utasítások Minden utasítást pontosvessző zár le.
Blokk (vagy összetett utasítás): { ... }
32
Típuskonverziók A Java erősen típusos nyelv Típuskonverzió lehet
automatikus (implicit) kényszerített (explicit): (típus)kifejezés type cast illetve szűkítő bővítő
33
Primitív típusok esetén egy szűkebb adattípus értéke konvertálható egy bővebb adattípus értékébe információ-vesztés nélkül. Ez általában automatikus. int i; double d; byte b; short s; b + s //implicit bővítő konverzió (int) d = i; //implicit bővítő konverzió i = d; //szintaktikai hiba i = (int)d; //explicit szűkítő konv.
34
Numerikus operátorok típuskonverziói
Automatikus konverziók a következő szabályok szerint: Unáris operátorok: ha az operandus int-nél szűkebb, akkor int-é konvertál, egyébként nem konvertál Bináris operátorok: mindkét operandust a kettő közül bővebb, de minimum int-é konvertálja (Az egész literál automatikusan int, a valós literál automatikusan double)
35
Értékadó utasítás változó = kifejezés;
A kifejezés típusának értékadás szerint kompatíbilisnek kell lenni a változó típusával: azonos típusok a jobb oldal szűkebb, akkor implicit bővítő konverzió a bal oldal byte, short vagy char, a jobb oldal int, és a fordító el tudja dönteni, hogy a jobboldal belefér a baloldalba, akkor implicit szűkítő konverzió. pl. byte b = 100; (az egész literál automatikusan int típusú). minden más esetben fordítási hiba keletkezik
36
Metódushívás Osztály.metódus(paraméterek) pl. y=Math.sin(x);
Objektum.metódus(paraméterek) pl. hossz=szoveg.length(); Saját osztályból elég csak a metódus neve: metódus(paraméterek) Egy metódus lehet eljárás- vagy függvényszerű. Túlterhelés (overloading): lehet több azonos nevű metódus, melyek a paraméterezésben és/vagy a visszatérési érték típusában térhetnek el egymástól. Pl. float max(float a, float b) illetve int max(int a, int b)
37
A java.lang.Math osztály
Java API (Application Programming Interface): rengeteg csomag, osztály Nem kell importálni. Konstansok: E, PI Függvények: abs, asin, sin, cos, atan, tan, exp, log, max, min, pow, sqrt, toDegrees, toRadians, random, round…
38
Java API dokumentum részlet
static int min(int a, int b) Returns the smaller of two int values. static long min(long a, long b) Returns the smaller of two long values. static double pow(double a, double b) Returns of value of the first argument raised to the power of the second argument. random() Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
39
min public static int min(int a, int b) Returns the smaller of two int values. That is, the result the argument closer to the value of Integer.MIN_VALUE. If the arguments have the same value, the result is that same value. Parameters: a - an argument. b - another argument. Returns: the smaller of a and b. See Also: Long.MIN_VALUE
40
Szelekciók - if utasítás
if(feltétel) utasítás1; else utasítás2; feltétel: logikai kifejezés az else ág elhagyható a feltétel után nincs pontosvessző az utasítás esetén viszont van pontosvessző minden feltétel zárójelben egy ágban több utasítás: blokk {...} egymásba ágyazás if(a>b) c=a; else c=b;
41
Szelekciók - switch utasítás
switch(kifejezés){ case érték1: utasítások; break; case érték2: utasítások; break; default: utasítások; } akkor alkalmazható, ha egy kifejezés jól meghatározott, különálló értékeire szeretnénk bizonyos utasításokat végrehajtani kifejezés: byte, short, int vagy char a break hatására a switch blokk végére kerül a vezérlés, e nélkül a következő case ágra kerülne a vezérlés egy case kulcsszóhoz csak egy érték tartozhat
42
Szelekciók - switch utasítás
switch(pont){ case 1: case 2: case 3: System.out.println("Elégtelen"); System.out.println("Készüljön tovább!"); break; case 4: System.out.println("Elégséges"); case 5: System.out.println("Közepes"); case 6: System.out.println("Jó"); default: System.out.println("Jeles"); }
43
Iterációk - while utasítás
while(feltétel) utasítás; Amíg a feltétel igaz, újból végrehajtja az utasítást, ha hamis, akkor a ciklust követő utasításra lép. Több utasítás esetén: blokk { ... } Példa: Bankba tesszük a pénzünket kamatozni, és addig tartjuk bent, amíg milliomosok nem leszünk. A program számolja ki, hogy hány évet kell várnunk.
44
Iterációk - while utasítás
import extra.*; public class Milliomos1{ public static void main(String[]args){ final double KAMAT=8.5; //konstans int ev=0; int penz=Console.readInt("Összeg: "); while(penz< ){ penz*=1+KAMAT/100; //Ft-ra kerekít ev++; } System.out.println(ev+ " ev mulva leszunk milliomosok!");
45
Iterációk - do...while utasítás
do utasítás; while(feltétel) Amíg a feltétel igaz, újból végrehajtja az utasítást, ha hamis, akkor a ciklust követő utasításra lép. Több utasítás esetén: blokk { ... } Példa: Bankba tesszük a pénzünket kamatozni, és addig tartjuk bent, amíg milliomosok nem leszünk. A program számolja ki, hogy hány évet kell várnunk.
46
Iterációk - do...while utasítás
import extra.*; public class Milliomos2{ public static void main(String[]args){ final double KAMAT=8.5; //konstans int ev=0; int penz=Console.readInt("Összeg: "); do{ penz*=1+KAMAT/100; //Ft-ra kerekít ev++; }while(penz< ); System.out.println(ev " ev mulva leszunk milliomosok!"); }
47
Iterációk - for utasítás
for(inicializálás; feltétel; léptetés) utasítás; inicializálás: egy vagy több utasítás vesszővel elválasztva, mely(ek) egyszer hajtódik végre a ciklusmagba való első belépés előtt. Pl. ciklusváltozó deklarálása, inicializálása. A ciklusváltozó típusa tetszőleges. feltétel: amíg igaz, újból végrehajtja az utasítást, ha hamis, akkor a ciklust követő utasításra lép. léptetés: egy vagy több utasítás vesszővel elválasztva, mely(ek) a ciklusmag minden egyes lefutása után automatikusan végrehajtódik. Általában a ciklusváltozót szokás itt növelni vagy csökkenteni.
48
Iterációk - for utasítás
A while ciklus egy speciális esetének tekinthető: for(inicializálás; feltétel; léptetés) utasítás; inicializálás; while(feltétel){ utasítás; léptetés }
49
Iterációk - for utasítás példák
for(int i=1; i<=10; i++) System.out.print("*"); for(int i=1; i<=10; i++){ for(int j=1; j<=10; j++) System.out.print("*"); System.out.println(); }
50
for(char c='A'; c<='Z'; c++) System.out.print(c+" ");
//(c+' ') esetén a kódokat írja ki for(char n='A',k='a'; n<='Z'; n++,k++) System.out.print(n+" "+k+" "); for(double d=500000; d<= ; d*=1.1) System.out.println(d);
51
Kiugrás a ciklusból Break utasítás: az aktuális utasításblokk-ból (pl. ciklusból) való azonnali kiugrást eredményezi. Continue utasítás: hatására a vezérlés az utasításblokk (ciklus) végére kerül.
52
Metódusok írása A metódus fej szintaktikája: [módosítók] visszatérésitípus metódusneve( [paraméterlista] ) Néhány példa: public static int min(int a, int b) public void vonalhuz() public void vonalhuz(int hossz) long fakt(byte n)//csomag szintű láthatóság Módosítók lehetnek: public, private, protected: láthatóság static: osztálymetódus stb.
53
Függvény, eljárás A metódusoknak két fajtáját különböztetjük meg:
Eljárás–szerű metódus: visszatérési értékének típusa void, azaz üres típus, nem tér vissza értékkel Függvény–szerű metódus: visszatérési értéké-nek típusa valamilyen voidtól különböző típus, azaz igazi értékkel tér vissza A függvény eljárásként is hívható.
54
Metódusok jellemzői Túlterhelés (overloading): lehet két egyforma nevű, de különböző paraméterezésű metódus. pl. vonalhuz() ill. vonalhuz(int hossz) vagy min(int a, int b) ill. min(double a, double b) Paraméterátadás: érték szerinti. Az aktuális paraméter típusának értékadás szerint kompatíbilisnek kell lennie a formális paraméterrel. Visszatérés a metódusból: függvény esetén return után kötelezően meg kell adnunk egy értéket.
55
Metódusok jellemzői Az osztály metódusainak deklarálási sor-rendje tetszőleges. A main-t elsőnek vagy utolsónak célszerű megadni. A metódusok nem ágyazhatóak egymásba. Lehet rekurzív metódusokat is definiálni. A metódusban –mint egyébként is bármely blokkban– definiálhatunk lokális változót.
56
public class Metodusok{
static void vonalhuz(int hossz){ for (int i=1; i<=hossz; i++) System.out.print("-"); System.out.println(); } static void vonalhuz(){ vonalhuz(50); static int abs(int n){ if (n>=0) return n; else return -n;
57
public static void main(String[] args){ int a=-10; int b=12345678;
static int jegySzam(int n){ int jszam=0; do{ n/=10; jszam++; }while(n!=0); return jszam; } public static void main(String[] args){ int a=-10; int b= ; vonalhuz(); System.out.println(a+" abszolut erteke: "+abs(a)); vonalhuz(40); System.out.println(b+" jegyeinek szama: "+jegySzam(b));
58
Osztály készítése
59
OO program vezérlő objektum üzenet3 objektum3 fut üzenet1 üzenet2
Egy objektumorientált program egymással kommunikáló objektumok összessége, melyben minden objektumnak megvan a feladatköre vezérlő objektum üzenet3 objektum3 fut üzenet1 üzenet2 objektum1 objektum2 üzenet1
60
Példa - Ember osztály és példányai
pozíció(x,y) iránySzög megy(táv) elmegy(x,y) fordul(szög) Ember zsófi andor kati
61
Az OOP fontosabb definícióinak összefoglalása
Példánydeklaráció (példánytag): A példányonként (objektumonként) helyet foglaló változók a példányváltozók (példányadatok). Azon metódusokat, melyek példányadatokon dolgoznak, példánymetódusoknak nevezzük. Osztálydeklaráció (osztálytag) (static) Az osztályváltozó az osztály saját változója, az egyes példányokban nem szerepel, valamilyen közös adatot tárol. Az osztálymetódus az osztály saját metódusa, amely csak osztályváltozókon dolgozik.
62
Láthatóság Privát (private): csak az osztály saját metódusai fér-hetnek hozzá. Nyilvános (public): minden, az objektummal kapcsolat-ban álló kliens eléri, használhatja. Egy osztály adatai általában privát adatok. Egy fordítási egység (java fájl) több osztályt is tartalmaz-hat, de közülük csak egy lehet nyilvános (public). Ha valamelyik osztályban szerepel a main metódus, akkor az nyilvános kell hogy legyen.
63
A deklarálás sorrendje általában:
Egy osztályban ugyanazon a néven dekla-rálható metódus és változó, sőt a metódu-sok túlterhelhetőek. A deklarálás sorrendje általában: változók konstruktorok metódusok main metódus, ha van.
64
A lokális változók eltakarják az ugyanolyan nevű osztály-, illetve példányváltozókat.
Ha az osztály deklarációjára szeretnénk hivat-kozni, akkor osztályváltozó esetén az osztály nevével, példányváltozó esetén pedig a this referenciával kell azt minősítenünk. Változók alapértelmezés szerinti kezdeti értékei: osztályváltozó vagy példányváltozó esetén 0, lokális változó esetén határozatlan.
65
Konstruktorok Feladata az objektum new operátorral való létrehozásakor annak inicializálása. Auto auto = new Auto("GHJ123”); A konstruktor speciális metódus, a következő szabályok érvényesek rá: Neve kötelezően megegyezik az osztály nevével. Csak a new operátorral hívható. Túlterhelhető. Nincs visszatérési értéke, és nem is void. Ha az osztályban nem adunk meg explicit módon konstruktort, akkor az osztálynak lesz egy alapértelmezés szerinti (default), paraméter nélküli konstruktora. Ha az osztályban létezik egy explicit konstruktor, akkor nem lesz implicit, alapértelmezés szerinti konstruktora.
66
Példa - Raktárprogam Adott egy zöldségraktár, melyben pillanatnyilag egyetlen árut, paradicsomot raktározunk. A raktárba gyakran te-szünk be, illetve veszünk ki onnan paradicsomot. A para-dicsom pillanatnyi egységára 300 Ft, de ez változhat. Készítsünk olyan programot, mely segítségével rögzíteni tudjuk a megfelelő adatokat, és bármikor jelentést tudunk adni a paradicsom aktuális mennyiségéről, egységáráról és értékéről! Végezzük el a következő akciókat: Tegyünk a raktárba 125 kg paradicsomot, aztán vegyünk ki 25 kg-ot, majd szállítsuk le a paradicsom egységárát 210 Ft-ra! Mindhárom akció után írjuk ki, mennyi paradicsom van raktáron és milyen értékben!
67
Osztálydiagram Aru -nev: String -egysegar: double -menny: double
RaktarProgram +Aru(aNev:String,aEgysegar:double) +getNev(): String +getEgysegar(): double +setEgysegar(aEgysegar:double) +getMenny(): double +getAr(): double +hozzatesz(aMenny:double) +elvesz(aMenny:double) +toString(): String -aru +RaktarProgram() +akciok() +main(args)
68
Osztálydiagram Aru -nev: String -egysegar: double -menny: double
RaktarProgram +Aru(aNev:String,aEgysegar:double) +getNev(): String +getEgysegar(): double +setEgysegar(aEgysegar:double) +getMenny(): double +getAr(): double +hozzatesz(aMenny:double) +elvesz(aMenny:double) +toString(): String -aru +RaktarProgram() +akciok() +main(args)
69
Példányváltozók Konstruktor class Aru { private String nev;
private double egysegar; private double menny; public Aru(String aNev, double aEgysegar) { nev = aNev; egysegar = aEgysegar; menny = 0; } public String getNev() { return nev; Példányváltozók Konstruktor Osztálydiagram
70
public double getEgysegar() { return egysegar; }
public void setEgysegar(double aEgysegar) { if (aEgysegar >= 0) egysegar = aEgysegar; public double getMenny() { return menny; public double getAr() { return menny*egysegar; Osztálydiagram
71
public void hozzatesz(double aMenny) { if (aMenny>0)
menny += aMenny; } public void elvesz(double aMenny) { if (aMenny>0 && aMenny<=menny) menny -= aMenny; public String toString() { return nev+"\tEgysegar: "+egysegar+ "\tMenny: "+menny+"\tAr: "+getAr(); Osztálydiagram
72
Objektum létrehozása saját osztályából
public class RaktarProgram { private Aru aru; public RaktarProgram() { aru = new Aru("Paradicsom",300); } public void akciok() { aru.hozzatesz(125); System.out.println(aru); aru.elvesz(25); aru.setEgysegar(210); public static void main(String[] args) { RaktarProgram program = new RaktarProgram(); program.akciok(); Kapcsolat Objektum létrehozása saját osztályából Objek Osztálydiagram
73
7: setEgysegar(aEgysegar)
Együttműködési diagram 3: Aru(aNev,aEgysegar) 5: hozzatesz(aMenny) 6: elvesz(aMenny) 7: setEgysegar(aEgysegar) 1: main(args) 2: RaktarProgram() 4: akciok() RaktarProgram program: RaktarProgram aru:Aru
74
Készítsünk egy banki programot, mely az ügyfelek számláit kezeli.
Példa – Bankprogam Készítsünk egy banki programot, mely az ügyfelek számláit kezeli. Osztálydiagram Szamla -utolsoSzamlaSzam: int -szamlaSzam: int -tulajdonos: String -egyenleg: int Bank -szamla1 -szamla2 +Bank() +ugyfelKiszolgalas (szamla:Szamla) +menu() +main(args) +Szamla(tulajdonos:String,egyenleg:int) +Szamla(tulajdonos:String) +getTulajdonos(): String +setTulajdonos(Tulajdonos:String) +befizet(osszeg:int) +kivesz(osszeg:int): int +toString(): String
75
import extra.*; class Szamla{ private static int utolsoSzamlaSzam=0; private int szamlaSzam; private String tulajdonos; private int egyenleg; public Szamla(String tulajdonos, int egyenleg){ szamlaSzam=++utolsoSzamlaSzam; this.tulajdonos=tulajdonos; this.egyenleg=egyenleg; } public Szamla(String tulajdonos){ this(tulajdonos,0); public String getTulajdonos(){ return tulajdonos;
76
this.tulajdonos=tulajdonos; } public void befizet(int osszeg){
public void setTulajdonos(String tulajdonos){ this.tulajdonos=tulajdonos; } public void befizet(int osszeg){ if(osszeg>=0) egyenleg+=osszeg; public int kivesz(int osszeg){ if(osszeg>=0 && osszeg<=egyenleg) egyenleg-=osszeg; return egyenleg; public String toString() { return "Szamlaszam: "+szamlaSzam+" Tulajd.: "+tulajdonos+ " Egyenleg: "+egyenleg; }//Számla osztály vége
77
public class Bank { private Szamla szamla1, szamla2; public Bank() { szamla1 = new Szamla("Kiss Istvan", ); szamla2 = new Szamla("Nagy Peter"); } public void ugyfelKiszolgalas(Szamla szamla) { char valasz; do{ valasz=Character.toUpperCase(Console.readChar("B(efizet)/K(ivesz)")); }while(valasz!='B' && valasz!='K'); if (valasz == 'B') szamla.befizet(Console.readInt("Mennyit fizet be? ")); else{ int egyenleg = szamla.kivesz(Console.readInt("Mennyit vesz ki? ")); System.out.println("Maradek egyenleg "+egyenleg+" Ft");
78
System.out.println("\n\n"+szamla1); System.out.println(szamla2);
public void menu() { char valasz; do{ System.out.println("\n\n"+szamla1); System.out.println(szamla2); System.out.println("\n1: 1. ugyfel kiszolgalasa"); System.out.println("2: 2. ugyfel kiszolgalasa"); System.out.print ("V: Vege "); valasz = Character.toUpperCase(Console.readChar()); switch (valasz) { case '1': ugyfelKiszolgalas(szamla1); break; case '2': ugyfelKiszolgalas(szamla2); break; } }while (valasz!='V'); public static void main(String[] args) { Bank otp = new Bank(); otp.menu(); }//Bank osztály vége
79
Inicializálók class Tanulo { static int alapTandij; double atlag;
int tandij; static { alapTandij = 2000; } { atlag = Console.readDouble("Atlag: "); tandij = alapTandij + (int)Math.round(3000*(5-atlag)); // … = 2000; = Console.readDouble("Atlag: ");
80
Az inicializálás sorrendje
Osztályadatok (osztály betöltésekor) alapértelmezés szerinti értékek osztályinicializáló kifejezések osztályinicializáló blokkok Objektum adatai (objektum születésekor) alapértelmezés szerinti értékek példányinicializáló kifejezések példányinicializáló blokkok konstruktor(ok)
81
Az Object osztály Minden osztály közös őse
A Java minden objektumára jellemző metódusokat tartalmaz. Például: boolean equals(Object obj) String toString() Class getClass()
82
Objektumok egyenlőségvizsgálata
String s1 = new String("Hello"), s2 = new String( "Hello"); System.out.println(s1==s2); System.out.println(s1.equals(s2)); false true
83
Karakterlánc A String osztályú objektum olyan szöveg tárolására szolgál, amelynek értékét nem akarjuk megváltoztatni. A StringBuffer osztályt akkor használjuk, ha a szövegen szeretnénk változtatni. A StringBuilder osztályt a JDK 5.0-tól vezették be, ami gyorsabb, mint a StringBuffer, de csak egy szálon használható biztonságosan.
84
Objektum létrehozása a new operátorral
Auto auto; //csak referencia auto = new Auto("GHJ123”); //a konstruktor hívásával létrejön az objektum, //az auto referencia erre mutat vagy Auto auto = new Auto("GHJ123”); Osztályazonosító objektum = new Osztályazonosító(paraméterlista);
85
String objektum létrehozása
String szoveg; //csak referencia szoveg = new String(”Ez a tartalma”); csak String esetén ez egyszerűsíthető: szoveg=”Ez a tartalma”;
86
A String osztály metódusai
Az eredeti objektumot nem változtatják, függvények, sokszor új String objektumot hoznak létre. Néhány metódus: char charAt(int index) tetszőleges indexű karakterét adja vissza, az indexelés 0-val kezdődik int compareTo(String str) összehasonlítja, értéke 0, ha egyenlő; –, ha kisebb; +, ha nagyobb, mint a paraméter
87
boolean equals(Object anObject)
igaz, ha az objektum String típusú, s karakterei ugyanazok int indexOf(String str) //hasonlóan lastIndexOf az adott sztring első előfordulásának pozíciója lesz az értéke, ha nincs benne, akkor érték –1 int indexOf(String str, int fromIndex) az adott sztring első előfordulásának pozíciója lesz az értéke, a keresést a második paraméterben megadott sorszámú karak-tertől kezdi, ha nincs benne, akkor az érték –1 int length() hosszát adja vissza
88
String replace(char oldChar, char newChar)
kicseréli a megadott karaktereket, s visszaadja az új sztringet (maga a sztring objektum nem változik meg) String substring(int beginIndex) a paraméterben megadott pozíciótól a szöveg végéig kimásol String substring(int beginIndex, int endIndex) a kezdő pozíciótól a végpozícióig kimásol, endIndex nem tartozik bele a részláncba, így a visszaadott sztring hossza endIndex- beginIndex String toLowerCase() kisbetűsre alakítottan adja vissza String toUpperCase() nagybetűsre alakítottan adja vissza
89
String trim() levágja a fehér szóközöket (space, tab, sorvégejel) az elejéről és végéről, s visszaadja Stb. Ezek példánymetódusok, hívásuk: objektumnév.metódusnév([paraméterlista]) pl: int hossz = szoveg.length(); Sztringet bekérni a billentyűzetről az extra csomagbeli Console osztály readLine() metódusával lehet. pl: String nev = Console.readLine("A neved: ");
90
1. példa String s = Console.readLine(); for(int i=s.length()-1; i>=0; i--) System.out.print(s.charAt(i)); System.out.println(); System.out.println(s.toUpperCase()); System.out.println(s.toLowerCase()); if(s.length()>=9) System.out.println(s.substring(0,9)); if(s.length()>=3) System.out.println(s.substring(s.length()-3)); System.out.println(s.replace(' ','-'));
91
2. példa String s=Console.readLine(); String elso=s; while(!s.equals("*")){ if(s.compareTo(elso)<0) elso=s; s=Console.readLine(); } System.out.println(elso);
92
StringBuffer osztály Konstruktorok Kapacitás, hossz, index
StringBuffer(int length) StringBuffer(String str) Kapacitás, hossz, index capacity():int length():int ensureCapacity(int minimumCapacity) setLength(int newLength) charAt(int index): char Manipulálható szöveg
93
StringBuffer osztály (folyt.)
Bővítés append (<Type> value): StringBuffer append (<type> value): StringBuffer insert (int offset, <Type> value): StringBuffer insert (int offset, <type> value): StringBuffer Törlés deleteCharAt(int index): StringBuffer delete(int start, int end): StringBuffer
94
StringBuffer osztály (folyt.)
Egyéb setCharAt(int index, char ch) replace(int start, int end, String str): StringBuffer reverse(): StringBuffer substring(int start): String substring(int start, int end): String toString(): String
95
StringBuffer hegy1 = new StringBuffer("Machu"); //1
StringBuffer hegy2 = hegy1.append(" Picchu"); //2 hegy2.insert(0,"Ez is "); //3 //1 //2 :StringBuffer "Machu" hegy1 :StringBuffer "Machu Picchu" hegy1 hegy2 //3 hegy1 :StringBuffer "Ez is Machu Picchu" hegy2
96
public static void main(String[] args) { // következő dián }
Feladat – Csere Olvassunk be egy szöveget, majd cseréljük ki az összes & jelet az and szóra! import extra.*; public class Csere { public static void main(String[] args) { // következő dián }
97
StringBuffer szoveg = new StringBuffer(Console.readLine("Szoveg: ")); //1 int poz = szoveg.toString().indexOf('&'); //2 while (poz!=-1) { szoveg.replace(poz,poz+1,"and"); //3 poz = szoveg.toString().indexOf('&'); //4 } System.out.println(szoveg); //5
98
Objektum átadása paraméterként
Feladat – Objektum paraméter Írjunk egy olyan eljárást, amely a paraméterként megkapott szöveget széthúzza, vagyis minden karaktere után beszúr egy szóközt! import extra.*; public class ObjektumParameter { //következő dián }
99
Értékadás szerinti kompatibilitás!
static void szethuz(StringBuffer str) { for (int i=str.length()-1; i>0; i--) str.insert(i,' '); str = null; // csak demonstrációs célú utasítás } public static void main(String[] args) { StringBuffer sb = new StringBuffer("Peace"); szethuz(sb); System.out.println("*"+sb+"*"); // "*P e a c e*" Értékadás szerinti kompatibilitás! Csak a referencia másolódik át!
100
A metódusba való belépéskor: A metódusból való kilépés előtt:
null str str :StringBuffer "Peace" :StringBuffer "P e a c e" sb sb A metódus csak a mutatott objektumot változtathatja meg, a referenciát nem!
101
Tömbök A tömb referencia típusú változó, melyet deklarál-nunk kell. Az elemtípus lehet akár primitív, akár referencia (osztály típusú vagy tömb típusú). Deklarálás: elemtípus [] tömbazonosító; vagy elemtípus tömbazonosító []; pl: int [] a; //inkább ez ajánlott int b[];
102
Létrehozás (futás közben):
Az így deklarált változó képes egy, a megadott elemtípusú tömbre mutatni. Még csak a referenciának (memóriacímnek) foglaltunk helyet, a tömböt külön létre kell hoznunk. Létrehozás (futás közben): new elemtípus [méret] pl: a = new int[10]; b = new int[20]; Természetesen történhet rögtön a deklaráláskor is a létrehozás: String[] sTomb = new String[50];
103
Minden tömbnek van egy length konstansa.
Indexelés: 0 .. length-1 int[] iArray=new int[10]; for(int i=0; i<iArray.length; i++) iArray[i]=Console.readInt(i+1+". szam: "); System.out.println("Az elemek visszafele:"); for(int i=iArray.length-1; i>=0; i--) System.out.print(iArray[i]+" "); for(int i=0; i<10; i++)
104
Tömb inicializálása Inicializáló blokk: deklaráláskor a tömb elemeinek kezdeti értékek adhatók, pl: int[] iArray={2, 4, 6, 8, 10}; char[] szamjegyek={'0','1','2','3','4','5','6','7','8','9'} Ekkor nem kell a tömböt a new operátorral létrehozni, a {} blokk képző operátor megteszi ezt helyettünk. A tömb mérete pontosan akkora lesz, amennyi a felsorolt értékek száma.
105
Értékadás tömbök között
A t2 tömb értékadás szerint kompatibilis a t1 tömbbel (azaz t1=t2 megengedett), ha primitív elemtípus esetén t1 és t2 elemtípusa azonos; referencia elemtípus esetén t2 elemtípusa t1 elem-típusával azonos, vagy annak leszármazottja. Értékadáskor a tömb referenciája kap értéket, nem pedig az elemei (a tömb nem másolódik, hanem átíródik a mutatója), így különböző hosz-szúságú tömbök is értékül adhatók egymásnak.
106
Kétdimenziós tömb Deklarálás: elemtípus [][] tömbazonosító;
Teljes kétdimenziós tömb létrehozása: new elemtípus [méret0] [méret1] Pl: int[][] matrix Lépésenkénti (soronkénti) létrehozás. A sorok különböző méretűek lehetnek, pl: double[][] atlagok = new double[4][]; atlagok[0] = new double[20]; atlagok[1] = new double[18]; atlagok[2] = new double[25]; atlagok[3] = new double[22]; Analóg a helyzet a többdimenziós tömbök esetén. = new int[3][4];
107
Tömb paraméter Formális paraméterként egy tömbreferenciát kell deklarálnunk, amely fogadja az aktuális tömb referenciáját. Az aktuális tömbnek értékadás szerint kompatíbi-lisnek kell lennie a formális tömbbel. Példa: Írjunk osztályt, amelynek adata egy int tömb. Az objektum létrehozásakor a konstruktor paraméterében adhassuk meg a tömb hosszát. Tartalmazzon egy bekér, kiir és egy osszeg nevű metódust!
108
import extra.*; class Tomb{ private int[]t; public Tomb(int hossz){ t = new int[hossz]; } public void beker(){ for(int i=0; i<t.length; i++) t[i] = Console.readInt(i+1+". szam: "); public void kiir(){ for(int i=0;i<t.length;i++) System.out.print(t[i]+" "); System.out.println(); public int osszeg(){ int s=0; for(int i=0;i<t.length;i++) s+=t[i]; return s; }//Tomb
109
public class Tombok{ public static void main(String[] args){ Tomb t1=new Tomb(5); Tomb t2=new Tomb(7); System.out.println("Adja meg az 1. tomb elemeit (5):"); t1.beker(); System.out.println("Adja meg a 2. tomb elemeit (7):"); t2.beker(); System.out.println("Az elso tomb:"); t1.kiir(); System.out.println("Az elemek osszege: "+ t1.osszeg()); System.out.println("A masodik tomb:"); t2.kiir(); }
110
Öröklődés
111
Java: class Auto extends Jarmu{ ... }
Öröklődés (inheritance) más néven kiterjesztés (extension): Egy már meglévő osztály továbbfejlesztése. Újabb tulajdonságokat és metódusokat adhatunk hozzá Meglévő metódusait átírhatjuk Cél: Specializáció: egy objektum leírásához egyedi jellemzőket adunk hozzá. Általánosítás: több objektum leírásából kiemeljük a közös jellemzőket. Java: class Auto extends Jarmu{ }
112
Szabályok Egy osztályból több osztály is származtatható
Egy osztályhierarchia mélysége elvileg tetszőleges lehet Az öröklés tranzitív Jávában: Egy osztálynak csak egy közvetlen őse lehet (nincs többszörös öröklés) Minden osztálynak őse az object
113
Mintafeladat Különböző hengereket szeretnénk nyilvántartani:
Csupán mértani testek, sugaruk és magasságuk van Tömör hengerek, súlyuk is van Csövek
114
Henger -sugar, magassag:double Cso +Henger(sugar, magassag:double) +getSugar():double +getMagassag():double +terfogat():double +toString():String -falVastagsag:double +Cso(sugar, magassag, fajsuly, falVastagsag:double) +getFalVastagsag():double +terfogat():double +toString():String TomorHenger -fajsuly:double +TomorHenger(sugar, magassag, fajsuly:double) +getFajsuly():double +suly():double +toString():String
115
Megjegyzések a példaprogramhoz
Az Object osztály getClass() metódusa egy Class osztályú objektumot ad vissza, melynek getName() metódusát használtuk (Henger: 22. sor) this: az objektum referenciája super: az objektum referenciája, de közvetlen ősosztály típusú A hengerek tömb elemei Henger osztályú referenciák, melyek azonosíthatnak leszármaztatott osztályú objektumokat is. Henger h; TomorHenger th; h=th; //jó th=h; //típushiba th=(TomorHenger)h //típuskényszerítés A lista és az átlagtérfogat műveleteknél az objektumok valódi típusa határozza meg, hogy melyik toString(), ill terfogat() metódus fog végrehajtódni: polimorfizmus (ld. 6. dia)
116
instanceof operátor: <objektum> instanceof <osztály> Eredménye egy boolean típusú érték, mely true, ha az objektum osztálya a megadott osztály vagy annak leszármazottja. Statikus típus: amit a referencia deklaráláskor kap Dinamikus típus: amilyen osztályú objektumot valójában azonosít hengerek[3]=new Cso(2,10,2,1); hengerek[3] statikus típusa Henger, dinamikus típusa Cso. Egy utódosztály akkor is örökli az ősosztály adatait, ha nem látja azokat (mert private elérhetőségűek)
117
Metódusok felülírása Akkor van szó felülírásról, ha a metódusok szignatúrái megegyeznek (egyébként túlterhelés) Csak példánymetódust lehet felülírni Nem lehet felülírni, ha final Dinamikus kötés (futás alatti kötés, késői kötés): Az osztályhierarchia bármely pontjáról is hívunk meg egy példánymetódust, minden esetben a megszólított objektum osztályában (vagy ha ott nincs, akkor a legközelebbi ősben) deklarált metódus fog végrehajtódni. A pontos címet a rendszer futáskor határozza meg. (Pl. TomorHenger, ill. Cso osztályú objektumok esetén a suly metódus meghívásakor más-más terfogat metódus hajtódik végre.)
118
Konstruktorok Nem öröklődik, nem lehet felülírni
Osztályon belül az egyik konstruktorból a másik így hívható: this(paraméterek) Egy konstruktorból a közvetlen ős konstruktor így hívható: super(paraméterek) Minden konstruktornak tartalmaznia kell pontosan egy this() vagy super() hívást legelső utasításként. Ha egyik sem szerepel, akkor a fordító betesz egy alapértelmezett paraméter nélküli super() hívást. Ekkor viszont lennie kell a közvetlen ősosztályban paraméter nélküli konstruktor. Elv: minden konstruktor a saját osztálya adatait inicializálja
119
Absztrakt metódus, absztrakt osztály
Az osztály egyes metódusait nem implementáljuk, csak a fejlécét adjuk meg. Az ilyen osztály absztrakt, a nyitva hagyott, absztrakt metódusokat tartalmaz Örökítési célokat szolgál, nem példányosítható Absztrakt metódust tartalmazó osztály csak absztrakt lehet
120
Idom {abstract} -fajsuly:double=0.8 +terfogat():double +suly():double Gomb Hasab -sugar:double -a,b,magassag:double +Gomb(sugar:double) +terfogat():double +toString():String +Hasab(a,b,magassag:double) +terfogat():double +toString():String
121
Interfész Az interfész olyan viselkedéseket definiál, amelyet az osztályhierarchia tetszőleges osztályával megvalósíthatunk. Az interfész (interface) metódusfejeket definiál abból a célból, hogy valamely osztály azt a későbbiekben implementálja, megvalósítsa. Definiálhat konstansokat (public static final) Az objektum elérésének, használatának egy lehetséges módját határozza meg. Egy interfészből nem lehet példányt létrehozni Az interfészek örökíthetők Egy konkrét osztály megvalósítja az interfészt, ha az összes metódusát megvalósítja (UML szaggatott nyíl, java kulcsszó: implements) Konvenció: az implements záradék az extends záradékot követi, ha mindkettő van.
122
Egy osztály több interfészt is implementálhat
Az értékadás kompatibilitás hasonló, mint az öröklődés esetén Mivel az interfész a megvalósítás nélküli, vagyis absztrakt metódusok listája, alig különbözik az absztrakt osztálytól. A különbségek: Az interfész egyetlen metódust sem implementálhat, az absztrakt osztály igen. Az osztály megvalósíthat több interfészt, de csak egy ősosztálya lehet. Az interfész nem része az osztályhierarchiának. Egymástól "független" osztályok is megvalósíthatják ugyanazt az interfészt. Amikor egy osztály megvalósít egy interfészt, akkor alapvetően aláír egy szerződést. Az osztálynak implementálni kell az interfészben és szülőinterfészeiben deklarált összes metódust, vagy az osztályt absztraktként kell deklarálni.
123
Az interfészek hasznosak a következő esetekben:
Hasonlóságok megfogalmazása anélkül, hogy mesterkélt osztályhierarchiát építenénk fel (For instance, a human and a parrot can both whistle, however it would not make sense to represent Humans and Parrots as subclasses of a Whistler class, rather they would most likely be subclasses of an Animal class (likely with intermediate classes), but would both implement the Whistler interface.) Olyan metódusok definiálása, amelyeket több osztályban meg kell valósítani Többszörös öröklődés modellezése
124
public interface Predator {
public boolean chasePrey(Prey p); public void eatPrey(Prey p); } public class Cat implements Predator { public boolean chasePrey(Prey p) { // programming to chase prey p public void eatPrey (Prey p) { // programming to eat prey p
125
Another use of interfaces is being able to use an object without knowing its type of class, but rather only that it implements a certain interface. (For example, a sorting algorithm may expect an object of type Comparable. Thus, it knows that the object's type can somehow be sorted, but it is irrelevant what the type of the object is.)
126
A String hasonlítható Comparable interfész «interfész» Comparable
Object +compareTo(Object obj): int String +compareTo(Object obj): int ...
127
class Henger implements Comparable<Henger>{
private double sugar, magassag; ... public int compareTo(Henger obj){ if(terfogat()<obj.terfogat()) return -1; if (terfogat()>obj.terfogat()) return 1; return 0; }
128
import java.util.*; public class HengerProgram { public static void main(String[] args) { Henger[] hengerek=new Henger[4]; ... //Max térfogat int max=0; for(int i=0;i<hengerek.length;i++) if(hengerek[i].compareTo(hengerek[max])>0) max=i; System.out.println("A legnagyobb térfogat: " hengerek[max].terfogat()); //Rendezés Arrays.sort(hengerek); //Lista System.out.println("\nRendezve:"); System.out.println(hengerek[i]); }
129
A kollekció keretrendszer – Java Collections Framework (JCF)
A kollekciók (konténerek) olyan objektumok, melyek célja egy vagy több típusba tartozó objektumok memóriában történő összefoglaló jellegű tárolása, manipulálása és lekérdezése. A kollekció keretrendszer egy egységes architektúra, ami a kollekciók megvalósítására, kezelésére szolgál. Elemei: Interfészek: absztrakt adattípusok, amelyek a kollekciókat reprezentálják. Lehetővé teszik a kollekciók implementáció független kezelését. Implementációk: a kollekció interfészek konkrét implementációi. algoritmusok: azok a metódusok, amelyek hasznos műveleteket valósítanak meg, mint például keresés, rendezés különböző kollekciókon. C++ Standard Template Library (STL)
130
A kollekció keretrendszer használatának előnyei
Csökkenti a fejlesztési időt Növeli a program sebességét és minőségét Megkönnyítik az API-k használatát, tervezését Elősegíti a szoftver újrafelhasználhatóságát
131
Interfészek
132
A kollekció interfészek (generic, általános) típus paraméterekkel dolgoznak. Például:
public interface Collection<E> ... Az <E> szintaxis azt jelenti, hogy az interfész általános (generikus) típussal működik. Amikor deklarálunk egy Collection-t, meg tudjuk határozni (ajánlott), hogy milyen típusú objektumot tartalmaz a kollekció. A típus paraméter a fordítóprogram számára lehetővé teszi, hogy csak az adott típusú objektumot engedje belerakni a kollekcióba, így csökkenti a futásidejű hibák számát. Ha megértettük az interfészek használatát, akkor a nagy részét megtudtuk annak, amit a JCF-ről tudni érdemes.
133
Collection: akkor érdemes ezt választani, ha a lehető legnagyobb rugalmasságra van szükség.
Set: matematikai halmaz modellezése List: sorszámozott kollekció, hozzáférés az elemekhez index segítségével Queue: várakozási sor létrehozására Map: az egyedi kulcsokat értékekké képezi le. SortedSet SortedMap
134
Általános célú implementációk
135
A Collection interfész
Használható például különböző kollekciók közötti konverzióra (mint közös nevező) All collection implementations have a constructor that takes a Collection argument. Suppose, for example, that you have a Collection<String> c, which may be a List, a Set, or another kind of Collection. This idiom creates a new ArrayList (an implementation of the List interface), initially containing all the elements in c. List<String> list = new ArrayList<String>(c);
136
public interface Collection<E> extends Iterable<E> {
// Basic operations int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optional boolean remove(Object element); //optional Iterator<E> iterator(); // Bulk operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); //optional boolean removeAll(Collection<?> c); //optional boolean retainAll(Collection<?> c); //optional void clear(); //optional // Array operations Object[] toArray(); <T> T[] toArray(T[] a); }
137
import java.util.*; public class HengerProgram { public static void main(String[] args) { Collection<Henger> hengerek= new ArrayList<Henger>(); hengerek.add(new Henger(2,10)); hengerek.add(new Henger(3,6)); hengerek.add(new TomorHenger(2,10,2)); hengerek.add(new Cso(2,10,2,1)); System.out.println(hengerek.size()); hengerek.clear(); }
138
import java.util.*; public class CollectionAddDemo { public static void main(String[] args) { Collection<Integer> szamok=new HashSet<Integer>(); int n=0; do{ if(szamok.add(Math.round((float)Math.random()*89)+1)) n++; }while(n<5); System.out.println(szamok); }
139
import java.util.*; class Diak{ private String nev; private int pont; public Diak(String nev, int pont){ this.nev=nev; this.pont=pont; } public int getPont(){ return pont; } public boolean equals(Object obj){ return nev.equals(((Diak)obj).nev); public String toString(){ return nev+": "+pont; } public class Diakok{ public static void main(String[]args){ Collection<Diak> diakok=new ArrayList<Diak>(); diakok.add(new Diak("Kovács István",10)); diakok.add(new Diak("Kiss Péter",2)); diakok.add(new Diak("Nagy Pál",10)); Diak diak=new Diak("Kiss Péter",0); System.out.println(diakok.contains(diak));
140
A kollekciók bejárása 1. A „for-each” ciklussal
for (Object o : collection) System.out.println(o); for(Henger henger:hengerek) System.out.println(henger.terfogat()); 2. Iterátorral Az iterátor egy olyan objektum, ami megengedi, hogy bejárjuk a kollekciót, és eltávolítsuk az elemeket a kollekcióból, ha akarjuk. Egy kollekció bejárásához az iterator metódusának a meghívásával kérhetünk egy Iterator objektumot.
141
Az Iterator interfész:
public interface Iterator<E> { boolean hasNext(); E next(); void remove(); } A hasNext metódus visszatérési értéke true, ha az iterációnak van még be nem járt eleme. A remove metódus eltávolítja a kollekcióból az utolsó elemet, amit a next hívására kaptunk. Az Iterator.remove az egyetlen biztonságos út, hogy módosítsuk a kollekciót az iteráció folyamán. Iterátor használata célszerű a for-each ciklus helyett a következő esetekben: Törölni szeretnénk a bejárás közben. Párhuzamosan több kollekciót szeretnénk bejárni
142
for (Iterator<Henger> it=hengerek. iterator(); it
for (Iterator<Henger> it=hengerek.iterator(); it.hasNext(); ) System.out.println(it.next()); for (Iterator<Henger> it=hengerek.iterator(); it.hasNext(); ) if (it.next().terfogat()<100) it.remove();
143
Collection Interface Bulk Operations
Az egész kollekcióval hajtanak végre műveleteket. containsAll – megmondja, hogy a kollekció tartalmazza-e a paraméterben megadott kollekció összes elemét addAll – hozzáadja a kollekcióhoz a paraméterben megadott kollekció összes elemét removeAll – eltávolítja a kollekcióból a paraméterben megadott kollekció összes elemét retainAll – eltávolítja a kollekcióból azokat az elemeket, amelyek a paraméterben megadott kollekcióban nincsenek benne clear – eltávolítja a kollekció összes elemét Pl: c.removeAll(Collections.singleton(e)); c.removeAll(Collections.singleton(null)); Collections.singleton(e): egy halmazzal tér vissza, mely csak a megadott elemet tartalmazza.
144
A Set interfész Set egy speciális Collection, amely nem tartalmaz ismétlődő elemeket. A Set csak a Collection-tól örökölt metódusokat tartalmazza, azzal a megszorítással kiegészítve, hogy nem engedi meg az elemek ismétlődését. public interface Set<E> extends Collection<E> { // Basic operations int size(); boolean isEmpty(); ... }
145
A Java platform három általános célú Set implementációt tartalmaz: a HashSet, TreeSet, és LinkedHashSet. HashSet esetén az elemeket egy hash táblában (hasítótáblában) tárolja, ez a legjobb választás, ha a bejárás sorrendje nem fontos. A TreeSet az elemeket egy fában tárolja az értékük szerint rendezetten. Lényegesen lassabb, mint a HashSet. A LinkedHashSet ötvözi a láncolt listát a hash táblával. Beszúrás szerinti rendezettség.
146
import java.util.*; public class SetDemo { public static void main(String[] args) { Collection<Integer> szamok=new ArrayList<Integer>(); for(int i=0;i<50;i++) szamok.add(Math.round((float)Math.random()*99)+1); for(Integer iobj:szamok) System.out.print(iobj+" "); System.out.println(); Set<Integer> szamokh=new HashSet<Integer>(szamok); for(Integer iobj:szamokh) }
147
public class FindDups { public static void main(String[] args) {
import java.util.*; public class FindDups { public static void main(String[] args) { String[] words={"i", "came", "i", "saw", "i", "left"}; Set<String> h = new HashSet<String>(); for (String s : words) if (!h.add(s)) System.out.println("Duplicate detected: " + s); System.out.println(h.size() + " distinct words: " + h); } String w="i came i saw i left"; String s; Set<String> h = new HashSet<String>(); for(StringTokenizer st=new StringTokenizer(w);st.hasMoreTokens();) if (!h.add(s=st.nextToken())) System.out.println("Duplicate detected: " + s); System.out.println(h.size() + " distinct words: " + h); Note that the code always refers to the Collection by its interface type (Set) rather than by its implementation type (HashSet). This is a strongly recommended programming practice because it gives you the flexibility to change implementations merely by changing the constructor.
148
Set Interface Bulk Operations
Egyszerűen megvalósíthatók az algebrából ismert halmazműveletek. s1.containsAll(s2) – Igaz logikai értékkel tér vissza, ha s2 részhalmaza s1-nek s1.addAll(s2) – Az s1-be s1 és s2 uniója kerül. s1.removeAll(s2) – Az s1-be s1 és s2 különbség kerül. s1.retainAll(s2) – Az s1-be s1 és s2 metszete kerül. clear – eltávolítja a kollekció összes elemét Feladatok: 1. Módosítsuk a FindDups programot úgy, hogy azt akarjuk tudni, hogy mely szavak fordulnak elő egyszer a listában, és mely szavak fordulnak elő többször, de nem akarunk duplán kiírt szavakat látni. Ezt úgy tudjuk elérni, hogy két halmazt hozunk létre: az egyik minden elemet tartalmaz, a másik csak a duplikáltakat. 2. Hozzunk létre két Integer objektumokat tartalmazó halmazt a FindDups programban látott módon tömbökkel inicializálva. Állítsuk elő a két halmaz unióját, metszetét, különbségét.
149
A List interfész Sorszámozott kollekció
A Collection osztálytól örökölt műveletek mellett újabbakat is tartalmaz: Pozíció szerinti elérés: Az elemek a listában betöltött helyük alapján is elérhetők. Keresés: A megadott elemet kikeresi a listából, és visszaadja a pozícióját. Bejárás: Kibővíti az Iterator lehetőségeit Részlista: Lehetővé tesz részlista műveleteket. A Java platform két általános célú List implementációt tartalmaz: a ArrayList (mely általában hatékonyabb), és a LinkedList (mely bizonyos esetekben hatékonyabb), valamint hozzáigazította a régebbi Vector osztályt az új interfészhez.
150
public interface List<E> extends Collection<E> {
// Positional access E get(int index); E set(int index, E element); //optional boolean add(E element); //optional void add(int index, E element); //optional E remove(int index); //optional boolean addAll(int index, Collection<? extends E> c); //optional // Search int indexOf(Object o); int lastIndexOf(Object o); // Iteration ListIterator<E> listIterator(); ListIterator<E> listIterator(int index); // Range-view List<E> subList(int from, int to); }
151
A listaelemek összehasonlítása azok equals metódusa alapján történik
A Collection-tól örökölt metódusokat az elvárásainknak megfelelően használhatjuk. remove metódus mindig az első előforduló elemet törli a listából. Az add és addAll metódusnál az elem a lista végére kerül. Például a list1 végére másolja a list2 elemeit: list1.addAll(list2); A listaelemek összehasonlítása azok equals metódusa alapján történik A pozíció szerinti elérés és keresés metódusainak működése értelemszerű
152
Iterátor funkciók kiterjesztése
public interface ListIterator<E> extends Iterator<E> { boolean hasNext(); E next(); boolean hasPrevious(); E previous(); int nextIndex(); int previousIndex(); void remove(); //optional void set(E e); //optional void add(E e); //optional } Pl: for (ListIterator<Type> it = list.listIterator(list.size()); it.hasPrevious(); ) { Type t = it.previous(); ... }
153
Range-view A subList(int fromIndex, int toIndex) részlista metódus visszaadja a lista egy szeletét A visszaadott lista kapcsolatban marad az eredeti listával. Így bármilyen módosítás történik a részlistán, az hatással lesz az eredetire is, sőt ez fordítva is igaz. Pl: A lista egy részét töröljük list.subList(fromIndex, toIndex).clear();
154
Lista algoritmusok A Collections osztály nagyon hatékonyan használható algoritmusokat nyújt listák kezelésére. A következő lista csak felsorolja a fontosabbakat: sort: Rendezi a listát. shuffle: Véletlenszerűen felcserél elemeket a listában. (Permutál.) reverse: Megfordítja az elemek sorrendjét a listában. rotate: Egy adott távolsággal rotálja az elemeket. swap: Felcserél két meghatározott pozícióban levő elemet. replaceAll: Az összes előforduló elemet kicseréli egy másikra. fill: Felülírja az összes elemet egy meghatározott értékkel. copy: Átmásolja a forráslistát egy céllistába. binarySearch: Egy elemet keres a bináris keresési algoritmust használva. indexOfSubList: Visszatér az első olyan indexszel, amelynél kezdődő részlista egyenlő a másik listával. lastIndexOfSubList: Visszatér az utolsó olyan indexszel, amelynél kezdődő részlista egyenlő a másik listával.
155
Feladat Módosítsa a korábban látott raktárprogramot úgy, hogy az egy listában tárolja az egyes árufajták adatait. Végezze el a következő műveleteket: Árufajta felvétele Listázás Eladás Vétel Ármódosítás
156
A Map interfész Kulcs-érték párokat tartalmaz
Az egyedi kulcs alapján megkereshetjük a kulcshoz tartozó értéket (sokkal kényelmesebb, mintha össze kellene állítanunk egy keresőobjektumot) A Java platform három általános célú Map implementációt tartalmaz: HashMap, TreeMap és LinkedHashMap (melyek hasonló tárolási elvűek és működésűek, mint a Set implementációk), valamint hozzáigazította a régebbi Hashtable osztályt az új interfészhez.
157
public interface Map<K,V> {
// Basic operations V put(K key, V value); V get(Object key); V remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty(); // Bulk operations void putAll(Map<? extends K, ? extends V> m); void clear(); // Collection Views public Set<K> keySet(); public Collection<V> values(); public Set<Map.Entry<K,V>> entrySet(); // Interface for entrySet elements public interface Entry { K getKey(); V getValue(); V setValue(V value); }
158
import java.util.*; public class Freq { public static void main(String[] args) { String[] words={"i","came","i","saw","i","left"}; Map<String, Integer> m=new HashMap<String, Integer>(); for (String w: words) { Integer freq=m.get(w); m.put(w, (freq==null)?1:freq+1); } System.out.println(m.size() + " distinct words:"); System.out.println(m);
159
A Collection view metódusokkal háromféle nézetét kapjuk a Map-nek
keySet: kulcsok halmaza (Set) values: értékek kollekciója (Collection) entrySet: kulcs-érték párok halmaza (Set). A Map interfész tartalmaz egy kis beágyazott interfészt – Map.Entry – ezen halmaz elemei típusának meghatározására. Csak a kollekció nézetekkel lehet iterációt végezni a Map-en. Használhatók remove, removeAll, retainAll, clear kollekció műveletek for (KeyType key : m.keySet()) System.out.println(key); //With an iterator: //Filter a map based on some property of its keys. for (Iterator<Type> it = m.keySet().iterator(); it.hasNext(); ) if (it.next().isBogus()) it.remove(); //Following is the idiom for iterating over key-value pairs. for (Map.Entry<KeyType, ValType> e : m.entrySet()) System.out.println(e.getKey() + ": " + e.getValue());
160
További példák a kollekció nézetek használatára
//1. if (m1.entrySet().containsAll(m2.entrySet())) { ... } //2. if (m1.keySet().equals(m2.keySet())) { //3. Set<KeyType>commonKeys = new HashSet<KeyType>(m1.keySet()); commonKeys.retainAll(m2.keySet()); //4. m1.entrySet().removeAll(m2.entrySet()); //5. m1.keySet().removeAll(m2.keySet());
161
//6. Set<Employee>individuals=new HashSet<Employee>(managers.keySet()); individuals.removeAll(managers.values()); //7. Suppose you want to fire all the employees who report directly to some manager, Simon. Employee simon = ... ; managers.values().removeAll(Collections.singleton(simon)); //8. Once you've done this, you may have a bunch of employees whose managers no longer work for the company (if any of Simon's direct-reports were themselves managers). The following code will tell you which employees have managers who no longer works for the company. Map<Employee,Employee> m=new HashMap<Employee,Employee>(managers); m.values().removeAll(managers.keySet()); Set<Employee> slackers = m.keySet();
162
Rendezés Collections.sort(l); Alapértelmezett rendezés, a lista elemeinek osztálya implementálja Comparable interfészt, azaz tartalmaz egy compareTo metódust. Korlátok: Csak egyféle rendezettség Be van égetve az objektumba, nem lehet változtatni rajta Lehet, hogy nem is implementálta a Comparable interfészt Rendezés egy Comparator objektummal public interface Comparator<T> { int compare(T o1, T o2); } „Névtelen osztály” létrehozásával
163
import java.util.*; public class DiakokList3{ public static void main(String[]args){ final Comparator<Diak> PONTSZERINT=new Comparator<Diak>(){ public int compare(Diak d1, Diak d2){ return d1.getPont()-d2.getPont(); } }; List<Diak> diakok=new ArrayList<Diak>(); diakok.add(new Diak("Kovács István",10)); ... //Természetes rendezettség szerinti lista Collections.sort(diakok); for(Diak a:diakok) System.out.println(a); //Lista comparator szerinti rendezettséggel Collections.sort(diakok, PONTSZERINT);
164
A SortedSet interfész Rendezettség:
public interface SortedSet<E> extends Set<E> { // Range-view SortedSet<E> subSet(E fromElement, E toElement); SortedSet<E> headSet(E toElement); SortedSet<E> tailSet(E fromElement); // Endpoints E first(); E last(); // Comparator access Comparator<? super E> comparator(); } Rendezettség: Az elemek természetes rendezettsége szerint A létrehozásakor megadott Comparator alapján Általános implementáció: TreeSet
165
import java.util.*; public class SortedSetDemo{ public static void main(String[]args){ int[]a={21,25,23,28,22,26,12}; SortedSet<Integer> s1=new TreeSet<Integer>(); for(Integer i: a) s1.add(i); System.out.println(s1); System.out.println(s1.headSet(25)); Comparator<Integer> reverse=new Comparator<Integer>(){ public int compare(Integer i1, Integer i2){ return i2-i1; } }; SortedSet<Integer> s2=new TreeSet<Integer>(reverse); s2.addAll(s1); System.out.println(s2);
166
int count = dictionary.subSet("doorbell", "pickle").size();
dictionary.subSet("f", "g").clear(); for (char ch = 'a'; ch <= 'z'; ch++) { String from = String.valueOf(ch); String to = String.valueOf(ch); System.out.println(from + ": " + dictionary.subSet(from, to).size()); }
167
A SortedMap interfész Rendezettség:
public interface SortedMap<K, V> extends Map<K, V>{ Comparator<? super K> comparator(); SortedMap<K, V> subMap(K fromKey, K toKey); SortedMap<K, V> headMap(K toKey); SortedMap<K, V> tailMap(K fromKey); K firstKey(); K lastKey(); } Rendezettség: Az kulcsok természetes rendezettsége szerint A létrehozásakor megadott Comparator alapján Általános implementáció: TreeSet
168
Summary of Interfaces The core collection interfaces are the foundation of the Java Collections Framework. The Java Collections Framework hierarchy consists of two distinct interface trees: The first tree starts with the Collection interface, which provides for the basic functionality used by all collections, such as add and remove methods. Its subinterfaces — Set, List, and Queue — provide for more specialized collections. The Set interface does not allow duplicate elements. This can be useful for storing collections such as a deck of cards or student records. The Set interface has a subinterface, SortedSet, that provides for ordering of elements in the set. The List interface provides for an ordered collection, for situations in which you need precise control over where each element is inserted. You can retrieve elements from a List by their exact position. The Queue interface enables additional insertion, extraction, and inspection operations. Elements in a Queue are typically ordered in on a FIFO basis. The second tree starts with the Map interface, which maps keys and values similar to a Hashtable. Map's subinterface, SortedMap, maintains its key-value pairs in ascending order or in an order specified by a Comparator. These interfaces allow collections to be manipulated independently of the details of their representation.
169
Általános célú implementációk
Az általános célú implementációk mind biztosítják az összes opcionális műveletet, amit az interfészek tartalmaznak.
170
Általános szabály, hogy programíráskor az interfészeken, és nem az implementációkon kell gondolkodni. Legtöbb esetben az implementáció megválasztása csak a teljesítményt befolyásolja. Az előnyben részesített programozói stílus az, ha egy interfész típusú változóhoz választunk egy implementációt. Így a program nem függ majd egy adott implementáció esetén az ahhoz hozzáadott új metódusoktól, ezáltal a programozó bármikor szabadon változtathatja az implementációt, mikor jobb teljesítményt szeretne elérni, vagy a működési részleteket szeretné módosítani.
171
The Java Collections Framework provides several general-purpose implementations of the core interfaces: For the Set interface, HashSet is the most commonly used implementation. For the List interface, ArrayList is the most commonly used implementation. For the Map interface, HashMap is the most commonly used implementation. For the Queue interface, LinkedList is the most commonly used implementation.
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.