Eszközök a webhelyen


oktatas:programozás:java:java_nyelv

Tartalomjegyzék

< Java

A Java nyelv

  • Szerző: Sallai András
  • Copyright © Sallai András, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2018
  • Licenc: GNU Free Documentation License 1.3

Bevezetés

A Java-át James Gosling, Patrick Naughton, Chris Warth, Ed Frank, és Mike Sheridan hozta létre a Sun Microsystems, Inc. cégnél 1991-ben. 18 hónap telt el az első verzió megjelenéséig. Ennek az első nyelvnek a neve Oak volt, később 1995-ben lett átnevezve Java-ra. 2009-ben a Sun Microsystems-t felvásárolta az Oracle, így a Java rendszert ők viszik tovább.

Java-át úgy tervezték, hogy az így megírt programok minden operációs rendszeren fussanak minden változtatás nélkül. Ez úgy lehetséges, hogy a Java program nem az operációs rendszeren fut natív módon, azt egy Java környezetben futtatjuk.

A Java nyelven írt programokat java fordítóval fordítjuk le, és Java futtató környezettel futtatjuk. Ez utóbbi azt jelenti, hogy egy operációs rendszeren önállóan futni nem képes. A futtató környezet általánosan keretrendszernek is hívjuk, de az Oracle keretrendszerét Java Runtime Environment néven használjuk, röviden JRE. A fejlesztői környezet pedig a JDK, azaz a Java Development Kit. A fejlesztői környezet tartalmazza többek között a java fordítót, amely parancs a „javac”.

A Java nyelv szigorúan osztályok halmaza, kis és nagybetű érzékeny, minden utasítást pontosvesszővel zárunk.

A Java nyelven írt programokból bájtkódot szokás létrehozni.

Java forráskód Java fordító Java bájtkód Java futtató Gépi kód
Program.java javac Program.class java 1 és 0 sorozata

Azonban vannak fordítók, amelyek gépi kód létrehozására is alkalmasak.

Java forráskód Java fordító Gépi kód
Program.java javac Program.exe

A bájtkód futtatását a Java keretrendszer, vagy futtató környezet, angolosan Java Runtime Environment, röviden JRE biztosítja.

Java bájtkód
Java keretrendszer
Operációs rendszer
Hardver

Helló Világ

Készítse el a következő forráskódot a megadott néven, majd mentse, fordítsa és futtassa:

Test.java
class Test {
    public static void main(String[] args) {
        System.out.println("Java működik a gépeden");
    } 
}

Fordítás:

javac test.java

Futtatás:

java test

Előfordul, hogy a futtató keretrendszer nemtalálja a keretrendszer osztályait. Ekkor a következő kapcsoló megadása szükséges:

java -cp . test.java

A program elemzése

A programban megfigyelhetjük, hogy az összetartozó részeket, továbbiakban blokkokat kapcsos zárójelek határolják:

{  ez a blokk  }
{
   egyik sor
   másik sor
}

A példa alapján azt is észrevehetjük, hogy a blokkok egymásba ágyazhatók, és minden blokknak van egy fejrésze. A blokk fejrészében írjuk le mire is való az adott blokk. A Javaban mindig osztályokkal dolgozunk, angolul class. Osztályokba szervezzük a megvalósítandó programjainkat. Ennek valamilyen nevet kell adni. Fenti példánkban a név „test”. Ennek a névnek meg kell egyeznie az állomány nevével. Ez lesz a kiindulási osztályunk, a program végrehajtása ebben az osztályban kezdődik majd.

A Javaban az egyes tevékenységeket függvényekben valósítjuk meg és szokásos módon metódusnak nevezzük. Minden Java program kell tartalmazzon egy „main” nevű metódust. A programnak ez lesz kiindulási pontja, innen indul, amit úgy mondunk: a program „belépési pontja”. A main metódust a kiinduló osztályunkban hozzuk létre. A neve előtt és után egy pár dolgot meg kell adnunk. A main előtt módosítókat adunk meg. A main kötelező módosítói a public és static. A public biztosítja, hogy a program indításakor a main metódus elérhető legyen az operációs rendszerből. A static módosító biztosítja, hogy a main metódust a nélkül is elérhessük, hogy példányosítanánk a test osztályt (Később látni fogjuk, hogy az osztályokkal sokszor úgy dolgozunk, hogy létrehozunk belőle egy példányt). A void egy speciális típus, azt jelenti nincs típus. Esetünkben ezzel azt mondjuk, hogy a program visszatérési értékkel nem rendelkezik a futtató környezet felé.

A main név után zárójelekben adjuk meg a program bemenő paramétereinek leírását. Ez „String[] args” A bemenő paraméterek leírását akkor is meg kell adnunk ha nem használjuk őket. Fordításkor nem is de futtatáskor hibát kapunk, ha hiányzik. A példában azt látjuk, hogy egy String típusú tömbben amelynek neve „args” tároljuk el a bemenő paramétereket. A String típusról és a tömbökről később lesz szó.

Fordítás

A példában szereplő forrást a javac paranccsal fordítjuk. Alap esetben persze ez nem áll rendelkezésére. Telepítenünk kell a Java SDK valamely verzióját. A telepített SDK könyvtárában lesz egy „bin” nevű könyvtár, ezt útvonalba tesszük. Itt található a javac fordító is.

A java futtató parancs általában működni szokott, ha böngészőnk miatt már telepítettünk egy Java JRE csomagot.

System osztály

A Java nyelvben osztályokkal dolgozunk. Mivel sok osztály létezik szükséges azok csoportosítása. Az összetartozó osztályokat csomagokban tároljuk. Egy csomag a háttértárolón egy könyvtárnak felel meg.

A System osztály a java.lang csomagból (wrapper) való. Ha egy osztályt a Java nyelvben használni szeretnénk, akkor importálni kell azt a csomagot, amely azt tartalmazza. A java.lang egy olyan alaposztály, amelyet a Javaban nem kötelező importálni, ez biztosítja a Java program alapszerkezetét.

Gyakorlás

  • Milyen kiterjesztése van egy Java forráskódnak?
  • Milyen kiterjesztése van egy lefordított Java programnak?
  • Eredetileg hány ember hozta létre a Java-át?
  • Milyen paranccsal fordítjuk le a Java nyelven írt programunkat?
  • Milyen paranccsal tudjuk futtatni a Java programot?
  • Egy Java program futtatásakor meg kell adni a program kiterjesztését?
  • Mit kell tudni a main() metódusról?
  • Milyen karakterrel jelezzük egy blokk kezdetét és végét?
  • A main() metódusnak milyen kötelező módosítói vannak?
  • A main() metódusnak milyen kötelező bemenő paramétere van?
  • A System osztály melyik csomagban található?
  • Mi az a void?
  • Írasson ki karaktersorozat helyett számokat a képernyőre.
  • Oldjon meg feladatokat az általános feladatgyűjteményből. Önnek jelenleg körülbelül az első 20 feladat megoldása jöhet szóba.
  • Melyik csomag van alapértelmezetten importálva?
  • A Java nyelv kisbetű-nagybetű érzékeny?
  • Mi a JDK?
  • Mi a JRE?

Megjegyzések

A Java nyelvben egy és kétsoros megjegyzések használhatók.

Az egysoros megjegyzést a kettőd darab perjel valósítja meg:

// egy soros megjegyzés

Több soros megjegyzést a /* és */ karakterek közzé írhatunk:

/* ez
   egy
   több
   soros
   megjegyzés */

Kivitel

A kivitel alapesetben azt jelenti írok a képernyőre. Ezt megtehetjük a következő két metódussal a System osztályból:

  • print()
  • println()

A következőkben összehasonlítjuk a két metódust, megnézzük a különbségeket.

System.out.println("ElsőMásodik");
System.out.println("Első");
System.out.println("Második");
System.out.print("Első");
System.out.print("Második");

Persze nem csak karaktersorozatokat írathatunk ki, lehet számok és más karakterek is:

System.out.println("ElsőMásodik");
System.out.println("1234");
System.out.println("@!+=");

Ha számokat szeretnénk kiíratni, akkor azokat nem kötelező idézőjelek közzé tenni:

System.out.println(1234);

Ha a számokat idézőjelek nélkül adjuk meg paraméterként, akkor számításokat is végezhetünk vele.

A következő példában beszorozzuk az 1234-s értéket 2-el.

System.out.println(1234 * 2);

Esetleg összeadásokat végezhetünk vele:

System.out.println(3 + 2);

A kimenet:

5

Ügyeljünk arra, hogy ha az előbbi kifejezést idézőjelbe tesszük, akkor nem az összeadás eredménye íródik ki, hanem a kifejezés karakterről karakterre:

System.out.println("3 + 2");

Kimenet:

3 + 2

Statikus import:

Program01.java
import static java.lang.System.*;
class Program01 {
	public static void main(String[] args) {
		out.println("Hi");
	}
}

Különleges karakterek

A különleges karakterek másként escape szekvenciák.

Néhány karakternek speciális értelmezése is lehet. Ha így akarjuk használni, akkor ezt valahogy jelezni kell. Ilyen speciális értelmezés lehet, amikor egy sortörést akarunk kiíratni. Ezt az „n” karakterrel tehetjük meg, ha a speciális jelentését használjuk. A speciális jelentést egy visszaperjellel (\) jelezzük:

\n

Ilyen speciális kérés lehet egy tabulátorjel kiíratása. A tabulátorjelet a „t” karakter jelképezi. A használatához itt is a visszaperjelet tesszük elé:

\t

Az ilyen karaktereket Escape szekvenciának hívjuk.

Gyakorlásként írjuk a képernyőre a „Helló Világ” nevű programot a következő formában:

Program.java
class Program {
    public static void main(String[] args) {
        System.out.println("Helló\nVilág");
    }
}

A példafeladatban a (\n) escape szekvenciát használjuk.

Program.java
class Program {
    public static void main(String[] args) {
        System.out.println("Helló\tVilág");
    }
}

Vannak olyan karakterek is, amelyeknek a Java nyelven eleve speciális jelentésük van. Ilyen az idézőjel („), amely egy szöveg elejét és végét jelzi. Ha egy karaktersorozatban szeretnénk kiíratni, nehézségekbe ütközünk. Ehhez is tartozik persze escape szekvencia:

\"
Program.java
class Program {
    public static void main(String[] args) {
        System.out.println("Helló\"Világ");
    }
}

Az escape szekvenciák tehát egy-egy betű, amelyet ha alkalmazunk visszaperjellel vezetjük be. Alkalmazhatjuk őket karakterek helyén is.

char sortores = '\n';

A Java nyelv Escape karakterei az alábbi táblázatban láthatók.

Escape szekvencia Leírás
\uxxxx Hexadecimális UNICODE karakter (xxxx)
\' Felső vessző
\” Idézőjel
\\ Visszaperjel
\r Kocsi vissza (A kiírás a sor elején folytatódik)
\n Új sor
\f Lapdobás
\t Tabulátor
\b Visszatörlés (Előtte lévő karaktert törli)

Escape szekvenciával megadhatunk Unicode karakter is ha tudjuk annak kódját.

Az alábbi táblázatban a Copyright és negáció jelek unicode-ját látjuk.

Karakter Kód
© 00a9
¬ 00ac

A példa kedvéért így íratjuk kia copyright karaktert:

System.out.println("\u00a9");

Még több unicode karakter: http://www.unicode.org/charts/PDF/U0080.pdf

Karakter típusú változók létrehozása és értékadás így a következő módon néz ki:

char ch;
char idezojel;
 
ch = 'a';
idezojel = '\"';

W7 alatt fok:

\u0159

Adattípusok

A memóriában adatokat tárolunk, amelyek lehetnek egész számok, valós számok, karakterek, esetleg karaktersorozatok. Az ilyen memóriahelyeket a programozás során mint változókat emlegetjük. A változókat használatuk előtt deklarálni kell. Ez azt jelenti, meg kell mondanunk milyen típusú adatot szeretnénk tárolni az adott memória helyen. Ez azért fontos, mert a rendszer így tudja mekkora helyet kell az adatnak lefoglalni. Az alábbiakban megnézzük hogyan foglalhatunk helyet egész, valós, karakteres, stb., típusok számára.

Példa egy változó deklarációra:

int szam;

A különböző primitív adattípusok számára a memóriában helyet foglalunk, használat előtt. Azonban nem mindegy mekkora helyet kell lefoglalni. Más méretet foglalunk le egy egész típusú számnak vagy más méretet egy valóst típusú számnak.

A memóriában lefoglalt helyre értéket helyezhetünk el a következő utasítással:

szam = 35;

A „szam” nevű memóriahelyre 35 értéket tettük. Akármekkora számot nem tehetünk a memóriahelyre. Ha deklaráláskor az „int” kulcsszót tettük a deklarációba, akkor a legnagyobb beírható szám: 2147483647. A legkisebb: -2147483648.

Az int helyett megadható még egy pár típus. A következő táblázatokban azt látjuk, melyik mekkora helyet foglalhat a memóriában és így mekkora számot tárolhatunk benne, maximum és minimum értékekkel.

Egész típusok

byte 1 byte -128 – 127
short 2 bytes -32 768 – 32 767
int 4 bytes -2 147 483 648 – 2 147 483 647
long 8 bytes -9 223 372 036 854 775 808 – 9 223 372 036 854 775 807

Ha nagyobb értéket akarunk elhelyezni egy változóban, mint amire névlegesen megengedett:

short a = 32768;

Fordításkor a következő hibaüzenetet kapjuk:

javac -cp Program.java 
Program.java:6: possible loss of precision
found   : int
required: short
		short a = 32768;
		          ^
1 error
>Exit code: 1

Az int típus esetén:

integer number too large: 2147483648
		int c = 2147483648;
		        ^

Valós típusok

Valós típusok tárolására a float és a double típusok használhatók. Tartományuk az alábbi táblázatban látható:

double 8 bytes 4.9e-324 – 1.7976931348623157e+308
float 4 bytes 1.4e-45 – 3.4028235e+38

A float egyszeres pontosságú számokat képres tárolni, míg a double dupla pontosságú számokat képes tárolni.

A valós típusok használata:

double a = 3.4d;
double a = 3.4f;

A double esetén elhagyható a szám végéről a „d” betűt:

double a = 3.4;

Java karakterek

char 2 byte

A karaktereket a char segítségével definiálhatunk, amely egy darab karaktert szimbolizál, ami lehet egy betű, egy szám vagy valamilyen írásjel.

Például:

a

vagy

b

vagy

@

Az „a”, „b” és „et” jel karaktereket jelentik.

Ha meg akarok adni egy karaktert a Java nyelvben azt mindig aposztrófok között adjuk meg. Például:

'a'

vagy:

'b'

vagy:

'@'

Ezek után egy változót a következő módon tárolunk változóban:

char ch; 
ch = 'a';

Gyakorlásként írjunk egy programot, amely egy-egy változóban eltárolja a következő betűket: „a”, „l”, „m”, „a”. Majd írassuk a képernyőre egy sorba:

Program.java
class Program {
    public static void main(String[] args) {
        char a = 'a';
        char b = 'l';
        char c = 'm';
        char d = 'a';
        System.out.print(a);
        System.out.print(b);
        System.out.print(c);
        System.out.print(d);
    }
}

Logikai típus

A logikai változóknak két értéke lehet true és false. Deklarálásra a következő szót használom: boolean

boolean 1 byte

Használata például:

boolean van;
van = true;

A szelekciós vagy iterációs kifejezésekben hasznunkra lehetnek, lásd később a szelekciónál.

A float típus

float a = 3.87;

Ebben a formában hibaüzenetet ad, mi szerint elveszítjük a pontosságot. Ezért egy „f” betűt kell a végére tenni.

float a = 3.87f;

A primitív típusok csomagolóosztályai

A Java nyelvben nem minden objektum. Az adattípusok egy ilyen speciális csoportot alkotnak. Ezeket primitív típusoknak is szoktuk nevezni.

Primitív típus Érték Csomagoló osztály Tartomány
boolean true, false Boolean true vagy false
char 16 bit-es Unicode Character \u0000 – \uFFFF
byte 8 bit-es előjeles egész Byte -128 – 127
short 16 bit-es előjeles egész Short -32768 – 32767
int 32 bit-es előjeles egész Integer -2147483648 – 2147483647
long 64 bit-es előjeles egész Long -9223372036854775808 – 9223372036854775807
float 32 bit-es lebegőpontos Float 1.4E-45 – 3.4028235E+38
double 64 bit-es lebegőpontos Double 439E-324 – 1.7976931348623157E+308

A Java nyelvben minden típus előjeles (signed), azaz nincs előjel nélküli (unsigned) típus.

A primitív típusok rendelkeznek egy nekik megfelelő csomagolóosztállyal (vagy burkoló osztály).

Egyenlőség

A következő program true értéket ír a képernyőre, mivel a két változó értéke egyenlő:

double a = 3.0;
double b = 3.0;
System.out.println(a == b);

Ha burkoló osztállyal hozom létre a változókat, az egyenlőség nem igaz:

Double a = 3.0;
Double b = 3.0;
System.out.println(a == b);

Az egyenlőség nem igaz, mert osztályok között az „==” operátor a két osztály hivatkozását hasonítja össze, nem az tartalmát.

Burkoló osztály esetén használjuk az osztály equals() metódusát:

Double a = 3.0;
Double b = 3.0;
System.out.println(a.equals(b));

Típusok mérete és határa

Maximum értékek kiíratása:

System.out.println(Byte.MAX_VALUE);			
System.out.println(Short.MAX_VALUE);		
System.out.println(Integer.MAX_VALUE);		
System.out.println(Long.MAX_VALUE);

Minimum értékek kiíratása:

System.out.println(Byte.MIN_VALUE);			
System.out.println(Short.MIN_VALUE);		
System.out.println(Integer.MIN_VALUE);		
System.out.println(Long.MIN_VALUE);

Hány biten tároljuk az adott típust:

System.out.println(Byte.SIZE);
System.out.println(Short.SIZE);
System.out.println(Integer.SIZE);
System.out.println(Long.SIZE);

A printf metódussal tizedestört formában is kiírhatók a lebegőpontos számok:

System.out.printf("%f\n\n", Double.MAX_VALUE);

Írjon programot, amelybe a fenti utasításokat helyettesíti be. Például:

Program01.java
class Program01 {
    public static void main(String[] argv) {
        System.out.println(Byte.MIN_VALUE);			
    }
}

Primitív típusok konverziója szélesítéssel

Ha van egy kisebb számokat tárolni képes változónk, annak értéke eltárolható egy nagyobb értékek tárolására képes változóban. Ezt nevezzük szélesítésnek.

Ha eltárolom például egy 35-öt egy byte típusú változóban:

byte a = 35;

Később átadhatom az értéket egy short, int, long, stb. típusú változónak:

byte a = 35;
int b = a;

Ezt azért tehetem, mert „b” változóban nagyobb szám tárolható mint az „a” változóban. Ezt nevezzük szélesítésnek. Fordítva azonban már nem lehetséges.

Az alábbiakban az egyes típusokat látjuk milyen szélesítés alkalmazható rajtuk:

  • byte → short, int, long, float, double
  • short → int, long, float, double
  • char → int, long, float, double
  • int → long, float, double
  • long → float double
  • float → double

Lássuk újabb példával:

byte a = 3;
short b = a;

A példában 3-s számot az „a” változóban tároljuk először, az után szélesítést alkalmazunk meg „a” értékét egy olyan változóban tároljuk el, amely már nagyobb számok tárolására is képes. Vagyis, egy byte típusú változót tartalmát egy short típusúban tárolhatom, ehhez semmiféle konverzióra nincs szükség.

Primitív típusok konverziója szűkítéssel

A szűkítés már kényesebb dolog. Az értéket olyan változóban szeretném tárolni amely kisebb számok tárolására alkalmas mint az eredeti.

  • short → byte, char
  • char → byte, short
  • int → byte, short, char
  • long → byte, short, char, int
  • float → byte, short, char, int, long
  • double → byte, short, char, int, long, float

Példa:

short a = 3;
byte b  = (byte) a;

A példánkban a short nagyobb számok tárolására alkalmas, így nem írhatjuk le:

b = a;

Helyette típus kényszerítést használunk. A típuskényszerítés során zárójelbe tesszük annak a típusnak a nevét, amelybe szeretnénk átalakítani. Ha az egyenlőségjel baloldalán egy byte típus van, akkor zárójelbe azt írom „byte”. A típuskényszerítést „kasztolás” névvel is használjuk.

A kasztolás egyébként az angol casting szó magyarosan ejtése: casting [UK: ˈkɑːstɪŋ][US: ˈkæstɪŋ] esés, hajítás, horgászás, kimustrálás, öntés, öntvény, szereposztás, vetemedés, vetés. Eredeti formája: „type casting”. A C nyelvben terjedt el használata. Egy újabb példa a kasztingra:

double a = 3;
int b = (int)a;

Az „a” változó értékét kasztoljuk int típussá.

Literális

A literális egy olyan állandó, aminek nincs neve. Literális például a „3”, az „a” betű, a „/” jel, bármi.

Amikor leírjuk, hogy

int a = 3;

a három az egy literális állandó. Állandó, mert a program további részében ezt az adatott nem tudom megváltoztatni, és literális mivel nincs neve. Nem egy névvel hivatkozok rá, hanem beírtam úgy ahogy van.

Literális a következő karakter, egyenlőség jel jobboldalán:

char ch = 'a';

Literális a következő is:

String s = "szilva";

Láthatjuk hogy a szám literálisokat csak úgy leírjuk, a karakterlitárálisokat felsővesszők közé tesszük, a karaktersorozat literálisokat pedig idézőjelek közé tesszük a Java nyelvben.

Gyakorlat

  • Milyen primitív típusok vannak a Java nyelvben?
  • Lehet-e valós számokat tárolni egy int típusú változóban?
  • Lehet-e valós számokat tárolni egy double típusú változóban?
  • Eltárolható-e a 300-as egész érték egy byte típusú változóban?
  • Milyen értékeket vehet fel egy boolean típusú változó?
  • Írjon le minimum négy primitív típus, írja mellé milyen burkoló osztály tartozik hozz!

Java változók és állandók

A változók elnevezése

A Java-ban a legkisebb tárolási egység. A változókat használat előtt deklarálni kell.

double fizetes;
double _fizetes;
int fizetes;
int $fizetes;
long fizetes;
boolean kesz;

Nem használható változónevek:

double 1salary;
double %salary;
int #holidays;

Egy változó nem kezdődhet számmal, nem kezdődhet százalékjellel, nem kezdődhet kettős-kereszttel.

A változók deklaráláskor értékét is definiálhatjuk:

double fizetes = 70000;

A Java állandói

Eddig is használtunk állandókat, konkrétan literális állandókat. A következő állandók úgynevezett nevesített állandók. Azt vállaljuk, hogy a memóriaterületen elhelyezett értéket a program további részében nem fogjuk megváltoztatni. Ehhez a final kulcsszót fogjuk használni:

Program01.java
class Program01 {
	public static void main(String args[]) {
		final int a = 5;		
		System.out.println(a);
	}
}

A programunkban azt vállaljuk, hogy a program további részében az „a” nevű memóriahely tartalmát többet nem változtatjuk meg.

Program01.java
class Program01 {
	public static void main(String args[]) {
		final int ALAPFIZETES = 200000;		
 
		System.out.println(ALAPFIZETES);
	}
}

Az állandókat nagybetűvel szokás írni, hogy megkülönböztessük azokat a változóktól. Így a forráskódban azonnal felismerhető.

Kérdések és gyakorlat

Kérdések

  • Hogyan nevezzük az egyedváltozókat másként?
  • Hogyan nevezzük a statikus változókat másként?
  • A helyi változókat hol hozzuk létre?
  • Hol érvényesek a paraméterként létrehozott változók?
  • Hogyan deklarálunk egy nevesített állandót?
  • Mondjon vagy írjon példát literális állandóra.

Gyakorlat

  1. Készítsen egy programot, amely legalább 3 mezőt tartalmaz. Írja át a mezőneveket úgy, hogy ne legyen szabályos. Milyen hibaüzeneteket kap?
  2. Az előző programban próbáljon meg mezőket úgy létrehozni, hogy nem ad kezdőértéket.

Értékadás

Értékadást egy darab (=) karater segítségével végzünk. A Java nyelvben előfordul két egyenlőségjel karakter is egymás után, annak azonban más jelentése van. Értékadáshoz csak egy darab karaktert használunk.

Az egyenlőségjel baloldalán álló változó felveszi a jobboldalon álló számállandó, változó vagy kifejezés értékét.

Számállandók a jobboldalon

Float a = 3F;

vagy kisbetűvel:

Float a = 3f;

Primitív típus egész számmal:

float b = 3;

Valós számmal már szükséges az „f” vagy „F” jelző:

float b = 3.0f;
Double c = 3.;
double d = 3;

Használhatjuk a „d” vagy „D” jelzőt:

double d = 3.0d;

Változó a jobboldalon

float a = b;

Kifejezés a jobboldalon

float a = (b + c) * 3;

A kifejezés operátorokat és operandusokat tartalmazó összeállítás. A példában a operandusok az egyenlőség jel jobb oldalán a „b”, a „c” és a „3”. Operátorok a záró és szorzójel.

Értékadás esetén kifejezés nem állhat az egyenlőségjel baloldalán. A következő utasítás teljesen hibás: (b + c) * 3 = a;

Egész és valós számok

Nézzük meg a következő kifejezés hogyan lesz kiértékelve, mit ír a program a képernyőre:

double a = 1 / 2;
System.out.println(a);

Az eredmény nulla, pedig 0.5 vártunk volna. Pedig egy double típusban tároljuk az eredményt. Mivel az értékadás jobboldalán csak egész számok szerepelnek az értékadás során a tört részek elvesznek.

Ha legalább egy számot valós típusúvá teszünk az eredmény 0.5 lesz.

double a = 1 / 2.0;
System.out.println(a);

A 2-es értéket valóssá számmá változtattuk azzal, hogy után írtunk egy pontot (.) és egy nullát (0). A nulla a Java nyelvben elhagyható:

double a = 1 / 2.;
System.out.println(a);

Használhatjuk a számok után a f vagy a d jelzőt:

double a = 1 / 2f;
System.out.println(a);
 
double b = 1 / 2d;
System.out.println(b);

Gyakorlat

  • Lehet-e egy egyenlőség jel baloldalán összeadni?
  • A Double típus esetén milyen jelzőt használunk a szám literális után?
  • A Float típus esetén milyen jelzőt használunk a szám literális után?
  • Float típus esetén kötelező a szám literális után megadni a jelzőt?

Formázott kivitel

Formázott kivitel esetén, amikor számot vagy egyéb érték használok, az egyszerű képernyőre írás helyett, apróbb formai változtatásokat hajtok végre. Ilyen lehet, hogy a számot, mindenképpen 10 helyen ábrázolom. Az üres helyeken vezető nullákat írok ki. Vagy 3 tizedesjegy pontossággal ábrázolok egy számot. Esetleg mindig ábrázolom az előjelt.

Formázott kivitelt például a printf() metódussal lehetséges:

System.out.printf("formátumkód", változó_állandó_vagy_kifejezés);

Az első argumentum egy formátumszöveg (formátum-karaktersorozat) , amely tartalmaz egy formátumkódot. A második egy változó, egy állandó vagy egy kifejezés.

A formátumkód szintaxisa:

%[argumentum_index$][jelzők][szélesség][.pontosság]konverziós_karakter

A formátumkód mindig százalékjellel (%) kezdődik és egy formátumkarakterrel (konverziós karakter) végződik. A formátumkaraktereket lásd alább. A formátumkód előtt és után bármi állhat a karaktersorozatban.

Argumentum index

Ha több argumentum is van, akkor megadhatjuk annak sorszámát, amelyet ki szeretnénk íratni. Az indexelés 1-el kezdődik.

Az alábbi példában nem használjuk az argumentumindexet:

System.out.printf("%d %d\n", 3, 4);

Így a képernyőre a következő íródik:

3 4

Az argumentumindext használva a megfordításhoz:

System.out.printf("%2$d %1$d\n", 3, 4);

A következő a kimenet:

4 3

Ehhez persze elég lett volna a két érték felcserélése, ezért a legkevésbé használt lehetőség.

Szélesség

A kiírás szélessége. Egy egész szám, például:

10
System.out.printf("%10d\n", 35);

A kiíratandó szám akárhány számjegyből áll, azt 10 helyen fogjuk ábrázolni, a a maradék hely szóközökkel lesz kitöltve. A tíz helyen a szám jobbra lesz igazítva.

Pontosság

A tizedes jegyek száma. Mindig egy ponttal (.) kezdődik. Például két tizedes jegy:

.2

Valós számok esetén megadhatjuk a tizedesjegyek számát:

System.out.printf("%.2f\n", 35.1234567);

Egyszerre megadható az szám ábrázolásának szélessége és a tizedesjegyek száma is:

System.out.printf("%10.2f\n", 35.1234567);

Ezredes elválasztó

A könnyebb olvashatóság érdekében nagyobb számok esetén ezredenként elválasztót szoktunk használni a számoknál. Amerikai szokás szerint ez egy vessző (,), de nálunk a magyar nyelvben ezt szóközökkel oldjuk meg. A Java nyelvben egy vessző megadásával vehetjük rá a programunkat az ezredeselválasztó használatára:

System.out.printf("%,f\n", 32432344842.52334);

Több szám kiíratása

Program.java
class Program {
	public static void main(String args[]) {
		int a = 45;
		int b = 27;
		System.out.printf("%d  %d\n", a , b);
	}
}
Program.java
class Program {
	public static void main(String args[]) {
		int a = 5;
		int b = 4;
                int c = 3;
		System.out.printf("%d  %d %d\n", a , b, c);
	}
}

Változók indexel megadva

Az egymás után megadott „a”, „b”, stb. változók kiíratásának sorrendje megváltoztatható:

Program.java
class Program {
	public static void main(String args[]) {
		int a = 45;
		int b = 27;
		System.out.printf("%d  %d\n", a , b);
		System.out.printf("%2$d  %1$d\n", a , b);
	}
}

Egy dollár jel előtt megadjuk, melyik indexű változó kiíratására gondoltunk. Ezzel persze egy változó többször is kiíratható. A következő példában az „a” változó tartalmát kétszer is kiíratom.

Program.java
class Program {
	public static void main(String args[]) {
		int a = 45;
		int b = 27;
		System.out.printf("%d  %d\n", a , b);
		System.out.printf("%2$d  %1$d  %1$d\n", a , b);
	}
}

A váltózók indexei 1-el kezdődnek.

Jelzők

+ előjel
- balra igazítás (csak szélesség meghatározással, így van értelme)
0 vezető nullák megjelenítése
, ezredes tagolás
# alternatív formátum megjelenítése (csak o, x és X esetén)
' ' egy vezető szóköz pozitív számok számára (csak: 'd', 'o', 'x', és 'X' esetén)
'(' negatív számok zárójelbe kerülnek (csak: 'e', 'E', 'f', 'g', és 'G esetén)

A jelzők sorrendje felcserélhetők. Az összes jelző alkalmazás lehetséges, de előfordul, hogy az egyik jelző használat értelmetlen a másik mellett.

Az ezredeselválasztó Linuxon gond nélkül működik, Windowson Unicode fontokat kell beállítani, másként nem működik.

Konverziós karakter

A formátumkódot mindig egy konverziós karakter zárja . Az alábbi táblázatban láthatjuk a lehetséges formátumkódokat.

Konverziós
karakter
Kategória Leírás
'b', 'B' elsődleges Ha az argumentum null, akkor visszatérés „false”. Az argumentum
boolden vagy Booldan, akkor a visszatérés String.valueOf().
Ellenkező esetben a vissztérés „false”.
'h', 'H' elsődleges Ha az argumentum null, akkor a visszatérés is null. Egyébként a
visszatérés Integer.toHexString(arg.hashCode().
's', 'S' elsődleges Ha az argumentum null, akkor a visszatérés is null. Ha az argumentum
formázást valósít meg akkor a formázás érvényesül.
Minden más esetben az argumentumon karaktersorozattá alakul toString()
'c', 'C' karakter Visszatér egy Unicode karakterrel
'd' átalakító Visszatér egy formázott decimális egésszel.
'o' átalakító Visszatér egy formázott oktális egésszel.
'x', 'X' átalakító Visszatér egy formázott hexadecimális egésszel.
'e', 'E' lebegőpontos Visszatér egy formázott decimális számmal
tudományos formában.
'f' lebegőpontos Visszatér egy formázott decimális számmal.
'g', 'G' lebegőpontos Visszatér egy formázott tudományos formával vagy decimális
formával, a kerekítés utáni érték pontosságától függően.
'a', 'A' lebegőpontos Visszatér egy formázott hexadecimális lebegőpontos számmal,
alappal és a kitevővel.
't', 'T' idővel kapcsolatos Dátum és konverziós karakterek előtagja.
Lásd a dátum és idő konverziót.
'%' százalék Visszaad egy '%' literálist '\u0025')
'n' sorelválasztó Visszatér egy platformspecifikus sortöréssel.

Példák

double a = 2,7183;
System.out.printf("Szám: %+10.4f", a);
// " Szám =    +2,7183"
 
System.out.format("Hatvany: %.2f\n", b);

Idő kiíratás

Az óra, perc, másodperc kiíratása:

System.out.printf("%tT\n", java.util.Calendar.getInstance());

Az év kiíratása:

System.out.printf("%tY\n", java.util.Calendar.getInstance());

Az óra kiíratása:

System.out.printf("%tH\n", java.util.Calendar.getInstance());
Program.java
import java.util.Calendar;
 
class Program {
	public static void main(String args[]) {
 
		Calendar datum = Calendar.getInstance();
		System.out.printf("%tH\n", datum);
	}
}

Még több példa:

      Calendar c = Calendar.getInstance();
      // -->  "May 29, 2006"
      System.out.format("%tB %te, %tY%n", 
                        c, c, c);
 
      // -->  "2:34 am"
      System.out.format("%tl:%tM %tp%n",
                        c, c, c);
 
      // -->  "05/29/06"
      System.out.format("%tD%n", c);

Sortörés

Mint azt fentebb láttuk sortörést lehet kiíratni a println() metódussal, de az '\n' escapeszekvencia is használható erre a célra. Ugyanezt tehetjük meg a „%n” segítségével.

Az aktuális operációs rendszer sortörésének kiíratása:

System.out.format("%f%n%n", 455.3823);

A Formatter osztály használata

Forma.java
import java.io.*;
import java.util.*;
class Forma {
    public static void main(String args[]) throws IOException {
        Formatter formazo = new Formatter();
 
        formazo.format("%s %d %f", "Java", 10, 97.5);
 
        System.out.println(formazo);
 
	System.in.read();
    }
}

A Formatter osztály a java.util csomagban található.

DecimalFormat osztály

Program.java
import java.text.DecimalFormat;
 
class Program {
	public static void main(String args[]) {
		DecimalFormat sajatForma = new DecimalFormat("###,###.###");
		System.out.format(sajatForma.format(123456.789));
	}
}

Console osztály használata

Program.java
import java.io.Console;
 
class Program3 {
	public static void main(String args[]) {
		Console konzol = System.console();		
		konzol.printf("Helló Világ!\n");
	}
}

Gyakorlat

  • Mikor használjuk a formázott kivitelt?
  • Mi a formátumkód?
  • Mi a formátumkarakter?
  • Milyen formátumkóddal írathatunk ki egész számokat?
  • Mit jelent a formátumkódban a %?
  • Milyen formátumkóddal írathatunk ki karaktereket?
  • Írjon példát, hogyan határozza meg, hogy egy „a” változóban tárolt valós szám, három tizedesjegy pontossággal íródjon ki.
  • Milyen formátumkóddal írathatunk ki valós számokat?
  • Milyen formátumkóddal írathatunk ki karaktersorozatokat?

Math osztály

Használat

A Math osztály olyan metódusokat tartalmaz, amelyek megkönnyítik a matematikai feladataink megoldását. Ilyenek az abszolút érték számítása, gyökvonás, hatványozás, trigonometriai függvények számítása, stb.

A Math osztály importálás és példányosítás nélkül azonnal rendelkezésünkre áll. A következő példában -15 abszolút értékét számítjuk ki.

Matek
import java.io.*;
class Matek {
    public static void main(String args[]) throws IOException {
        System.out.format("%d\n", Math.abs(-15));		
	System.in.read();
    }
}

Abszolút érték

Egy szám abszolút értékét adja vissza.

Ha megnézzük a Java API dokumentációt ehhez hasonlókat láthatunk:

double abs(double a)
float abs(float a)
int abs(int a)
long abs(long a)

Ebből tudhatjuk, hogy az abs metódusnak négy módon használhatjuk. Megadhatunk paraméterként double, float, int vagy long típust. Ha double adunk meg double típust ad vissza. Ezt az első sorból látjuk:

double abs(double a)

A „double a” mutatja, hogy milyen bemenő paraméter jöhet szóba, az elején a „double” pedig azt mutatja milyen értéket ad vissza a metódus.

Hatvány

Hatvány számítása:

double a = Math.pow(3, 2);

Az első szám alap, a második a kitevő.

double b = 1;

Gyökvonás

Adott szám gyökével tér vissza.

System.out.println(Math.sqrt(9));

Trigonometria

double c = Math.sin(b * Math.PI / 180);
double d = Math.sin(Math.toRadians(b));
 
System.out.printf("Szinusz : %.5f\n", c);
System.out.printf("Szinusz : %.5f\n", d);

A trigonometriai függvények radiánban várják az értékeket. A bemenő paramétert ezért át kell konvertálni előbb radiánba.

Függvények
double sin(double a)
double tan(double a)
double cos(double a)
double asin(double a)
double acos(double a)
double atan(double a)
double atan2(double a)

Pi

System.out.println(Math.PI);

A PI nem függvény! Tulajdonság!

Euler-féle szám

Az Euler-féle szám (jele: e) egy matematikai állandó, amit a természetes logaritmus alapja

System.out.println(Math.E);

Az E nem függvény! Tulajdonság!

max

Két szám közzül a nagyobbat adja vissza:

System.out.println(Math.max(7,4));

min

Két szám közül a kisebbet adja vissza:

System.out.println(Math.min(7,4));

round

A round a tizedes törtet kerekíti. .4-től lefele, .5-től felfele:

System.out.println(Math.round(1.5));

Eredménye: 2

System.out.println(Math.round(1.4));

Eredménye: 1

ceil

A ceil függvény a tizedes törtet felfelé kerekíti.

System.out.println(Math.ceil(1.0));

Eredménye: 1

System.out.println(Math.ceil(1.1));

Eredménye: 2

floor

A floor függvény a tizedes törtet lefelé kerekíti.

double floor(double a)

Két példa:

System.out.println(Math.floor(1.1));

Eredménye: 1

System.out.println(Math.floor(1.9));

Eredménye: 1

toDegrees

Radiánfok átszámítása szögfokká.

Math.toDegrees(85);

toRadians

Szögfok átszámítása radiánfokká.

Math.toRadians(85);

Exponenciális

Az exponenciális függvény ex vagy exp(x), ahol e egy matematikai állandó, a természetes alapú logaritmus alapja, értéke körülbelül 2,718281828, és Euler-féle szám

double exp(double a)

Logaritmus

A hatványozás egyik megfordított (inverz) művelete

log(a)

double log(double a)

A log() a szám természetes logaritmusát adja. A matematikában ln(x) a jelölése.

log10(a)

double log10(double a)

A log10() a szám 10 alapú logaritmusát adja. A matematikában a lg(x) a jelölése.

log1p(x)

double log1p(double x)

A log1p a szám és 1 összegének logaritmusát adja.

Gyakorlás

  • Milyen értéket várnak a trigonometriai függvények? Radián vagy szög?
  • Milyen metódussal számítható át szögfok radiánra?
  • A log(a) melyik logaritmust típust számítja ki?
  • Melyik metódussal kerekíthetünk a tört részeket felfelé?
  • Melyik metódussal kerekíthetjük a tört részeket lefelé?
  • Melyik metódussal tudunk a kerekítés szabályai szerint kerekíteni?
  • A log(a) függvénynek milyen típusú a bemenőparamétere és a visszatérési értéke?

Véletlen szám generálás

A véletlenszámok előállítására két osztály áll rendelkezésünkre. A Random és a Math.

Random osztály

Az eddig használt osztályok a java.lang csomagban voltak, amit nem kellett importálni. A Random osztály az eddigiektől eltérően importálni kell, a java.util csomagban található. Használni sem használhatjuk csak példányosítással. A példányosítás azt jelenti létrehozunk az osztályból egy példányt.

Az osztályok hasonlítanak például a „dolgozó” fogalomhoz. Ha azt mondom „dolgozó” az nem egy konkrét személy, konkrét ember, akár ki lehet. Ha azt mondom a Jóska nevű dolgozó akkor már konkretizáltam. A Jóska tulajdonképpen a dolgozó egy példánya. A Java nyelvben ehhez használjuk az osztályokat. Az osztály egy általános dolog. Ha példányosítom akkor, létrehoztam az adott osztály egy példányát. A létrehozott példányt objektumnak nevezzük. Az előbbi „dolgozó” analógiában az objektum a „Jóska példánynak” felel meg.

A Random osztályt példányosítani kell használat előtt, azt pedig a new utasítással tudjuk megtenni. Lássunk a példányosításra egy példát:

Random veletlen = new Random();  

A példánkban kitaláltunk egy objektum nevet, ez a „veletlen”. A példányosítás utn a „veletlen” egy olyan objektum, amelyet a Random osztályból hoztunk létre a „new Random()” kifejezés segítségével.

A háttérben, tulajdonképpen a memóriában egy „veletlen” nevű objektumnak foglaltunk helyet a „new Random()” kifejezéssel.

A Random osztály importálása:

import java.util.Random;

A Random osztály példányosítása veletlen objektum létrehozásával:

Random veletlen = new Random();

A veletlen objektum használata:

int szam = veletlen.nextInt(3);

A Random osztály egyik metódusa a nextInt(). A nextInt() metódus egy véletlen számot generál, ha meghívjuk a veletlen objektumon. A példánkban a generált számot a „szam” nevű változóban tároljuk.

A nextInt() metódusnak paraméterként 3-at megadva 0 és 2 közötti értéket kaphatunk.

1 és 6 közötti szám előállítása ezek után:

Random veletlen = new Random();
int dobas = veletlen.nextInt(6) + 1;

A következő táblázatban a Random osztály további metódusait láthatjuk. A „veletlen” objektum helyett, azonban csak egy „r” nevű objektumot használunk a rövidség miatt.

Visszatérés típusa Hívás Leírás
int i = r.nextInt(int n) int >= 0 és < n közötti véletlen számot ad vissza
int i = r.nextInt() a teljes int tartományból ad vissza véletlen számot
long l = r.nextLong() a teljes long tartományból ad vissza véletlen számot
float f = r.nextFloat() float >= 0.0 és < 1.0 közötti véletlen számot ad vissza
double d = r.nextDouble() double >= 0.0 és < 1.0 közötti véletlen számot ad vissza
boolean b = r.nextBoolean() true vagy false értékkel tér vissza véletlenszerűen
double d = r.nextGaussian() 0.0 és szabályos eltéréssel 1.0 közötti véletlen eltéréssel tér vissza

Math osztály

A Math.random() 0.0…0.999999 között állít elő egy számot.

double a = Math.random();
System.out.printf("%.20f\n", a);

A következő kimenetet adja:

0,509873801078128200000

Ha négyel szoroztam volna a számot:

double a = Math.random();
System.out.printf("%.20f\n", a * 4);

Kimenet például:

2,03949520431251270000

A szám egész része egy 0 és 3 közötti szám.

Ebből lehet egy egész véletlen számom.

Esetleg így is írhatjuk:

double a = 4 * Math.random();
System.out.println(a);

Ha mindig hozzáadunk 1-t, akkor 1 és 4 közötti számot kapunk:

double a = 4 * Math.random() + 1;
System.out.println(a);

Példa 1 és 10 közötti egész szám előállítására:

szam = (int) (10 * Math.random()) + 1;

Gyakorlat

  • Mit állít elő a Math.random() metódus?
  • Generáljon 10 és 20 között egy számot.
  • Milyen osztályokkal állíthatunk elő véletlen számokat?
  • Mondjon két példát a Random osztály metódusaira.
  • Szükséges-e példányosítani a Random osztályt használatához?

Java operátorok

Operátorok

Értékadó operátor

= Egyszerű értékadás

Az értékadást általánosan így írhatjuk le:

<változó> = <kifejezés> 

Lássunk néhány konkrét példát a használatára:

int a, b;
a = 2;     // 2 értéket hozzárendeljük az a változóhoz
b = 5;     // 5 értéket hozzárendeljük a b változóhoz
Home home1 = new Home();  // új objektum készítése
Home home2 = home1;       // home1 referencia home2-be rendelése

Aritmetikai operátorok

+ összeadás (karaktersorozatok összefűzésére is használjuk
- kivonás
* szorzás
/ osztás
% maradékképzés

Egyoperandusú operátorok

+ Unary plusz operator; az értéket adja
- Unary mínusz operator; előjelet vált, vagyis az értéket negálja
++ inkrementáló operátor; az inkremens értéke: 1
-- dekrementáló operátor; a dekremens értéke: 1
! logikai ellentét; a logikai értéke ellentétes értékét adja

A (+) egyoperandusú operátort a C nyelvben tették szabvánnyá először a (-) operátor ellentéteként csak a szimetria kedvéért. A (+) operátor használata így nem tesz semmit az értékkel, azt kapjuk ami van.

A (!) operátor az ellentétére fordít egy logikai értéket. A true értékből false értéket csinál és fordítva. Teszteljük a következő programmal:

System.out.println(true);
System.out.println(!true);
 
System.out.println(false);
System.out.println(!false);

Egyenlőség és összehasonlító operátorok

== egyenlő
!= nem egyenlő
> nagyobb mint
>= nagyobb vagy egyenlő
< kisebb mint
<= kisebb vagy egyenlő

Az egyenlő operátor visszaad egy true vagy false értéket, attól függően igaz-e amit állítunk.

int a = 4;
System.out.println(a == 3);

A következő program ugyanígy true vagy false értéket ír ki, de most az ellentétére kérdezünk:

int a = 4;
System.out.println(a != 3);

A többi logikai operátor is hasonlóan használható.

Feltételes operátorok

&& feltételes ÉS
|| Feltételes VAGY
?: Hármas operátor (az if-then-else rövid változata)

Az && operátor feltételes ÉS, amelyet két logikai állítás között szoktunk használni. A következő példában két állítást teszünk. Először azt állítjuk, hogy az „a” értéke 3, majd b értéke 4. Ha mindkettő igaz lenne, akkor kapnánk igaz értéket a teljes kifejezésben:

int a = 4;
int b = 4;
System.out.println(a == 3 && b == 4);

A példánkban false értéket kapunk, mert az a változóban nem 3-as érték szerepel.

Típusvizsgáló operátor

instanceof Egy objektumot egy megadott típushoz hasonlít

Bitmozgató és bitenkénti operátorok

~ komplemensképzés bitenként (unary; egyoperandusú)
<< előjeles balra mozgatás (shift)
>> előjeles jobbra mozgatás (shift)
>>> előjel nélküli jobbra mozgatás (shift)
& bitenkénti ÉS
| bitenkénti VAGY
^ bitenkénti Kizáró VAGY

Precedencia

Ha egy kifejezésben több operátor is van, akkor el kell dönteni, mi lesz az operátorok végrehajtásának sorrendje. Ezt nevezzük precedenciának. Az alábbiakban a Java nyelv precedencia táblázatát látjuk:

++ --
! ~
instanceof
(pre- vagy poszt-) inkremens és dekremens,
logikai és bitenkénti negálás,
típus ellenőrzés
* / % szorzás, osztás, moduló
+ - összeadás, kivonás
<< >> >>> bitenkénti léptetések
< > >= <= összehasonlítások
== != egyenlő, nem egyenlő
& bitenkénti AND
^ bitenkénti XOR
| bitenkénti OR
&& logikai AND
|| logikai OR
? : feltételes kifejezés
= += -= *= /= %= ^=
&= |= <<= >>= >>>=
különböző értékadások

A táblázatban legfelül látjuk azokat amelyek hamarabb végrehajtásra kerülnek. Mi történik akkor, ha azonos precedenciaszintű operátorokból van több? Ebben az esetben azok balról jobbra, sorba egymás után hajtódnak végre.

Lássunk egy példát:

int szam = 1 + 2 + 3;
System.out.println(szam);

Az utasítások balról jobbra végrehajtódnak, de nekünk persze mindegy, mert az eredmény ugyanaz, ha először a második összeadás hajtódik végre.

A következő példában viszont nem mindegy melyik operátor hajtódik először végre:

int szam = 1 + 2 * 3;
System.out.println(szam);

Ebben az esetben először a szorzás hajtódik végre, majd az összeadás.

A zárójelekkel azonban ezen változtathatunk:

int szam = (1 + 2) * 3;
System.out.println(szam);

Először a zárójelen belüli összeadás kerül végrehajtásra, majd a szorzás.

Az inkrementáló és dekrementáló operátorok

Adott a következő Java programrészlet:

int a = 3;
b = a++;

Jó kérdés lehet, hogy milyen érték kerül a b változóba. A kérdés úgy is feltehető, hogy az „++” operátor mikor növeli az „a” változó értékét? Mielőtt átadja az értékét „b” változónak, vagy csak utána. A helyes válasz csak utána. A b változóba tehát 3 kerül, utána növeli a ++ operátora az „a” változó tartalmát.

Ezzel ellentétes viselkedés is elérhető, ha az ++ operátort nem a változó utána, hanem az előtt szerepeltetjük:

int a = 3;
b = ++a;

Ebben az esetben a „b” változó értéke 4 lesz, mivel az operátor előbb növelte „a” értékét, majd ez az érték került átadásra.

A „–” operátor használata megegyezik a „++” használatával, ebből a szempontból.

Bitműveletekre példa

Program02.java
class Program02 {
	public static void main(String[] args) {
		int a = 3;
		int b = ~a;
		System.out.printf("%32s\n", Integer.toBinaryString(a));
		System.out.printf("%32s\n", Integer.toBinaryString(b));
	}
}
Program01.java
//Előjeles balra mozgatás (baloldalon mindig az előjel bit jön be)
class Program01 {
	public static void main(String[] args) {
		int a = 3; //Próbáljuk ki negatív értékkel
		int b = a << 2;
		System.out.printf("%4s\n", Integer.toBinaryString(a));
		System.out.printf("%4s\n", Integer.toBinaryString(b));
	}
}
//A baloldali első bit az előjel bit negatív számok esetén 1, pozitív esetén 0.
Program03.java
//Előjel nélküli jobbra mozgatás (baloldalon mindig 0 jön be)
class Program03 {
	public static void main(String[] args) {
		int a = 14;
		int b = a >>> 1;
		System.out.printf("%32s\n", Integer.toBinaryString(a));
		System.out.printf("%32s\n", Integer.toBinaryString(b));
	}
}
Program03.java
//Előjeles jobbra mozgatás
class Program03 {
	public static void main(String[] args)
	{
		int a = 14;
		int b = a >> 1;
		System.out.printf("%32s\n", Integer.toBinaryString(a));
		System.out.printf("%32s\n", Integer.toBinaryString(b));
	}
}

Feltételes értékadás

A feltételes operátor tulajdonképpen az if-then-else hasonlata. Van egy feltétel a kérdőjel előtt. Ha igaz, akkor az első értéket kapj az egyenlőség baloldalán álló „b” változó. Ne nem igaz, akkor a kettőspont utáni értéket kapja.

Program.java
class Program {
	public static void main(String[] args) {
		int a = 8;
		String b =  a > 5  ?  "Nagyobb"  :  "Kisebb";
		System.out.println(b);
	}
}

Az instanceof operátor

Program01.java
class Program01 {
	public static void main(String[] args) {
		Integer a = 3;
 
		System.out.println(a instanceof Integer);
	}
}

Primitív típussal nem működik a instanceof operátor!

A mellékletek részben találunk egy sokkal hasznosabb példát az operátor használatára. A jelen példának azért nincs sok értelme, mert az Integer helyett nem is tudunk mást írni.

Művelettel kombinált értékadás

Legyen egy „a” változó, amelynek értékét szeretnénk 2-el növelni. Ekkor ezt írnánk:

int a = a + 2;

Ennek van egy rövidebb formája:

int a += 2;

A plusz jelet az egyenlőség jel elé tesszük, az „a” változóba pedig csak egyszer írom le.

Lehetséges kombinált értékadó operátorok:

+= -= *= /= %= &= ^= |= <<= >>=

Ternary

Hármas operátor. Ennek az operátornak három operandusa van, ezért a neve.

Az operátor egy kérdőjelből és egy kettőspontból áll:

? :

Használatát lásd a szelekciónál.

Gyakorlat

  • A bitenkéni AND vagy a logikai AND van előrébb a prioritási sorban?
  • A logikai AND vagy a logikai OR van a prioritási sorban előbb?
  • Mire való az instaceof változó?
  • Mutassa be hogyan működik a feltételes értékadás.
  • Mi a különbség a » és a »> operátor között?

Konvertálás

Sztring egész számmá

System.out.println(Integer.parseInt("89"));
String s = "25";
int a = Integer.valueOf(s).intValue();

A valueOf() egyik prototípusa:

static Integer valueOf(String s) 

Visszatér egy karaktersorozat számértékével egy Integer objektumban eltárolva.

Az intValue() metódussal primitív int típussá alakítjuk.

Az intValue()prototípusa:

int intValue()
String s = "87";
System.out.println(Integer.parseInt(s));

Szöveges formában tárolt valós számot alakítunk egésszé.

int a = Float.valueOf( "799.87" ).intValue();

Sztring valós számmá

System.out.println(Double.parseDouble("89.5"));
Double d = Double.valueOf(str).doubleValue();
Float f = Float.valueOf(str).floatValue();

Sztring hosszú egésszé

  long l = Long.valueOf(str).longValue();
 
  Long l = Long.parseLong(str);

Egész sztringgé

System.out.println(Integer.toString(77));

Valós sztringgé

System.out.println(Float.toString(77.88));

Dupla sztringgé

System.out.println(Double.toString(77.88));
 
double a = 3; 
System.out.println(Double.toString(a));

Hosszú egész sztringgé

Long a = 7L;
String str = Long.toString(a);

Hexadecimális sztring egésszé

int a = Integer.valueOf("B8DA3", 16).intValue();
int a = Integer.parseInt("B8DA3", 16); 

A következő sor például a 11-et ír a képernyőre:

System.out.println(Integer.parseInt("B", 16));

Karakter sztringgé

String s = String.valueOf('c');

Karakter ASCII kóddá

char ch = 'A';
int b = ch;
System.out.println(b); //Az eredmény: 97

vagy:

char ch = 'A';
int b  = (int) ch; 
System.out.println(b); //Az eredmény: 97

Egész (ASCII kód) karakterré

int a = 97;
char ch = (char)a;
System.out.println(ch); //Az eredmény: a

Sztring ASCII kóddá

String str = "ABCD";
for ( int i = 0; i < str.length(); ++i ) {
     char c = str.charAt(i);
     int j = (int) c;
     System.out.println(j);
}

Egész logikai típussá

int a = 2;
boolean b = (a != 0);

A nulla érték mindig hamis lesz. Az ettől eltérő pedig igaz.

Logikai típus egésszé

boolean a = true;
int b = a ? 1 : 0;

A true és a false a következő módon alakul át:

  • true –> 1
  • false –> 0

Illegális karakterkonverzió vizsgálata try/catch mechanizmussal

try {
    a = Integer.parseInt(str);
} catch(NumberFormatException e) {
 
}

Sztring bájt formára konvertálása

String s = "some text here";
byte[] b = s.getBytes("UTF-8");

Bájt Sztring formára konvertálása

byte[] b = {(byte) 99, (byte)97, (byte)116};
String s = new String(b, "US-ASCII");

Az US-ASCII helyett lehet „UTF-8” is

Valós egészé

Double a = 3.8;
int b = Double.valueOf(a).intValue();
Float a = 3.8f;		
int b = Float.valueOf(a).intValue();
double a = 3.8;
int b = (int) a;

Egyéb lehetőség

Decimális binárissá

Konvert.java
import java.io.*;
 
class Konvert {
    public static void main(String args[]) throws IOException {
		int i = 2;
		String bin = Integer.toBinaryString(i);
		System.out.println(bin);
 
		System.in.read();
    }
}

Decimális hexadecimálissá

Konvert.java
import java.io.*;
 
class Konvert {
    public static void main(String args[]) throws IOException {
		int i = 11;
		String bin = Integer.toBinaryString(i);
		System.out.println(bin);
 
		String hexstr = Integer.toHexString(i);
		System.out.println(hexstr);
 
		System.in.read();
    }
}

Bináris string számmá

String s = "1000100010000000";
int a = Integer.parseInt(s, 2);

Gyakorlat

  • Hogyan konvertálunk karaktersorozatot egész számmá?
  • Hogyan konvertálunk karaktersorozatot egész valós?
  • Hogyan konvertálunk valós számot karaktersorozattá?
  • Hogyan konvertálunk egész számot karaktersorozattá?
  • Hogyan konvertálunk karaktert karaktersorozattá?

Bevitel a billentyűzetről

A Java nyelven az olvasás a billentyűzetről nem egyszerű feladat. Van ugyan az in mezőnek egy read() metódusa, de az csak egyetlen bájtot olvas be. Ha ezzel kérnénk be egy számot, azt utána még át kellene konvertálnunk számmá. A System.in.read() metódust így legfeljebb arra használjuk, hogy várjunk egy „Enter” lenyomására.

Az util csomag használata

Egy egész szám bekérése

Program01.java
import java.util.Scanner;
 
class Program01
{
    public static void main(String args[])
    {
        Scanner bevitel = new Scanner(System.in);
 
        System.out.print("Egész szám: ");
	int a = bevitel.nextInt();
 
	System.out.println(a);
 
     }
}

Egy valós szám bekérése

Program02.java
import java.util.Scanner;
 
class Program02
{
    public static void main(String args[])
    {
        Scanner bevitel = new Scanner(System.in);
 
	System.out.print("Valós szám: ");
	double b = bevitel.nextDouble();
	System.out.println(b);
     }
}

Egy karaktersorozat bekérése

Program03.java
import java.util.Scanner;
 
class Program03
{
    public static void main(String args[])
    {
        Scanner bevitel = new Scanner(System.in);
 
	System.out.print("Szöveg: ");
	String s = bevitel.nextLine();
	System.out.println(s);
     }
}

Egész és valós bekérése

Program04.java
import java.util.Scanner;
class Program04
{
	public static void main(String args[])
	{
		Scanner bevitel = new Scanner(System.in);
 
		System.out.print("Egész szám: ");
		int a = bevitel.nextInt();
 
		System.out.print("Valós szám (vesszővel írjuk a tizedesvesszőt): ");
		double b = bevitel.nextDouble();
 
		System.out.println(a + b);
	}
}

Két karakter sorozat bekérése

Program05.java
import java.util.Scanner;
class Program05
{
	public static void main(String args[])
	{
		Scanner bevitel = new Scanner(System.in);
 
 
		System.out.print("Szöveg: ");
		String s1 = bevitel.nextLine();
 
		System.out.print("Szöveg: ");
		String s2 = bevitel.nextLine();
 
		System.out.println(s1 + " " + s2);
	}
}

Karakter bekérése

A Scanner osztállyal nem tudunk karaktert bekérni, bár megtehetjük, hogy egy beolvasott karaktersorozat első elemét vesszük:

Program06.java
import java.util.Scanner;
 
class Program06
{
	public static void main(String args[])
	{
		Scanner olvaso = new Scanner(System.in);
 
		char ch = olvaso.nextLine().charAt(0);
 
		System.out.println("Olvasott: " + ch);
	}
}

Ez persze nem túl elegáns.

Az io csomag használata

Az io csomagból a BufferedReader és az InputStreamReader osztályokat vesszük segítségül. Az io csomag osztályait nem használhatjuk kivételkezelés nélkül. A programot fel kell készítenünk a kivételek kezelésére vagy eldobására. A kivételek tulajdonkképpen hiba esetén keletkeznek.

A példaprogramunkban kivételeket nem kezelünk így el kell azokat dobni. A metódus fejrészének a végére írjuk: „throws IOException.

Program01
import java.io.*;
 
public class Program01
{
    public static void main(String[] args) throws IOException
    {
        InputStreamReader befolyam = new InputStreamReader(System.in);
        BufferedReader bemenet = new BufferedReader(befolyam);
        String s;
        int szam;
 
        System.out.print("Szám: ");
        s = bemenet.readLine();
        szam = Integer.valueOf(s).intValue();
 
        System.out.println("Ezt írtad: " + szam);
    } /* main vége */
} /* Fő osztály vége*/

Amit még felfedezhetünk, hogy a bekéréshez két osztály szükséges.

A következő kód megegyezik az előzővel, de az InputStreamReader deklarációt beágyaztuk a BufferedReader részbe.

import java.io.*;
 
public class ap 
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader bemenet = new BufferedReader(new InputStreamReader(System.in));
        String s;
        int szam;
 
        System.out.print("Szám: ");
        s = bemenet.readLine();
        szam = Integer.valueOf(s).intValue();
 
        System.out.println("Ezt írtad: " + szam);
    } /* main vége */
} /* Fő osztály vége*/
konzol.java
import java.io.*;
class Program
{
	public static void main(String args[])
	{
		Console console = System.console();
                System.out.print("Szöveg: ");
		String str = console.readLine();
		System.out.println(str);
	}
}

System.console() metódus

Beolvasásra használható a System.console() metódus. Ez a metódus egy Console osztályt ad vissza, amelyen van egy readLine() metódusa, amely már alkalmas beolvasásra.

Program01.java
class Program01
{
	public static void main(String args[])
	{		
		System.out.print("Név: ");
		String nev = System.console().readLine();
 
		System.out.println("Ezt írtad: " + nev);
	}
}

A bekéréssel együtt írhatunk is a képernyőre a bekérés előtt:

Program01.java
class Program04
{
	public static void main(String[] args)
	{
		String szamStr = System.console().readLine("Kerek egy szamot: ");
		System.out.println("Ezt irtad: " + Integer.parseInt(szamStr));
	}
}

A readLine() valójában formázott bemenetre képes.

Console osztály

Karaktersorozat bekérése

Program.java
import java.io.Console;
 
class Program
{
	public static void main(String args[])
	{
		Console kon = System.console();
 
		System.out.print("Név: ");
		String szoveg = kon.readLine();
 
		System.out.println("Neved: " + szoveg);		
	}
}

Egész szám bekérése

Program.java
import java.io.Console;
 
class Program
{
	public static void main(String args[])
	{
		Console kon = System.console();
 
		System.out.print("Szam: ");
		int szam = Integer.parseInt(kon.readLine());
 
		System.out.println("Duplája: " + szam * 2);		
	}
}

Karakterek bekérése

char ch;
 
System.out.print("Karakter: ");
ch = (char) System.in.read(); System.in.read();
System.out.println("A beírt karakter: " + ch);
 
System.out.print("Karakter: ");
ch = (char) System.in.read(); System.in.read();
System.out.println("A beírt karakter: " + ch);
 
System.out.print("Karakter: ");
ch = (char) System.in.read();
System.out.println("A beírt karakter: " + ch);

Ha több karaktert kérünk be az első karakter leütése után a leütött „Enter” a billentyűzet pufferben marad. Így következő billentyűzetről olvasás nem vár billentyűnyomásra, hanem tovább lép. Ezt az „Enter” billentyűt kiolvassuk a bekérés után tett System.in.read() utasítással.

Komplett példa:

Program.java
import java.io.*;
 
class Program
{
	public static void main(String args[]) throws IOException
	{
		System.out.print("Karakter: ");
		char ch1 = (char) System.in.read(); System.in.read();
 
		System.out.print("Karakter: ");
		char ch2 = (char) System.in.read(); System.in.read();
 
		System.out.print("Karakter: ");
		char ch3 = (char) System.in.read(); System.in.read();
 
		System.out.println("A beírt karakterek: " + ch1 + " " + ch2 + " " + ch3);
	}
}

Karakterbekérés két másik módja:

ch = (char) System.console().reader().read(); //Java 6

A következő megoldás nem hagyja az Entert a billentyűzetpufferben.

ch = (char) new InputStreamReader(System.in).read();
Program.java
import java.io.*;
 
class Program
{
	public static void main(String args[]) throws IOException
	{
 
		char ch;
 
		System.out.print("Karakter: ");		
		ch = (char) System.console().reader().read();
		System.console().reader().read();
		System.out.println(ch);
 
		System.out.print("Karakter: ");		
		ch = (char) System.console().reader().read(); 
		System.console().reader().read(); 
		System.out.println(ch);
 
		System.out.print("Karakter: ");		
		ch = (char) new InputStreamReader(System.in).read();
		System.out.println(ch);
 
		System.out.print("Karakter: ");		
		ch = (char) new InputStreamReader(System.in).read();
		System.out.println(ch);
	}
}

Újabb példa:

Program.java
import java.io.*;
 
class Program
{
	public static void main(String args[]) throws IOException
	{
		System.out.print("Karakter: ");
		char ch1 = (char) new InputStreamReader(System.in).read();
 
		System.out.print("Karakter: ");
		char ch2 = (char) new InputStreamReader(System.in).read();
 
		System.out.print("Karakter: ");
		char ch3 = (char) new InputStreamReader(System.in).read();
 
		System.out.println("A beírt karakterek: " + ch1 + " " + ch2 + " " + ch3);
	}
}

Gyakorlat

  • Soroljon fel osztályokat, amelyekkel megvalósítható bekérés.
  • A Scanner osztállyal milyen primitív típust nem tudunk bekérni?
  • Írjon példát a egy karakter sorozat bekérésére.
  • Ha egy bejövő szám adatot karaktersorozatként kapunk meg, hogyan tudjuk átkonvertálni szám típussá?

Szelekció

A szelekcióról

Alapesetben a program forráskódjában az utasítások egymás után sorban hajtódnak végre futtatáskor. Ezt nem mindig szeretnénk. Lesznek olyan utasítások, amelyek végrehajtását bizonyos feltételhez akarjuk majd kötni. Ha feltétel teljesül akkor végrehajtjuk az utasítást vagy utasításokat, ha nem akkor nem teszünk semmit, vagy éppen az utasítások egy másik csoportját akarom végrehajtani.

Vegyünk egy egyszerű iskolapéldát. Szeretném eldönteni egy változóról, hogy kisebb számot tartalmaz-e mint 100. Ha kisebbet, akkor szeretném kiírni, hogy kisebb. Ehhez tennem kell egy állítást. Például, legyen az „a” változó amit vizsgálok. Azt állíthatom például, hogy kisebb:

a < 100

Ez vagy igaz, vagy hamis állítás. Szükségünk van a Java nyelvben egy olyan utasításra, amellyel ezt képesek vagyunk megvizsgálni. Ez lesz az if.

if

Az if utasítással meg tudjuk vizsgálni, hogy egy állítás igaz, vagy hamis. Az állítást, mindig zárójelek közzé kell tennünk, az if után:

if (feltétel) utasítás;

A zárójel után jöhet az utasítás. Az utasítást persze tehetjük a következő sorba is, ha úgy átláthatóbb:

if (feltétel) 
    utasítás;

Előfordul, hogy nem egy hanem több utasítást akarunk végrehajtani a feltétel teljesülése esetén. Az utasításokat ilyenkor blokk nyitó és blokk záró karakterek közzé teszem:

if (feltétel)
{
    utasítás_1;
    utasítás_2;
    ...
    utasítás_n;
}

A kapcsos zárójel jelzi, hogy a közzé zárt utasításokat együtt szeretném kezelni.

A következő lehetséges eset, hogy ha feltétel nem teljesül, akkor is szeretnék valamilyen utasításokat végrehajtani. Ekkor az utasítás után egy „else” kulcsszó után írom ezeket az utasításokat.

if (feltétel)
    utasítás_1;
else
    utasítás_2;

Ha a feltétel teljesül, akkor az első utasítás hajtódik végre, ha nem, akkor a második, azaz az „else” utáni utasítás.

Ugyanez több utasítással:

  if (feltétel)
  {
      utasítás_1;
      utasítás_2;
      ...
      utasítás_n;
  }
  else
  {
      utasítás_1;
      utasítás_2;
      ...
      utasítás_m;
  }

Eddig az szelekciónak csak a szintaxisát mutattuk be. Álljon itt egy konkrét példa a az if használatára:

Szelekció példa

szel.java
import java.util.*;
class szel
{
        public static void main(String args[])
        {
                Scanner bevitel = new Scanner(System.in);
                System.out.println("Szelekció");
 
		System.out.print("Szám: ");
		int szam = bevitel.nextInt();
 
		if(szam >0)
			System.out.println("Pozitív");
		else
			System.out.println("0 vagy negatív");
 
        }
}

A program bekér egy számot, majd megvizsgálja, hogy pozitív szám, nulla vagy negatív számot írt be a felhasználó. Bekéréshez a Scanner osztályt használtam.

else if

Többágú szelekció else if szerkezettel.

Ha több feltételnek is meg kell feleljünk, akkor egy első if utasítás után else if utasításokat használunk. Általánosan:

if (feltétel_1)
    utasítás_1;
else if (feltétel_2)
    utasítás_2;
else
    utasítás_3;

Egy konkrét példához nézzük egy problémát. A fentebb volt egy feladatunk ahol azt vizsgáltuk, hogy egy szám pozitív vagy más. A program arra már nem volt képes, hogy azt is megvizsgálja, hogy ha nem pozitív, akkor 0 vagy negatív!?! Az „else if” szerkezet lehetőséget ad erre, mert újabb feltételt tudunk beilleszteni.

tobbagu.java
import java.util.Scanner;
class tobbagu
{
	public static void main(String args[])
	{
		Scanner olvaso = new Scanner(System.in);
 
		System.out.print("Szám: ");
		int szam = olvaso.nextInt();
 
		if(szam > 0)
			System.out.println("Pozitív szám");
		else if(szam == 0)
			System.out.println("Nulla");
		else
			System.out.println("Negatív szám");
	}
}

Ugyanaz csak a bekérés más osztályokkal (Kezdőknek akik nem használtak Scanner osztályt.).

tobbagu2.java
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
class tobbagu2
{
	public static void main(String args[]) throws IOException
	{
		InputStreamReader folyam = new InputStreamReader(System.in);
		BufferedReader olvaso = new BufferedReader(folyam);
 
		System.out.print("Szám: ");
		int szam = Integer.parseInt(olvaso.readLine());
 
		if(szam > 0)
			System.out.println("Pozitív szám");
		else if(szam == 0)
			System.out.println("Nulla");
		else
			System.out.println("Negatív szám");
	}
}

switch

A switch utasítás szintén többágú szelekcióra lett kitalálva.

switch (kifejezés)
{
    case érték1 : utasítások; break;
    case érték2 : utasítások; break;
    ...
    case értékn : utasítások; break;
    default : utasítások; 
}

Switch példa

sw.java
class sw
{
        public static void main(String args[])
        {
                System.out.println("Hi");
		int a = 7;
 
		switch(a)
		{
			case 1 : System.out.println("Egy"); break;
			case 2 : System.out.println("Kettő"); break;
			case 3 : System.out.println("Három"); break;
			case 4 : System.out.println("Négy"); break;
			default : System.out.println("Ismeretlen");
		}				
        }
}

A fenti program megvizsgálja, hogy az „a” változóban milyen szám van. Ha 1 akkor kiírja az „Egy” karaktersorozatot a képernyőre. Ha 2 akkor a „Kettő” karaktersorozatot, stb. Ha egyik sem – mint a példában is – akkor az „Ismeretlen” karaktersorozatot írja ki.

A vizsgált változót a switch utáni zárójelek közzé írjuk. A case után írjuk szóközzel tagolva a feltételezett értékeket. A default után jönnek azok az utasítások, amelyek akkor hajtódnak végre, ha egyik feltétel sem teljesült.

Vegyük észre minden kiírató utasítás után a break utasítást. Mit csinál a break utasítást? A brak utasítás megszakítja az utasítások végrehajtását és újból a switch részhez ugrik. Hogy jobban megértsük változtassuk kissé meg a példánkat. Tegyük az „a” változóba a 2-es értéket. A case 2 : végén lévő break utasítást pedig töröljük:

sw2.java
class sw2
{
        public static void main(String args[])
        {
		int a = 2;
 
		switch(a)
		{
			case 1 : System.out.println("Egy"); break;
			case 2 : System.out.println("Kettő");
			case 3 : System.out.println("Három"); break;
			case 4 : System.out.println("Négy"); break;
			default : System.out.println("Ismeretlen");
		}				
        }
}

Végrehajtás után az eredmény a következő:

Kettő
Három

A következő, azaz a case 3 : utáni utasítás is végrehajtódott. Ez éppen a berak utasítás hiány miatt történt. A szerkezetet pont ilyen esetekre hozták létre. Ha az „a” változó értéke „2” és szeretnénk ebben az esetben „Kettő” és „Három” karaktersorozatot is a képernyőre írni.

A switch utasítás a következő primitív típusokkal működik:

  • byte
  • short
  • char
  • int

Használható még a következő felsorolt típusokkal és a primitív típusok wrapper osztályaival Byte, Short, Char, Integer. A Java SE 7-es verziótól használható String osztállyal is.

Ternary operátor

Általánosan:

állítás ? érték_ha_igaz : érték_ha_hamis

A kifejezés visszaadja az első vagy második értéket, attól függően, hogy az állítás igaz, vagy hamis.

A kapott érték eltárolható egy változóban:

változó = állítás ? érték_ha_igaz : érték_ha_hamis
Program01.java
class Program01
{
	public static void main(String[] args)
	{
		int a = 3;
		String e = (a > 10) ? "Nagyobb" : "Kisebb";
		System.out.println(e);
	}
}

A program egyenértékű a következő if-es megoldással:

Program01.java
class Program01
{
	public static void main(String[] args)
	{
		int a = 35;
		String e = null;
		if (a > 10) 
			e = "Nagyobb";
		else
			e = "Kisebb";
 
		System.out.println(e);
	}
}

Gyakorlat

  • Hányféle szelekciós utasítás van a Java nyelvben?
  • Mi az a ternary operátor?
  • Egy if szelekció törzs részének elejét és végét mivel jelöljük a Java nyelvben?
  • Egy if szerkezetben a kapcsos zárójelek {} kötelezőek a Java nyelvben egy utasítás esetén?
  • Egy if szerkezetben mire való az else?
  • Az if szerkezetben kötelező az else ág használata?
  • A swicth utasításban milyen típusú változókat vizsgálhatunk a Java nyelvben?

Iteráció

Az iterációról

Az iteráció vagy ismétlés, amely ciklus néven ismert még.

Lesznek utasítások, amelyeket többször végre akarunk hajtani majd. Egyes esetekben tudni fogjuk hányszor, máskor pedig nem tudjuk hányszor, csak várunk valamilyen esemény bekövetkeztére. Az első eset a növekményes ciklus, a második pedig az „amíg” típusú ciklus.

for

A for utasítást jellemzően olyan ciklusoknál használjuk, ahol tudjuk meddig kell ismételni, azaz növekményes ciklusok esetén.

for ( kezdeti_érték ; feltétel ; növekmény)
    utasítás;

A for utasításnak három paramétere van. A három paramétert pontosvesszővel (;) választjuk el egymástól. A három paraméter a következő:

  • kezdő érték
  • feltétel (meddig menjünk)
  • növekmény

Ha már számolnunk kell hányszor hajtunk végre az utasításokat, akkor kell egy változó ahol ezt tárolni fogjuk. Gyakran erre a célra az „i” változót használjuk. Az „i” változónevet egy programban csak ciklusváltozóként szoktuk használni. A Java fordító erre nem kötelez, de jó szokás. Ha az „i” foglalt, akkor a következő „j”. Ha ez is foglalt, akkor „k”. Ennél több eset ritka, de van még betű az ábécében.

A következő példában az „i” változót használjuk ciklusváltozónak:

for ( i = 1; i <= 10 ; i++)
    System.out.println("Város");

Az i változót persze valahol deklarálni kell. A Java nyelv megengedi, hogy ezt a ciklus fejrészében (a ciklus zárójelben lévő része) tegyük:

for ( int i = 1; i <= 10 ; i++)
    System.out.println("Város");

Hasonlóan az if szerkezethez, itt is írhatunk több utasítást is a ciklus törzsébe (egy utasítás esetén, maga ez az egy utasítás a törzs, több utasítás esetén a blokk nyitótól a blokk záróig tart.

for ( int i = 1; i <= 10 ; i++)
{
    System.out.println("Város");
    System.out.println("Cím");
}

A fenti példákban a ciklustörzsben lévő utasítás, illetve utasítások 10-szer hajtódnak végre. Ezt a következő fejrésszel értük el:

for ( int i = 1; i <= 10 ; i++)

Ugyanez elérhető így is:

for ( int i = 0; i < 10 ; i++)

Vegyük észre a különbséget. A kezdő érték az utóbbi esetben 0, és addig megy a ciklus amíg kisebb mint 10, tehát 9-ig.

while

A while ciklus alapvetően „amíg” típusú ciklusok használatára találták ki.

A while ciklus általánosan így épül fel:

while (feltétel)
    utasítás;

Egy konkrét példa

i = 1;
while (i <= 10)
{
    System.out.println("Város");
    i++;
}

A példában szereplő while ciklus ugyanazt csinálja mint a fentebbi programok legtöbbje. Itt is tudjuk meddig megyünk. A while utasítást úgy használtuk mint a for-t. Csak a kezdőértéket a ciklus előtt adtam meg, a növekményt meg a ciklus törzsében.

Ez persze még nem az „amíg” típusú ciklus. Az „amíg” típusú ciklusnál nem tudjuk meddig megyünk. Várunk egy eseményre. A példa kedvéért a felhasználótól számokat kérünk be összeadás céljából. Nem tudjuk mennyit, majd a felhasználó eldönti. Ekkor valahogy biztosítanunk kell, hogy a bevitel végét jelezze. Ha 0 értéket nem vihet be a felhasználó, akkor használhatjuk ezt végjelnek.

Vagyis kérjük be sorra a számokat, amikor a felhasználó 0 számot üt be, akkor nem kérünk több számot. A következő példában a Scanner osztállyal kérünk be számokat 0 végjelig:

vegjelig.java
import java.*;
import java.util.*;
 
class vegjelig
{
	public static void main(String[] argv)
	{
		Scanner bevitel = new Scanner(System.in);
 
		int szam=-1;
		while(szam != 0)
		{
			System.out.print("Kovetkezo szam: ");
			szam = bevitel.nextInt();
		}
	}
}

A példában persze a bekért számokkal még nem csinálunk semmit. Szeretnénk összeadni a bekért számokat:

osszeg.java
import java.*;
import java.util.*;
 
class osszeg
{
	public static void main(String[] argv)
	{
		Scanner bevitel = new Scanner(System.in);
 
		int szam=-1;
                int osszeg = 0;
		while(szam != 0)
		{
			System.out.print("Kovetkezo szam: ");
			szam = bevitel.nextInt();
                        osszeg = osszeg + szam;
		}
                System.out.printf("%d\n", osszeg);
	}
}

Gyakorlásképpen összeadás helyett szorozza össze a bekért számokat. Bekérés közben ne írja ki a részeredményeket. Csak a ciklus végén írja ki a szorzatot.

do while

Az eddigi ciklusok úgynevezett elől tesztelő ciklusok voltak. Ez annyit tesz, hogy előbb megvizsgálták a feltételt, majd ha az igaz volt, végrehajtották a ciklustörzs utasításait. A most következő ciklus hátul tesztelő ciklus. A ciklus törzsében lévő utasítások egyszer mindenképpen végrehajtódnak, a feltétel csak ez után kerül vizsgálatra. Ha a feltétel igaz, akkor az ciklus törzsében lévő utasítások megint végrehajtódnak.

hatul.java
do
{
    utasítások;
}while(feltétel);

Vegyük észre, hogy ezt ciklust végén le kell zárni pontosvesszővel.

Konkrét példa a hátul tesztelésre:

hatul.java
import java.util.*;
class hatul
{
	public static void main(String args[])
	{
		Scanner bevitel = new Scanner(System.in);
		System.out.println("Hátul tesztelő ciklus");
 
		int szam;
		do
		{
			System.out.print("Szám: ");
			szam = bevitel.nextInt();
		}while(szam != 0);
	}
}

for újra

A for utasításnak van egy kiterjesztett változata, amely tömbök és kollekciók iterálására lett kitalálva. Angolosan enhanced for néven ismert. A következőben ennek a használatát látjuk.

Program01.java
class Program01
{
	public static void main(String args[])
	{
 
		String[] varos = {"Debrecen", "Nyíregyháza", "Zalaegreszeg", "Pécs", "Szeged"};
 
		for(String str : varos)
			System.out.println(str);
	}
}

A for() ciklus segítségével végtelen ciklust is előállíthatunk ha nem adunk meg paramétert:

for(;;){
   //ciklustörzs
}

Gyakorlat

  • Mit jelent az iteráció?
  • Hányféle iterációs utasítást ismert a Java nyelvben?
  • A for ciklusban hány alakja van a Java nyelvben?
  • Mi a különbség a do-while és while ciklus között?

Tömbök

A tömb azonos típusú értékeket tárolására alkalmas adatszerkezet. A tömböknek beszélünk a kiterjedéséről. Ha a kiterjedés csak egyirányú akkor vektorról beszélünk, ami hasonlít is a matematikában tanult vektorfogalomhoz. Ha a kiterjedés kétirányú akkor mátrixról beszélünk, szintén a matematikában használt mátrixhoz hasonlóan. A tömböknek lehet ennél több kiterjedése is, három, vagy akár több. De ezeket már ritkán szoktuk használni.

Vektorok

Egy tömb akkor vektor, ha egyirányú a kiterjedése. Például egész számokat szeretnénk eltárolni:

37 23 47 52 28

A példában öt darab egész számot szeretnénk tárolni.

A tömb egyes elemeivel szeretnénk valamit csinálni, így hivatkozni kell rájuk. Ezt úgy szoktuk megtenni, hogy minden értékhez egy indexet rendelünk. Az első érték indexe nulla, a következőé egy, aztán kettő, stb.

0 1 2 3 4
37 23 47 52 28
<elemi típus>[] <változó név>;

vagy

<elemi típus>  <változó név>[];

Konkrét példa:

int[] tomb;

vagy

int tomb[];

Kezdőérték adása

int[] tomb = {37, 23, 47, 52, 28};

De lehet így is:

int[] tomb = new int[] {37, 23, 47, 52, 28};

Más típussal:

long[] fizetesek = new long[] {10000, 20000, 30000, 40000};
int[] tomb =  {3, 4, 7, 8};

A Java tömböknek deklaráláskor nincs hely lefoglalva a memóriában. Ez a new kulcsszóval kell megtennünk. Pl.:

tomb.java
class tomb
{
	public static void main(String args[])
	{
		int[] tomb;
 
		tomb = new int[5];
 
		tomb[0]=37;
 
		System.out.println(tomb[0]);
	}
}
tomb2.java
class tomb2
{
	public static void main(String args[])
	{
		int[] tomb = new int[5];
 
		tomb[0]=37;
 
		System.out.println(tomb[0]);
	}
}

Tömb mérete

import java.lang.reflect.*;
...
System.out.println(Array.getLength(tomb));

Tömb feltöltése:

Program.java
import java.util.*;
 
class Program
{
	public static void main(String[] argv)
	{
		int[] tomb = new int[10];
 
		Arrays.fill(tomb, 5);
 
		for(int i=0; i<tomb.length; i++)
			System.out.print(tomb[i] + " ");
		System.out.println();
 
	}
}

A példában 5-ös számokkal töltjük fel a tömböt.

Java többdimenziós tömbök

1 2 3
2 4 6
3 4 7
5 6 7
Integer ars[][] = new Integer[4][3];  // Integer az int burkoló osztálya
int ars[][] = new int[][]{{1,3,3}, {2,4,6}, {3,4,7}, {5,6,7}};

Olyan mint egy 4 x 3 matrix

public class MultiDimensionalArrayExample 
{    
  public static void main(String[] args) 
  {
 
    int ars[][] = new int[][]{{1,2,3}, {2,4,6}, {3,4,7}, {5,6,7}};
 
    for(int i = 0; i < 4; i++) 
        for(int j = 0; j < 3; j++) 
            System.out.println(ars[i][j]);
  }
}

Tömb mérete

int tomb[][] = new int[8][4];
System.out.println(tomb.length);           // 8-at ír ki
System.out.println(tomb[0].length);        // 4-et ír ki

Tömb átméretezése

A Java egyszerű tömbjeit nem arra találták ki, hogy később átméretezzük őket. Az átméretezés azért megoldható:

int ujHossz = 20;
int eredetiHossz = tomb.length;
Class componentType = tomb.getClass().getComponentType();
Object tomb2 = Array.newInstance(componentType, ujHossz);				
int vedettHossz = Math.min(eredetiHossz,ujHossz);
if (vedettHossz > 0)
	System.arraycopy(tomb, 0, tomb2, 0,  vedettHossz);		
tomb = (int[]) tomb2;

A komplett program működés közben:

tombmeret.java
class tombmeret
{
 
        private static Object resizeArray (Object oldArray, int newSize)
        {
                int oldSize = java.lang.reflect.Array.getLength(oldArray);
                Class elementType = oldArray.getClass().getComponentType();
                Object newArray = java.lang.reflect.Array.newInstance(
                                          elementType,newSize);
                int preserveLength = Math.min(oldSize,newSize);
                if (preserveLength > 0)
                        System.arraycopy (oldArray,0,newArray,0,preserveLength);
                return newArray;
        }
 
        public static void main(String[] args)
        {
                int[] tomb = new int[10];
 
                tomb[0] = 35;
                tomb[1] = 27;
                tomb[2] = 42;
 
                System.out.println(tomb.length);
 
                tomb = (int[]) resizeArray(tomb, 20);
                System.out.println(tomb.length);
        }
}

Látjuk, hogy az ilyen egyszerű tömbök nem méretezhetők át könnyen. Ha méretezhető tömböt szeretnénk, akkor használjuk az ArrayList vagy a Vector osztályt, az util csomagból. Ezek átméretezése automatikus.

Tömb feltöltése

Az Arrays osztály arra való, hogy tömbökön végezzünk néhány műveletet. Ez lehet annak feltöltése.

int[] tomb = new int[10];
java.util.Arrays.fill(tomb, 0);

Tömb paraméterként kezdőértékkel

method(new Object[] { a, b, c});

Egyéb tömbök

ArrayList

A tömblisták (ArrayList) automatikusan átméreteződnek, ezzel nem kell foglalkoznunk. Mérete mindig az elemek számától függ. Az egyes elemeket mindössze fel kell venni vagy törölni. Egy ilyen változó deklarálásánál meg kell adnunk milyen típusú elemet szeretnénk tárolni kisebb-mint és nagyobb-mint jelek között. A következő példában például karaktersorozatot szeretnénk tárolni:

ArrayList<String> tomb = new ArrayList<String>();

Vagy egészek tárolása

ArrayList<Integer> tomb = new ArrayList<Integer>();

Lássuk az alábbi példában egy komplett programot:

Program.java
import java.util.*;
 
class Program
{
	public static void main(String[] argv)
	{		
		ArrayList<String> tomb = new ArrayList<String>();
 
		tomb.add("eper");
		tomb.add("málna");
		tomb.add("barack");
 
		System.out.println(tomb.get(2));
	}
}

Vector

Az ArrayList-et egyszálas programokhoz tervezték. A Vectort többszálas programokhoz. A Vector nem ellenőrzi, ha a kollekciója megváltozik, ami hibákhoz vezethet.

megváltozhat az iteráció során, viszont a változás nem ellenőrzött.

A vektor az ArrayList-hez hasonlóan használható. Meg kell adnunk mit szeretnénk benne tárolni. A következőben lássunk egy komplett példát a használatára.

Program2.java
import java.util.*;
 
class Program2
{
	public static void main(String[] argv)
	{
 
		Vector<String> tomb = new Vector<String>();
 
		tomb.add("eper");
		tomb.add("málna");
		tomb.add("barack");
 
		System.out.println(tomb.get(2));
	}
}

Elem törlése

tomb.remove(1);

Ha Object típust adok meg akkor különböző típusokat is eltehetek a verembe.

Program3.java
import java.util.*;
 
class Program3
{
	public static void main(String[] argv)
	{
 
		Vector<Object> tomb = new Vector<Object>();
 
		tomb.add("eper");
		tomb.add(25);
		tomb.add("málna");
		tomb.add("barack");
 
		System.out.println(tomb.get(1));
	}
}

Egyéb metódusok használat közben:

Program4.java
import java.util.*;
 
class Program4
{
	public static void main(String[] argv)
	{
 
		Vector<Object> tomb = new Vector<Object>();
 
		tomb.add("eper");
		tomb.add(25);
		tomb.add("malna");
		tomb.add("barack");
		tomb.addElement("korte");
 
		System.out.println(tomb.get(1));
 
		System.out.println(tomb.size());
		System.out.println(tomb.remove(1));
		System.out.println(tomb.size());
		System.out.println(tomb.get(1));
		System.out.println(tomb.elementAt(2));
		System.out.println("Hol talalhato: " + tomb.indexOf("malna"));
 
		tomb.clear();
		System.out.println(tomb.size());
 
		tomb.addElement(new Integer(1)); 
		tomb.addElement(new Integer(2)); 
		System.out.println("Utolso: " + tomb.lastElement());
		System.out.println("Elso: " + tomb.firstElement());
 
 
		tomb.removeAllElements();
		tomb.addElement("Valami");
		tomb.addElement("Masik");	
 
		//Konverziók:		
		Object[] tomb2 = tomb.toArray();
 
		String[] tomb3  = new String[10];
		tomb3 = (String []) tomb.toArray(tomb3);
		//Itt gond, ha a vektor nem string típusú elemet tartalmaz
                //Olyankor Object típusba lehet konvertálni.
 
		Enumeration e = tomb.elements();
	}
}

Ha Vector és hasonló listák esetén, ha számot akarunk tárolni akkor nem használhatjuk a primitív típust, helyette a burkolóosztályt kell használnunk. Ugyanakkor a for ciklusnak használhatjuk egy újabb változatát a lista kiíratására.

A következő példa ezt mutatja be:

Program.java
import java.util.Scanner;
import java.util.Vector;
 
class Program
{
	public static void main(String args[])
	{
		Vector<Integer> szamok = new Vector<Integer>();
 
		szamok.add(37);
		szamok.add(52);
		szamok.add(48);
		szamok.add(87);
		szamok.add(23);
 
		for(Integer szam : szamok)
			System.out.print(szam + " ");
		System.out.println();
	}
}

Vegyük észre az „Integer”-t az „int” helyett, a for ciklus fejrészében pedig „Integer szam : szamok”. Utóbbi azt jelenti, hogy veszem a szamok list minden elemét. Az elemeket a szam változóban kapom meg minden ciklusban, ameddig a lista elemei el nem fogynak.

List

A List egy Interfész, ezért példányt nem lehet belőle létrehozni. A konstruktorként az előző osztályok valamelyikét használhatjuk. A következő példában a Vector<> osztályt használjuk konstruktorként.

Program5.java
import java.util.*;
 
class Program5
{
	public static void main(String[] argv)
	{		
		List<String> tomb = new Vector<String>();
 
		tomb.add("eper");
		tomb.add("málna");
		tomb.add("barack");		
 
		System.out.println(tomb.get(1));
	}
}

Használható <Object> típussal egyszerre több típus.

Set

A Set egy interface, nem osztály. Ezért nincs is konstruktora. Helyette a TreeSet vagy HashSet osztályok konstruktorát használjuk. Egy halmazt határozhatunk meg vele, amelyen a szokásos halmazműveletek használhatók.

Program6.java
import java.util.*;
 
class Program6
{
	public static void main(String[] argv)
	{	
		//Set<String> halmaz = new TreeSet<String>();		
		Set<String> halmaz = new HashSet<String>();
 
		halmaz.add("eper");
		halmaz.add("málna");
		halmaz.add("barack");		
 
		System.out.println(halmaz.size());
		System.out.println(halmaz.contains("eper"));
 
		Iterator it = halmaz.iterator();
		while(it.hasNext())
		{
			Object elem = it.next();
		}
	}
}

Iterátor

Program01.java
import java.util.Iterator;
import java.util.Vector;
 
public class Program02
{
	public static void main(String args[])
	{
		Vector<String> v = new Vector<String>();
		v.add("alma");
		v.add("körte");
		v.add("barack");
		v.add("szilva");
 
		Iterator<String> i = v.iterator();
		while (i.hasNext())
		{
			System.out.println(i.next());
		}
	}
}

ArrayList kezdőérték

Program01.java
import java.util.ArrayList;
import java.util.Arrays;
class Program01
{
	public static void main(String args[])
	{
		Integer[] t = {45, 37, 29, 82, 34, 56};
		ArrayList<Integer> v = new ArrayList<Integer>(Arrays.asList(t));
 
		for(Integer a : v)
			System.out.println(a);		
	}
}

ArrayList listák összefűzése

List<String> list = new ArrayList<String>();
list.addAll(list1);
list.addAll(list2);

Gyakorlat

  1. Mondjon olyan típust vagy osztályt, amely azonos típusú elemek felvétele során automatikusan nő annak mérete.
  2. Milyen osztállyal tudunk feltölteni egy tömböt?
  3. Mi a vektor?
  4. Mi a mátrix?
  5. Hogyan deklarálunk egy mátrixot Java nyelven?

Különböző típusú adatok egy adatszerkezetben

A C nyelvben ezt struct, míg Pascal nyelvben ez a record. A Java nyelvben ezek egyike sem használható, helyette osztályt használhatunk a már meglévő osztályon belül.

Program01.java
import java.io.*;
 
class Program01
{
	public static void main(String args[]) throws IOException
	{
 
		class Dolgozo
		{
			int kor;
			double fizetes;						
		}				
 
 
		Dolgozo Joska  = new Dolgozo();
		Joska.kor = 23;
		Joska.fizetes = 370000;
 
		System.out.printf("%f\n", Joska.fizetes);
 
		System.out.println("Folytatáshoz nyomjon egy billentyűt");
		System.in.read();
	}
}

vagy

Program01.java
import java.io.*;
 
class Program01
{
	static class Dolgozo
	{
		int kor;
		double fizetes;						
	}
	public static void main(String args[]) throws IOException
	{
		Dolgozo Joska  = new Dolgozo();
		Joska.kor = 23;
		Joska.fizetes = 370000;
 
		System.out.printf("%f\n", Joska.fizetes);
 
		System.out.println("Folytatáshoz nyomjon egy billentyűt");
		System.in.read();
	}
}

Osztály tömbként

Sokszor előfordulhat, hogy több különböző adatot szeretnénk tárolni de nem csak egy dologról vagy személyről hanem többről.

Például szeretnénk dolgozók adatait tárolni:

Osztalytomb.java
import java.io.*;
 
class Osztalytomb {
        public static void main(String[] args) throws IOException {
                Dolgozo[] munkas = new Dolgozo[3];
                munkas[0] = new Dolgozo("Nagy Béla", 350000);
                munkas[1] = new Dolgozo("Kis János", 750000);
                munkas[2] = new Dolgozo("Rózsa Sándor", 380000);
 
                for (int i = 0; i < 3; i++)
                        munkas[i].print();
 
		System.in.read();
        }
}
 
class Dolgozo {
        private String nev;
 
        private double fizetes;
 
        public Dolgozo(String n, double s) {
                nev = n;
                fizetes = s;
        }
 
        public void print() {
                System.out.println(nev + "\t" + fizetes);
        }
}

Újabb példa:

Program01.java
class Program01 {
	static class Dolgozo
	{
		String nev;
		int kor;
		double fizetes;
	}	
	public static void main(String[] args) {
		Dolgozo[] munkas = new Dolgozo[3];
 
		for(int i=0; i<3;i++)
			munkas[i] = new Dolgozo();
 
		munkas[0].nev = "Nagy István";
		munkas[0].kor = 25;
		munkas[0].fizu = 285600.0;
 
		munkas[1].nev = "Kis Béla";
		munkas[1].kor = 32;
		munkas[1].fizu = "Kis Béla";
 
		munkas[2].nev = "Be Kornél";
		munkas[2].kor = 22;
		munkas[2].fizu = "Erős Lajos";
	}
}

Harmadik példa

Program01.java
/* Több tulajdonság tárolása listában  */
import java.util.ArrayList;
 
public class Program02 {
	public static void main(String[] a) {
		ArrayList<Dolgozok> dolgozok = new ArrayList<Dolgozok>();
		dolgozok.add(new Dolgozok("Nagy", "József"));
		dolgozok.add(new Dolgozok("Rezeg", "István"));
		dolgozok.add(new Dolgozok("Kékedi", "János"));
 
		System.out.println(dolgozok);
 
		Dolgozok d = dolgozok.get(1);
		d.beallitVezNev("Erős");
 
		System.out.println(dolgozok);
 
		Dolgozok d2 = dolgozok.get(1);
		System.out.println(d2.lekerVezNev());
	}
}
 
class Cim {
}
 
class Dolgozok {
	private String vezNev;
 
	private String kerNev;
 
	private Double fizetes;
 
	public Cim cim;
 
	public Dolgozok(String vezNev, String kerNev) {
		this.vezNev = vezNev;
		this.kerNev = kerNev;
		this.cim = new Cim();
 
	}
 
	public String lekerVezNev() {
		return this.vezNev;
	}
 
	public void beallitVezNev(String vezNev) {
		this.vezNev = vezNev;
	}
 
	public String lekerKerNev() {
		return this.kerNev;
	}
 
	public void beallitKerNev(String kerNev) {
		this.kerNev = kerNev;
	}
 
	public double lekerFizetes() {
		return this.fizetes;
	}
 
	public void beallitFizetes(double fizetes) {
		this.fizetes = fizetes;
	}
}

Egy példa automatikus feltöltéssel:

Program01.java
class Szemely {
	private String nev;
	private int szuletesEve;
	Szemely(String nev, int szuletesEve) {
		this.nev = nev;
		this.szuletesEve = szuletesEve;
	}
	@Override
	public String toString() {
		return nev + ":" + szuletesEve;
	}
}
 
class Program01 {
	public static void main(String args[]) {
		Szemely[] szemelyek = new Szemely[5];
		for(int i=0;i<5;i++) {
			szemelyek[i] = new Szemely("Névtelen" + i, 0);
		}
		System.out.println(szemelyek[1].toString());
	}
}

Ha HashSet osztályba szeretnénk például egy Dolgozo osztály példányait tárolni, néhány dolog nem fog működni alapértelmezetten. Ha például felveszem kétszer ugyanazt az adatot, mindkét adat tárolásra kerül, pedig halmazról lévén szó ennek nem lenne szabad bekövetkeznie. Ha egy HashSet objektumba, amely például Integer értékeket tartalmaz, a 22 értéket kétszer adom hozzá az add() metódussal, az csak egyszer fog tárolódni.

Visszatérve a Dolgozo osztályunkhoz, hasonló probléma lép fel, ha meg akarom vizsgálni, hogy egy adott dolgozó szerepel-e már a halmazban. Ezt a contains() metódussal szoktuk vizsgálni. Ha a HashSet halmazunkban a Dolgozo osztály példányai vannak a contains() metódus mindig hamis értéket fogunk kapni, vagyis nem tudjuk megvizsgálni vele, hogy egy adott dolgozó szerepel-e egy halmazban.

Természetesen a probléma megoldható, csak felül kell írnunk a hashCode() és a equals() metódust. A következő programban erre látunk példát:

Program01.java
import java.util.HashSet;
 
class Dolgozo {
	String nev;
	int kor;
	double fiz;
	Dolgozo(String nev, int kor, double fiz) {
		this.nev = nev;
		this.kor = kor;
		this.fiz = fiz;
	}
 
	@Override
	public boolean equals(Object o) {
		if(this == o) return true;
		Dolgozo dolgozo = (Dolgozo) o;
		if(!dolgozo.nev.equals(this.nev)) return false;
		if(dolgozo.kor!=(this.kor)) return false;
		if(dolgozo.fiz!=(this.fiz)) return false;
		return true;
	}	
	@Override
	public int hashCode() {
		int nevHash = this.nev.hashCode();
		int korHash = this.kor;
		int fizHash = (new Double(this.fiz)).hashCode();		
		int res = nevHash + korHash + fizHash;
		return res;
	}
}
 
class Program01 {
	public static void main(String args[]) {
		HashSet<Dolgozo> h = new HashSet<Dolgozo>();		
		h.add(new Dolgozo("Nagy József", 35, 350000));		
		h.add(new Dolgozo("Nagy József", 35, 350000));		
 
		System.out.println(h.contains(new Dolgozo("Nagy József", 35, 350000)));
		System.out.println(h.size());
 
	}
}

Enum típusok

Az enum típus egy speciális típus, amellyel a nevesített állandókhoz hasonló típusok jönnek létre. Értéket azonban nem adunk nekik, csak a nevükkel hivatkozunk rájuk. Használatával olvashatóbb kódot kapunk.

enum Egtaj {
	ESZAK, DEL, KELET, NYUGAT
}
enum Os { 
	LINUX, WINDOWS, MACOSX
}
Program.java
class Program
{
 
	enum Nap {
		HETFO, KEDD, SZERDA, CSUTORTOK, 
		PENTEK, SZOMBAT, VASARNAP
	}	
	public static void main(String[] args)
	{
		Nap a = Nap.HETFO;
		System.out.println(a);
	}
}

Még több:

enum Day {SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
	THURSDAY, FRIDAY, SATURDAY 
}
enum Nap {HETFO, KEDD, SZERDA, CSUTORTOK, PENTEK, SZOMBAT, VASARNAP} ;
enum MovieType {ACTION, HORROR, COMEDY};
enum Gender {MALE, FEMALE};
enum WeekDay { MON, TUE, WED, THU, FRI, SAT, SUN };
enum Grade { A, B, C, D, F, INCOMPLETE }; //Ertekeles
enum Tank { EMPTY, HALF, FULL };
//Penny =1 centes, Nickel=5 centes, Dime=10 centes, Quarter=25 centes ; Amerika
enum Currency {PENNY, NICKLE, DIME, QUARTER};
enum Color {WHITE, BLACK, RED, YELLOW, BLUE };
enum Planet {
    MERCURY, VENUS, EARTH, ARS,
    JUPITER, SATURN, URANUS, NEPTUNE};
 
//sugár km, tömeg kg.
enum Bolygo {
	MERKUR (2439.7, 3.302E+23),
	VENUSZ (6051.8, 4.8685E+24),
	FOLD (6378.137, 5.9736E+24),
	MARS (3402.5, 6.4185E+23),
	JUPITER (71492.0, 1.899E+27),
	SZATURNUSZ (60268, 5.6846e+26),
	URANUSZ (25559, 8.6832e+25),
	NEPTUNUSZ (24764, 1.0243e+26);
	private final double radius;
	private final double mass;
	Bolygo(double radius, double mass){
		this.radius = radius;
		this.mass = mass;
	}
	private double getRadius() { return radius;}
	private double getMass() { return mass;}
}

Karakterkezelés

ASCII

A char típus egy karakter tárolására való. Igaz a Java Unicode karaktereket tárol, de az angol ábécé betűi az UTF-8 megvalósítás esetén kompatibilisek az ASCII kódtáblával.

Ha tudjuk, hogy az ASCII kódtáblában a nagy „A” és a kis „a” közötti különbség 32, akkor egyszerűen alakíthatjuk a nagybetűs karaktereket kisbetűssé és fordítva:

class ascii
{
	public static void main(String args[])
	{
		char ch = 'A';		
		System.out.printf("%c\n", ch + 32);
	}
}

A példában a nagy „A” karaktert kis „a” karakterré alakítjuk.

Rendelkezésre állnak a Character osztály metódusai is:

Kisbetűssé alakítása

char ch = Character.toLowerCase('A');

Szám, karakterként kezelése továbbiakban:

int a = 65;
char ch = (char) a;

A Character osztály további metódusai:

boolean isDigit(char ch)
boolean isLetter(char ch)
boolean isLetterOrDigit(char ch)
boolean isWhitespace(char ch)
boolean isLowerCase(char ch)
boolean isUpperCase(char ch)
String toString()
String toString(char c)
char toUpperCase(char ch)
Program01.java
class Program01
{
	public static void main(String args[])
	{
		System.out.println(Character.toChars(97)); // a
		System.out.println(Character.toChars(369)); // ű
		System.out.println((char)97); // a
		System.out.println((char)369); // ű
	}
}

ASCII kód

Program01.java
class Program01
{
	public static void main(String args[])
	{
		char ch = 'a';		
		System.out.printf("%d\n", (int) ch);
	}
}
Program01.java
class Program01
{
	public static void main(String args[])
	{
		int a = 65;
		System.out.printf("%c\n", a);
	}
}
Program01.java
class Program01
{
	public static void main(String args[])
	{
		int a = 'a';
		System.out.printf("%d\n", a);		
	}
}
Program01.java
class Program01
{
	public static void main(String args[])
	{
 
 
		System.out.println(Character.codePointAt("a", 0)); // 97
		System.out.println(Character.codePointAt("é", 0)); // 233
		System.out.println(Character.codePointAt("ű", 0)); // 369
	}
}

Összehasonlítás, egyenlőség vizsgálat

Program01.java
class Program01
{
	public static void main(String args[])
	{
		Character ch = 'a';
		char ch2 = 'b';
 
		System.out.println(ch.equals('a')); // true
		System.out.println(ch == 'a');  // true
		System.out.println(ch2 == 'b');  // true
	}
}
Program01.java
class Program07
{
	public static void main(String args[])
	{
		char ch1 = 'a';
		char ch2 = 'a';
		char ch3 = 'c';
 
		System.out.println(Character.compare(ch1, ch2)); // 0				
		System.out.println(Character.compare(ch1, ch3)); // -2
		System.out.println(Character.compare(ch3, ch1)); // 2		
	}
}

Karakter bekérés példa1

karbe.java
import java.util.*;
 
class karbe
{
	public static void main(String args[])
	{
		Scanner olvaso = new Scanner(System.in);		
 
		System.out.print("Karakter: ");
		String str = olvaso.next();
 
		char ch = str.charAt(0);
 
		System.out.println(ch);
                olvaso.close();
	}
}

A next() metódus helyett használható a nextLine() metódus is.

Példa 2

kar2be.java
import java.io.*;
 
class kar2be
{
	public static void main(String args[]) throws IOException
	{
 
		System.out.print("Karakter: ");
 
		char ch = (char) System.in.read();
 
		System.out.println(ch);		
 
	}
}

Példa 3

pel.java
import java.io.*;
 
class pel
{
	public static void main(String args[]) throws IOException
	{
		InputStreamReader folyam = new InputStreamReader(System.in);
		BufferedReader olvaso = new BufferedReader(folyam);
 
		System.out.print("Karakter: ");
 
		String str = olvaso.readLine();
		char ch = str.charAt(0);
 
		System.out.println(ch);				
	}
}

Sztring és karakter hasonlítása

Program01.java
class Program07
{
	public static void main(String args[])
	{
		if(Character.toString('a').equals("a"))
			System.out.println("Egyenlő");
		else
			System.out.println("Nem egyenlő");
 
 
	}
}

Karaktertömb sztringgé

Program01.java
class Program01
{
	public static void main(String args[])
	{
		//char tömb sztringgé 1:
		char[] t = {'a', 'b', 'c'};
		String s = new String(t);
		System.out.println(s);
 
		//char tömb sztringgé 2:
		String s2 = String.copyValueOf(t);
		System.out.println(s2);
 
	}
}

Sztring kezelés

String osztály

Stringeket a String osztállyal hozhatunk létre. Nincs string primitív típus.

String s;
s = "alma";

A Java nyelvben a sztringváltozónak értékadással is adhatunk értéket. A String osztály statikus, vagyis használható példányosítás nélkül.

A legnagyobb beírható string hossza: 65534

import java.io.*;
class szoveg
{
    public static void main(String args[]) throws IOException
    {
	String s;			
	s = "alma";
 
        System.out.println(s.length());	
 
	System.in.read();
    }
}

Egyenlőség vizsgálat

String gyumolcs = "körte";
if (gyumolcs.equals("alma"))
    System.out.println("A gyümölcs alma");

String osztály metódusai

length()

A karaktersorozat hosszát adja vissza.

int hossz = s.length();

concat()

Karaktersorozatok összefűzésére való.

String s = "egyik";
s.concat(" másik");

Az s változót kiíratva ezek után ezt kapjuk:

egyik másik

replace()

Egy karaktersorozatban egy adott karaktersor cseréje egy másikra.

Általános szintaxis:

replace(mitCserél, mireCserél)

Egy konkrét példa:

String s = new String("Nagy kő esett le a szívemről tegnap");
System.out.print(s.replace("szívemről", "egy kocsiról"));

replaceAll()

Egy karaktersorozatban a megtalált mintát minden helyen kicseréli.

str.replaceAll("\\s+", "\t"); //Szóközök tabulátorra cserélése

toLowerCase()

Kisbetűssé alakít minden karaktert.

toLowerCase()
String str = "SziLVa";
String kisbetus = str.toLowerCase();

toUpperCase()

Nagybetűssé alakít minden karaktert.

toUpperCase()
String str = "SziLVa";
String nagybetus = str.toUpperCase();

trim()

A trim() a szöveg elejéről és a végéről eltávolítja a whitespace karaktereket.

String s = "   alma   ";
System.out.println(s.trim());

split()

A karaktersorozatot feldarabolja a megadott szeparátor alapján.

str.split("\\s+"); //Egy vagy több szóköz

Szeparátorként megadható szabályos kifejezés.

isEmpty()

Megvizsgáljuk, hogy a karaktersorozat-változó üres-e.

Példa:

boolean ures = str.isEmpty();

További példák

class str
{
        public static void main(String args[])
        {
                System.out.println("Szövegkezelés Java nyelven");
 
		String szoveg = "alma";
 
		System.out.println(szoveg.equals("almaa")); // true értéket ad vissza, ha egyezik, vagy false
		System.out.println(szoveg.compareTo("alma")); // 0-át kapunk, ha egyezik
		System.out.println(szoveg.indexOf("alma")); // -1 ha nem található; hanyadik helytől (első index 0)
 
		//Szöveg darabolása
		String sor ="alma:körte:barack:szilva";
		String[] tomb = sor.split(":");
		System.out.println(tomb[1]);
 
		String mondat = "Ha megint ezért üzen";
		System.out.println(mondat.substring(4)); //Kezdő indextől szeretném a karaktereket
		System.out.println(mondat.substring(4, 6));  //Kezdő index és vég index közötti karakterek
        }
}

char[] és String

A String típusú objektum egy karakterére nem hivatkozhatunk a Java nyelven tömbként. Ehhez például a charAt() metódust használhatjuk.

Ez helyes:

char[] tomb = {'a', 'b', 'c'};
System.out.println(tomb[1]);

String esetén csak így:

String tomb = "abc";
System.out.println(tomb.charAt(1));

Esetleg:

char[] adat = {'a', 'b', 'c'};
String adat2 = new String(adat);
System.out.println(adat2.charAt(1));

Pufferelt sztringek

A string osztállyal létrehozott változó valójában nem változtatható meg. Ha ilyen műveletet végzünk a háttérben valójában egy új példány jön létre.

String str = "szilva";
str = "barack";

A fenti példa második sorában a egy új str objektum jön létre a memóriában.

StringBuilder

Ugyanaz mint a StringBuffer, de a Stringek nincsenek szinkronizálva. Ezért használatát egy szálas programokhoz találták ki.

StringBuilder defString = new StringBuilder();  // 16 karakter méret beállítása
StringBuilder nulString = new StringBuilder(6); // pontos méret megadása
StringBuilder aString = new StringBuilder("kezdőérték"); // kezdőérték megadása

Hozzátartozó metódusok:

capacity(), length(), charAt(i), indexOf(g), lastIndexOf(g)

Módosító metódusok:

append(g), delete(i1, i2), insert(iPosn, g), getChars(i), setCharAt(iposn, c), 
substring(), replace(i1,i2,gvalue), reverse(), trimToSize(g ), toString(g)

Összehasonlítás String típussal:

if(strb.toString().equals("hasonlítószöveg"))
    //Mit tegyünk

StringBuffer

StringBuffer s;

A StringBuffer osztállyal olyan sztringeket hozhatunk létre, amit meg is tudunk változtatni.

StringBuffer defString = new StringBuffer(); // 16 karakter méret beállítása
StringBuffer nulString = new StringBuffer(6); // pontos méret megadása
StringBuffer aString = new StringBuffer("kezdőérték"); // kezdőérték megadása

Hozzátartozó metódusok:

capacity(), charAt(i), length(), substring(iStart [,iEndIndex)])

Módosító metódusok:

append(g), delete(i1, i2), deleteCharAt(i), ensureCapacity(), 
getChars(srcBeg, srcEnd, target[], targetBeg), insert(iPosn, g), 
replace(i1,i2,gvalue), reverse(), setCharAt(iposn, c), 
setLength(),toString(g)

Sztring formázás

Az alábbi sorok a Calander típusú objektum tartalmát teszik olvashatóvá:

java.util.Calendar c = java.util.Calendar.getInstance();
String s = String.format("Születésnap: %1$tY-%1$tm-%1$te", c);

Valós szám kiíratása:

double a = 3.7;
System.out.println(String.format("%.2f\n", a));

Összefűzés

String s1 = "Egyik";
String s2 = s1 + "Másik";

Sztring hossza

int hossz = s2.length();

Számok sztringgé

int szam1 = 4;
double szam2 = 3.5;
 
String szamegy = String.valueOf(szam1);
String szamketto = String.valueOf(szam2);

Sztringek számmá

String s1 = "3.5";
String s2 = "34";
 
double szam1;
int szam2;
 
szam1 = Double.valueOf(s1).doubleValue();
szam2 = Integer.alueOf(s2).intValue();

Összehasonlítás

String gyumolcs = "alma";
if (gyumolcs.equals("körte"))
    System.out.println("A gyümölcs: körte");

Lexikográfiai összehasonlítás. 0-át kapunk ha azonos, 0-nál kisebb értéket ha a második kisebb (lexikográfialilag), illetve 0-nál nagyobb értéket ha nagyobb.

String abc = "abc";
Stirng def = "xyz";
 
if (abc.compareTo(def) < 0)   // 'a' kisebb mint 'x'
if (abc.compareTo(abc) == 0)  // ez is igaz

Egy adott karakter első előfordulása

String s = "Finomabb";
int kezdet;
kezdet = s.indexOf('b')

Egy adott sztring első előfordulása

String s = "Finomabb";
int kezdet;
kezdet = s.indexOf("nom")

Rész sztring keresése

String s = "Finomabb";
String resz;
resz = s.substring(2,4);

Az első paraméter a kezdet, a második a vég.

Sztring karaktertömbbé

String s = "barack";
char[] t = s.toCharArray();
System.out.println(t[0]);

Iterálással:

Program01.java
class Program01 {
	public static void main(String[] args) {
		String str = "almakörte";
 
		char[] ca = str.toCharArray();
 
		for(char ch : ca) {
			System.out.println(ch);
		}
	}
}

Sztring darabolása

String s = "barack:körte:alma";
String[] ts = s.split(":");
System.out.println(ts[1]);

A „|” szeparátorral nem működik. A Szeparátor lehet reguláris kifejezés is.

Gyakorlás

  • Milyen osztályokkal deklarálhatunk karaktersorozatot tárolni képes változót, illetve objektumot?
  • Hogyan kérdezhetjük le egy karaktersorozat hosszát?
  • Hivatkozhatok-e egy karaktersorozat adott elemére a szögletes zárójelekkel, a tömbökhöz hasonlóan?
  • Hogyan tudom egy szöveg egy részét venni?
  • Hogyan tudom megvizsgálni, hogy egy karaktersorozat egyenlő-e egy másik karaktersorozattal?

Kivételkezelés

A kivételkezelésről

A kivételkezelést a program futtatása során fellépő abnormális állapotok kezelésére találták ki. Abnormális állapot esetén a programok kivételt dobnak. Például, egy nemlétező állományra hivatkozunk, vagy írni akarunk állományba, de nincs hozzá jogunk. Esetleg nullával próbáltunk meg osztani.

Ha egy program dobott egy kivétel, mi két dolgot tehetünk. Eldobjuk vagy kezeljük. Az eldobás a throws utasítással lehetséges. Az elkapás a try-catch utasítás párral.

Osztás nullával

import java.io.*;
import java.util.*;
class program
{
	public static void main(String args[]) throws IOException
	{
		Scanner be =new Scanner(System.in);
		double c=0;		
 
		int a = be.nextInt();
		try {
				c =  50 / a;
		} catch (Exception e) {
 			if (e instanceof ArithmeticException)
				System.out.println("Osztás nullával");
		}
		System.out.printf("%f\n", c);
 
		System.out.println("Folytatáshoz nyomj egy billentyűt!");
		System.in.read();
	}
}
Program01.java
try{
 
   //utasítások
 
}catch(IOException e) {
    System.out.println("Kivétel törént - Hogy miért? Lásd itt: ");
    e.printStackTrace();
    System.exit(-1);
}

A kivétel eldobása:

Program01.java
import java.io.IOException;
 
class Program01
{
	public static void main(String[] args) throws IOException
	{
		System.out.println("Folytatáshoz nyomjon Entert");
 
		System.in.read();
	}
}

Osztás 0-val lebegőpontos számokkal

Ha lebegőpontos számokkal dolgozunk és 0-val osztunk, akkor az nem hiba. Ez csak egész számok esetén hiba. Valós számok esetén az eredmény végtelen.

Program01.java
class Program01 {
	public static void main(String[] args) {
		double a = 1/0.;
		if(a == Double.POSITIVE_INFINITY) {			          
			System.out.println("Végtelen");
		} else {
			System.out.println("Valami más");
		}
	}
}

Néhány kivétel

  • ArithmeticException - Például osztás nullával
  • InputMismatchException - java.util.Scanner osztállyal pl. számot várunk szöveget kapunk

Gyakorlat

  • Mikor használjuk a kivételkezelést?
  • Milyen utasítással alkalmazzuk a Java nyelvben a kivételkezelést?

Fájl műveletek

Műveletek fájlokkal

Fájl létezésének ellenőrzése:

import java.io.*;
 
public class ap
{
    public static void main(String[] args)
    {
         File f = new File("adat.txt");
         System.out.println(f.exists());
    }
}

További metódusok:

  • exists() – Ha a fájl létezik true, ha nem false
  • getName() – A fájl neve String-ként
  • length() – A fájl mérete long-ként
  • createNewFile() – Azonos nevű fájl létrehozása, ha még nem létezik
  • delete() – A fájl törlése, ha létezik
  • renameTo(Fájl) – A fájl átnevezése a paraméterben megadott File objektumot használva.

A fájl objektum könyvtárakat is jelölhet.

Ha egy File objektum könyvtárat jelöl akkor hívható a következő metódus:

  • listFiles()

Olvasás fájlból

Egyszerűen

Program2.java
import java.io.*;
 
class Program2 {
	public static void main(String args[]) throws IOException {
 
		FileReader olvaso = new FileReader("adat.txt");
 
		StringBuilder strb = new StringBuilder();
 
		char ch;
		while(olvaso.ready()) {
			ch = (char)olvaso.read();
			strb.append(ch);
		}
		olvaso.close();
 
		System.out.println(strb);
	}
}

BufferedReader használata

import java.io.*;
class readfile
{
    public static void main(String[] argv) throws IOException
    {
 
	FileReader folyam = new FileReader("adat.txt");
	BufferedReader fileolvaso = new BufferedReader(folyam); 
 
	String sor;
 
	while ((sor = fileolvaso.readLine()) != null)
	{
		System.out.println(sor);
	}
 
	fileolvaso.close();
 
	}
}

Három osztály használata

import java.io.*;
 
public class ap {
    public static void main(String[] args) throws IOException {
      File f = new File("adat.txt");
      FileReader fr = new FileReader(f);
      BufferedReader bemenet = new BufferedReader(fr);
 
      boolean vege = false;
      String s;
 
      while(!vege) {
          s = bemenet.readLine();
          if (s != null) 
              System.out.println(s);
          else
              vege = true;
      }
      bemenet.close();
    }
}

Olvasás Scanner osztállyal

import java.io.*;
import java.util.*;
class readfile2
{
    public static void main(String[] argv) throws IOException
    {
 
	Scanner olvaso = new Scanner(new FileReader("adat.txt"));
 
	while(olvaso.hasNextLine())
	{
		System.out.println(olvaso.nextLine());
	}
    }
}

Újabb példa

import java.io.*;
class readfile
{
        public static void main(String[] argv) throws IOException
	{
 
		FileReader folyam = new FileReader("adat.txt");
		BufferedReader fileolvaso = new BufferedReader(folyam); 
 
		String sor = null;
 
		do
		{
			sor = fileolvaso.readLine();
			System.out.println(sor);
		}while (sor != null);
 
		fileolvaso.close();
 
	}
}

A File és a Scanner osztály használata

Program01.java
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
class Program01
{
	public static void main(String[] args) throws FileNotFoundException
	{
		File f = new File("adat.txt");
		Scanner bef = new Scanner(f);
 
		while(bef.hasNextLine())
		{
			System.out.println(Integer.parseInt(bef.nextLine()));
		}
	}
}

Fájl olvasása kivételkezelésével

A kivételek kezelését sokan a úgy oldják meg, hogy a fájlkezelő utasításokat egy try..catch szerkezetbe ágyazzák. Például így:

Program01.java
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
 
class Program01 {
	public static void main(String[] args) {
		File f = new File("adat.txt");
		try {
			Scanner fin = new Scanner(f);
 
			while(fin.hasNextLine()) {
				System.out.println(Integer.parseInt(fin.nextLine()));
			}
		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		}
	}
}

A kivétel elkapásának persze akkor van értelme, ha magunk akarunk valamilyen szöveges üzenetet megjeleníteni. Ekkor a szöveges üzenet a catch() { } blokkba kerül.

Fájlbeolvasás korrekt kivételkezeléssel

A fenti kivételkezeléses példában a fájlkezelő utasításokat a try..catch szerkezetbe ágyaztuk. Ez nem valami elegáns, ráadásul átláthatatlanná teszik a szépen megírt fájlkezelő blokkunkat. A következő példában a kivételt eldobjuk a fájlkezelő részben, és mellette létrehozunk egy hasonló nevű függvényt, amelynek a feladata csak a kivétel kezelése.

FileBeolvas.java
import java.io.FileNotFoundException;
import java.io.File;
import java.util.Scanner;
 
public class FileBeolvas {
    public static void beolvas() {
        try {
            tryBeolvas();
        }catch(FileNotFoundException ex) {
            System.err.println("A fájl nem található");            
        }
    }
 
    public static void tryBeolvas() throws FileNotFoundException {
        File f = new File("adat.txt");
	Scanner olvaso = new Scanner(f); 
	while(olvaso.hasNextLine()) {
		System.out.println(olvaso.nextLine());
	}        
    }    
 
    public static void main(String[] args) {        
        beolvas();
    }    
}

Vegyük észre a fájlkezelő metódus, amelynek a neve beolvas() volt fentebb, most át lett nevezve tryBeolvas()-ra. A hibakezelő metódus kapta a beolvas() nevet. A hibakezelő metódusból hívjuk meg a tryBeolvas() metódust.

Fájlba írás

Egyszerű fájlba írás

Program.java
import java.io.*;
 
class Program
{
	public static void main(String args[]) throws IOException
	{
 
		FileWriter iro = new FileWriter("adat.txt", true);
 
		iro.write("joska:titok:gazdasag:Szolnok\n");	
 
		iro.flush();
		iro.close();
 
		System.out.println("Kiírva");
	}
}

A konstruktorban a második paraméter true, azt jelenti hozzáfűzünk az állományhoz. Ez a paraméter nem kötelező. Ha nem adjuk meg alapértelmezetten felülírjuk az állományt.

BufferedWriter használata

Program3.java
import java.io.*;
 
class Program3
{
	public static void main(String args[]) throws IOException
	{
		FileWriter firo = new FileWriter("adat2.txt", true);		
		BufferedWriter iro = new BufferedWriter(firo);
 
		iro.write("Valai");
 
		iro.close();
		firo.close();
 
		System.out.println("Kiírva");
	}
}

PrintWriter használata

Program4.java
import java.io.*;
 
class Program4
{
	public static void main(String args[]) throws IOException
	{
		FileWriter firo = new FileWriter("adat2.txt", true);		
		PrintWriter iro = new PrintWriter(firo);
 
		iro.println("Valai");
		firo.close();		
 
		System.out.println("Kiírva");
	}
}

Összetettebb fájlba írás

ap.java
import java.io.*;
 
public class ap
{
    public static void main(String[] args) throws IOException
    {
        File f = new File("adat.txt");
        FileWriter kifolyam = new FileWriter(f); // Ha hozzáfűzni akarunk akkor FileWriter(f, true);
        PrintWriter kimenet = new PrintWriter(kifolyam);
 
        kimenet.println("alma");
        kimenet.println("körte");
        kimenet.println("szilva");
        kimenet.println("barack");
 
        kimenet.close();
    }
}

Fájl sorainak olvasása darabolással

import java.io.*;
import java.util.*;
 
public class ap
{
    public static void main(String[] args) throws IOException
    {
        File f = new File("adat.txt");
        FileReader bemenet_folyam = new FileReader(f);
 
        BufferedReader bemenet = new BufferedReader(bemenet_folyam);
 
        boolean vege = false;
        String s, gyumolcs;
        int sorszam, suly;
        while(!vege)
        {
            s = bemenet.readLine();
            if (s != null)
            {
                StringTokenizer Tokenek = new StringTokenizer(s);
                sorszam = Integer.valueOf(Tokenek.nextToken()).intValue();
                suly = Integer.valueOf(Tokenek.nextToken()).intValue();
                gyumolcs = Tokenek.nextToken();
                System.out.println(sorszam + " " + suly + " " + gyumolcs);
            }
            else
                vege = true;
        }
        bemenet.close();
    }
}

Fájl olvasása karakterenként

InputStream in = new FileInputStream("adat.txt");
Reader r = new InputStreamReader(in, "US-ASCII");
 
int intch;
 
while ((intch = r.read()) != -1) 
{
  char ch = (char) intch;
  //...
}

Az util csomag használata

Program.java
import java.io.*;
import java.util.*;
 
class Program {
 
	private static String fajlOlvas(String path) {
		File file = new File(path);
		Scanner olvaso = null;
		StringBuilder strb = new StringBuilder((int)file.length());
		try {
			olvaso = new Scanner(file);
		} catch(IOException e) {
			e.printStackTrace();
		}
 
		String sorTores = System.getProperty("line.separator");
 
		try {
			while(olvaso.hasNextLine()) 
				strb.append(olvaso.nextLine() + sorTores);
			return strb.toString();
		} finally {
			olvaso.close();
		}
	}
	public static void main(String[] args) {
		String str = fajlOlvas("adat.txt");
		System.out.println(str.replace("m", "g"));
	}
}

Egy rövid példa:

Program.java
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
class Program {
	public static void main(String[] args) throws IOException {
		File file = new File("adat.txt");
		Scanner olvaso = new Scanner(file);			
 
		System.out.println(olvaso.nextLine());
		System.out.println(olvaso.nextLine());
	}	
}

Vegyük észre, hogy itt nem olvasunk a fájl végéig.

A fájl végéig olvasáshoz:

while(olvaso.hasNextLine()) 
    strb.append(olvaso.nextLine() + sorTores);

Olvasás byte tömbbe

Program.java
import java.io.*;
import java.util.*;
class Program {
        private static String readFileAsString(String filePath) throws IOException {
                byte[] buffer = new byte[(int) new File(filePath).length()];
                FileInputStream f = new FileInputStream(filePath);
                f.read(buffer);
                return new String(buffer);
        }
        public static void main(String[] args) throws IOException {
		String str = readFileAsString("adat.txt");
                System.out.println(str);
        }
}

Karakterkódolás beállítása

Ezzel a megoldással Linuxon és Windowson is helyesen látszanak az ékezetek.

Scanner nFile = new Scanner(new File(fileName), "UTF-8");

vagy:

try {
	String fileName = "adat.txt";				
	Reader r = null;
	try {
		InputStream in = new FileInputStream(fileName);
		//US-ASCII
		r = new InputStreamReader(in, "UTF-8");
	} catch(UnsupportedEncodingException e) {}
 
	Scanner nFile = new Scanner(r);
 
	while(nFile.hasNextLine()) {
		String str = nFile.nextLine();
		System.out.println(str);
	}
	nFile.close();
} catch(FileNotFoundException e) {
	System.err.println("Hiba a fájlból olvasás során");
}

Stream osztállyokkal:

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.BufferedReader;
 
class Program01 {
	public static void main(String args[]) throws IOException {
 
		OutputStreamWriter fout = new OutputStreamWriter(new FileOutputStream("adat.txt"), "UTF-8");
 
		fout.write("almaáűé");
		fout.flush();
		fout.close();
		System.out.println("Kiírva");
 
		InputStreamReader fin = new InputStreamReader(new FileInputStream("adat.txt"), "UTF-8");
		BufferedReader in = new BufferedReader(fin);
		System.out.println(in.readLine());
	}
}

Karakterkódolás a Scanner osztállyal:

Program01.java
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.File;
class Program01 {
	public static void main(String[] args) {
		Scanner nFile = null;
		try {
			nFile = new Scanner(new File("adat.txt"), "UTF-8");
		} catch(FileNotFoundException ex) {
			System.err.println("Nemlétező fájl");
		}
 
		String str = nFile.nextLine();
		System.out.println(str);
		nFile.close();
	}
}

Típusos fájl

Program01.java
import java.io.BufferedOutputStream;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
 
class Program01 {
	public static void main(String[] argv) throws Exception {
		FileOutputStream fileOut = new FileOutputStream("data.txt");
		BufferedOutputStream bufferOut = new BufferedOutputStream(fileOut);
		DataOutputStream dataOut = new DataOutputStream(bufferOut);
		dataOut.writeUTF("árvíztűrő");
		dataOut.writeLong(34L);
		dataOut.writeInt(44);
		dataOut.writeDouble(32.343);
		dataOut.writeBoolean(true);		
		dataOut.close();
		bufferOut.close();
		fileOut.close();
 
		FileInputStream fileIn = new FileInputStream("data.txt");
		BufferedInputStream bufferIn = new BufferedInputStream(fileIn);
		DataInputStream dataIn = new DataInputStream(bufferIn);
		System.out.println(dataIn.readUTF());
		System.out.println(dataIn.readLong());
		System.out.println(dataIn.readInt());
		System.out.println(dataIn.readDouble());
		System.out.println(dataIn.readBoolean());
		dataIn.close();
		bufferIn.close();
		fileIn.close();
	}
}

A sorrendet tartani kell.

Véletlen hozzáférésű fájlok

Írás fájlba

Program01.java
import java.io.*;
class Program01 {
	public static void main(String args[]) throws IOException{
		System.out.println("Hi");
 
		RandomAccessFile file = new RandomAccessFile("adat.txt", "rw");
		file.seek(12);
		file.write("Hello World".getBytes());
		file.close();
 
	}
}

A seek() metódussal a 12-es helyre állítom a fájlmutatót. Ha üres a 12 pozíció előtt a fájl, akkor NUL értékekkel tölti fel.

UTF karakterek írása és olvasása

Program01.java
import java.io.*;
class Program01 {
	public void kiir() throws IOException {
		System.out.println("Kiírás");
		RandomAccessFile file = new RandomAccessFile("adat.txt", "rw");
		file.seek(20);		
		file.writeUTF("alma");
		file.seek(40);
		file.writeUTF("körte");
		file.seek(60);
		file.writeUTF("barack");
		file.seek(80);
		file.writeUTF("szilva");
 
		file.close();
 
	}
	public void olvas() throws IOException {
		RandomAccessFile file = new RandomAccessFile("adat.txt", "r");
		file.seek(40);
		System.out.println(file.readUTF());
		file.seek(60);
		System.out.println(file.readUTF());		
		file.close();
 
	}
 
	public static void main(String args[]) throws IOException{
		new Program04().kiir();
		new Program04().olvas();
	}
}

Gyakorlat

  • Sorolja fel, milyen osztályok használata jöhet szóba fájlkezelés esetén.
  • Mondjon egy osztály, amellyel egy állomány végéhez fűzhetünk sorokat.
  • Milyen osztályok használata esetén adhatjuk meg a karakterkódolást is fájlból olvasás során?

Típus ellenőrzés

Kivételek használata

Ellenőrizi szeretnénk, hogy valóban szabályosan valós szám lett beírva:

try {
	double a = be.nextDouble();
} catch (Exception e) {
	System.out.println("Nem valós szám!");
}

Ha nem így történt, hibaüzenetet küldünk.

Ügyeljünk arra, hogy a forrásban ugyan tizedes pontot használunk, de a bekérésnél tizedes vesszőt vár a java.

Ugyanez egész számmal:

try {
	int a = be.nextInt();
} catch (Exception e) {
	System.out.println("Nem egész szám!");
}

Teljes példa a Scanner osztály használatára:

Tip.java
import java.io.*;
import java.util.*;
 
class Tip {
	public static void main(String args[]) throws IOException {
		System.out.println("Típusellenőrzés");
 
		Scanner be = new Scanner(System.in);
 
		System.out.print("Szám: ");
		try {
			int a = be.nextInt();
		} catch (Exception e) {
			System.out.println("Nem egész szám");
		}
 
		System.in.read();
	}
}

Teljes példa BufferedReader osztály használata esetén

Tip.java
import java.io.*;
 
class Tip {
	public static void main(String args[]) throws IOException {
		System.out.println("Típusellenőrzés");
 
		InputStreamReader befolyam = new InputStreamReader(System.in);
		BufferedReader be = new BufferedReader(befolyam);
 
		String s;
		int szam;
 
		System.out.print("Szám: ");
		s = be.readLine();
		try {
			szam = Integer.valueOf(s).intValue();
		} catch(Exception e) {
			System.out.println("Gond van konverzióval");
		}
 
		System.in.read();
	}
}

Konverziónál, használhatjuk a NumberFormatException kivételt is:

try {
    szam = Integer.valueOf(s).intValue();
} catch(NumberFormatException e) {
    System.out.println("Gond van konverzióval");
}

Függvény megírásával

Tipusv.java
import java.io.*;
 
class Tipusv {
	public static void main(String args[]) throws IOException {
		System.out.println("Hi");
 
		InputStreamReader befolyam = new InputStreamReader(System.in);
		BufferedReader be = new BufferedReader(befolyam);
 
		String s = be.readLine();
 
		if (isInteger(s))
			System.out.println("Egész szám");
		else
			System.out.println("Nem egész szám");
 
 
		System.in.read();
	}
 
	static public boolean isInteger(String bemenet) {
		try {
			Integer.parseInt(bemenet);
			return true;
		} catch(Exception e) {
			return false;
		}		
	} /* isInteger */
}

Reguláris kifejezések használata

Tipusv.java
import java.io.*;
 
class Tipusv {
	public static void main(String args[]) throws IOException {
		System.out.println("Hi");
 
		InputStreamReader befolyam = new InputStreamReader(System.in);
		BufferedReader be = new BufferedReader(befolyam);
 
		String s = be.readLine();
 
		if(s.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) 
			System.out.println("Szám");
		else
			System.out.println("Ez nem szám");
 
 
		System.in.read();
	}
}

Ez a kódrész elfogad előjeleket és tizedespontot is.

text csomag

Tipusv
import java.io.*;
import java.text.*;
 
class Tipusv {
	public static void main(String args[]) throws IOException {
		System.out.println("Hi");
 
		InputStreamReader befolyam = new InputStreamReader(System.in);
		BufferedReader be = new BufferedReader(befolyam);
 
		String s = be.readLine();
 
		DecimalFormat df = new DecimalFormat("#%");	
		Number a = 0;
 
		try {
			a = df.parse(s);
			System.out.println("Szám: " + a.doubleValue());
		} catch(Exception e) {
			System.out.println("Nem megfelelő formátum" );
		}
 
		System.in.read();
	}
}

Példaformátum leírás:

"#,##0.00%"
"#,##0.00"

A Number típusú objektum metódusai.

byte byteValue() Az adott szám bájt értékével tér vissza
abstract double doubleValue() Az adott számot doulbe-ként adja vissza
abstract float floatValue() Az adott számot float-ként adja vissza
abstract int intValue() Az adott számot int-ként adja vissza
abstract long longValue() Az adott számot long-ként adja vissza
short shortValue() Az adott számot short-ként adja vissza
Tipusv
import java.io.*;
import java.text.*;
 
class Tipusv {
	public static void main(String args[]) throws IOException {
		System.out.println("Hi");
 
		InputStreamReader befolyam = new InputStreamReader(System.in);
		BufferedReader be = new BufferedReader(befolyam);
 
		String s = be.readLine();
 
		NumberFormat df = NumberFormat.getInstance();
		Number a = 0;
 
		try {
			a = df.parse(s);
			System.out.println("Szám: " + a.doubleValue());
		} catch(Exception e) {
			System.out.println("Nem megfelelő formátum" );
		}
 
		System.in.read();
	}
}

Metódusok létrehozása

Statikus metódusok

Ha már nagyon sok utasításunk van, azokat csoportosítani szoktuk, adunk neki egy nevet, majd a nevével hivatkozva hívjuk meg az összes utasítást. Például szeretnénk egy névjegykártyát kiíratni, amelyen szerepel a nevünk, címünk, telefonszámunk, e-mail címünk, weblapunk.

Program.java
 
class Program {	
	static void nevjegy() {
		System.out.println("Nagy József");
		System.out.println("Budapest");
		System.out.println("Tél u. 3.");
		System.out.println("+36 (30) 123-4567");
		System.out.println("nagy@valaholdomain.hu");
		System.out.println("http://valaholdomain.hu");
	}
 
	public static void main(String[] args) {
		nevjegy();
	}
}

A fenti példában a metódus fej része így néz ki:

static void nevjegy()
  • ( )
    • A név után tettünk egy nyitó és egy bezáró zárójelet.
  • static
    • A static egy módosító, amely megmondja, hogy a metódust akkor is használhatjuk, ha nem hoztunk létre az osztályból példányt.
  • void
    • A void a visszatérés típusát mondja meg. A void azt jelenti nem térünk vissza semmivel.
  • { }
    • Az utasításokat a kapcsos zárójelekkel fogom össze egyetlen blokká.

Néha a metódusainknak szeretnénk bemenő paramétereket megadni. Például, szeretnénk egy szám négyzetét venni. Ekkor a metódusnak paraméterkén megadhatjuk mi legyen ez a szám.

Program.java
class Program {	
	static void negyzet(double szam) {
		System.out.println(szam * szam);
	}
	public static void main(String[] args) {
		negyzet(3.5);
 
	}
}

Előfordulhat, hogy a kapott számot nem képernyőre szeretném íratni, hanem szeretném azt megkapni, továbbszámolás céljára. Ekkor a metódust úgy kell megírni, hogy adja vissza a kért értéket. Maradva a fenti négyzetszámító programnál, alakítsuk úgy át a programot, hogy adja vissza az adott szám értékét.

Program.java
class Program {	
	static double negyzet(double szam) {
		return szam * szam;
	}
	public static void main(String[] args) {
		System.out.println(negyzet(3.5)+2);
	}
}

Vegyük észre, hogy a metódusainkat az osztályon belül hoztuk létre, static kulcsszóval láttuk el, ennek hatására az osztály példányosítása nélkül tudjuk azokat használni.

A metódusoknak egész sorozatát hozhatjuk létre:

Program.java
class Program {
	static double dupla(double szam) {
		return 2 * szam;
	}
	static double negyzet(double szam) {
		return szam * szam;
	}
	static double felez(double szam) {
		return szam / 2;
	}
	public static void main(String[] args) {		
		System.out.println(Program.negyzet(3.0));
		System.out.println(Program.dupla(3.0));
		System.out.println(Program.felez(3.0));
	}
}

Példánymetódus

Az alábbi példában a metódust a static kulcsszó nélkül hozzuk létre. A használata ebben az esetben csak példányosítással lehetséges.

Program.java
class Program {
	double negyzet(double szam) {
		return szam * szam;
	}
 
	public static void main(String[] args) {
		Program program = new Program();
		System.out.println(program.negyzet(3.5)+2);
	}
}

Metódusok egész sorozata:

Program.java
class Program {
	double dupla(double szam) {
		return 2 * szam;
	}
 
	double negyzet(double szam) {
		return szam * szam;
	}
	double felez(double szam) {
		return szam / 2;
	}
 
	public static void main(String[] args) {
		Program program = new Program();
 
		System.out.println(program.negyzet(3.0));
		System.out.println(program.dupla(3.0));
		System.out.println(program.felez(3.0));
	}
}

Metódusok külön osztályban

Program.java
class Szamitas {
	double dupla(double szam) {
		return 2 * szam;
	}	
	double negyzet(double szam) {
		return szam * szam;
	}
	double felez(double szam) {
		return szam / 2;
	}	
}
 
class Program {
	public static void main(String[] args) {
		Szamitas szamitas = new Szamitas();
 
		System.out.println(szamitas.negyzet(3.0));
		System.out.println(szamitas.dupla(3.0));
		System.out.println(szamitas.felez(3.0));
	}
}

Paraméterátadás

Ha készítek egy metódust, a bemenő paramétereket formális paraméternek is nevezzük. Ezzel szemben az aktuális paraméter, a metódus hívásának helyén behelyettesített változók.

A Java nyelvben a paraméterek érték szerint kerülnek átadásra. Másként szólva, ha egy metóduson belül megváltoztatom egy formális paraméter értéket, ez nem érinti az aktuális paraméter értékét.

Ha nem alaptípusokat használunk paraméterként az átadás már nem érték szerint történik.

A következő példában egyszerű típust adunk át paraméterként:

Program01.java
class Program01 {
	public static void szamol(Integer szam) {
		szam = szam * 2;
		System.out.println(szam);
	}	
	public static void main(String[] args) {
 
		Integer szam = 4;
		szamol(szam);
		System.out.println(szam);
	}
}

Eredmény:

8
4

A következő példában referencia típus adunk át:

Program01.java
class Dolog {
	int szam = 1;
}
class Program01 {	
	public static void szamol(Dolog dolog) {
		dolog.szam = dolog.szam * 2;
		System.out.println(dolog.szam);
	}
 
	public static void main(String[] args) {
		Dolog dolog = new Dolog();
		dolog.szam = 4;
		szamol(dolog);
		System.out.println(dolog.szam);
	}
}

Eredmény:

8
8

Az utóbbival egyező eredményt kapunk tömbökkel, mivel azok is referenciák:

Program01.java
class Program01 {
	public static void szamol(int[] t) {
		t[0] = t[0] * 2;
		System.out.println(t[0]);
	}	
	public static void main(String[] args) {
 
		int[] t = new int[2];
		t[0] = 4;
		t[1] = 10;
		szamol(t);
		System.out.println(t[0]);
	}
}

Eredmény:

8
8

Több fájl

Ha már sok osztályunk van érdemes azokat külön állományban tárolnunk.

A következő két fájl egyszerűen egy könyvtárban használom.

Program01.java
class Program01 {
	public static void main(String args[]) {
		Program02 prog = new Program02();
		prog.kiir();
	}
}
Program02.java
class Program02 {
	public void kiir() {
		System.out.println("Másik osztály");
	}
}

Saját osztályaink "becsomagolása"

Ha még több saját osztályunk van azokat külön állományokba rakjuk és becsomagoljuk.

Abban a fájlban ahol az osztályaink el vannak helyezve, az állomány elején egy package Csomagnév; utasítást kell elhelyeznünk.

Egy osztály importálása egy csomagból az import utasítás után megadott csomagnév.Osztály; formában történhet. Ilyen formában:

import csomagnév.Osztály;

Ha „*” karaktert használunk, akkor a csomag összes osztályát használatba vettük.

Minden csomag számára saját könyvtárat kell létrehozni. A csomag osztályainak .class állományait ide be kell másolni.

Program01.java
import sajat.*;
 
class Program01 {
	public static void main(String args[]) {		
		Program02 ketto = new Program02();
		ketto.kikuld();
 
		Program03 harom = new Program03();
		harom.kikuld();
	}
}
sajat/Program02.java
package sajat;
public class Program02 {
	public void kikuld() {
		System.out.println("Második");
	}
}
sajat/Program03.java
package sajat;
public class Program03 {
	public void kikuld() {
		System.out.println("Harmadik");
	}
}
Ez a weboldal sütiket használ statisztikai céllal. Ha használod a weboldalt, elfogadod, hogy a számítógépeden sütiket tárolunk.Több információ
oktatas/programozás/java/java_nyelv.txt · Utolsó módosítás: 2018/05/28 18:15 szerkesztette: admin