Predavanje br. index|1|2|3|4|5|6|7|8|9|10|11|12|13|14|HOME


Drugo predavanje – proceduralna sintaksa

Primitivni tipovi podataka – operatori – razmak – literali – identifikatori – kljuène rijeèi – separatori – zbrajanje cijelih brojeva – zbrajanje brojeva tipa double – množenje i dijeljenje – neoèekivani kvocijenti – raèunanje ostatka, modulo – prioritet izvršavanja operatora – zagrade – miješanje tipova podataka – automatsko dodjeljivanje tipova podataka (casting) – pretvaranje stringova u brojeve – podaci tipa char – Unicode – naredbe za kontrolu toka – naredba if – ispitivanje jednakosti – klauzula else – klauzula else if – while petlja – for petlja – do while petlja – booleovski podaci – relacijski operatori – prioritet izvršavanja relacijskih operatora – ispitivanje jednakosti objekata – naredba break – naredba continue – labelirane petlje – naredba switch-case – kondicionalni operator (? :) – logièki operatori – prioritet izvršavanja logièkih operatora – deklariranje polja – kreiranje polja – inicijaliziranje polja – metoda System.arraycopy() – deklariranje, alociranje i inicijaliziranje dvodimenzionalnih polja – višedimenzionalna i neuravnotežena polja


Primitivni tipovi podataka

Primitivni tipovi podataka u Javi vrlo su slièni onima u C i C++. To su boolean, byte, short, int, long, float, double i char. Tip boolean je dodan u Javi. Implementacija je meðutim bitno proèišæena na nekoliko naèina.

  1. Dok C i C++ ostavljaju mnoge stvari ovisnima o mašini i kompajleru (npr. duljinu za int), Java specificira sve.
  2. Java ne dopušta pretvaranje tipova izmeðu proizvoljnih varijabli. Dopušteno je pretvaranje jedino meðu numerièkim varijablama te izmeðu podklasa i nadklasa istog objekta.
  3. Sve numerièke varijable u Javi su oznaèene.

boolean

1-bit. Može poprimiti vrijednosti true ili false.

true i false su definirane konstante jezika i nisu isto što i True i False, TRUE i FALSE, nula i ne-nula, 1 i 0 ili bilo koja druga numerièka vrijednost. Ne može se pretvoriti ni u jedan drugi tip varijable niti se drugi tipovi mogu pretvoriti u boolean.

byte

1 oznaèeni byte (komplenent od 2). Pokriva vrijednosti od -128 do 127.

short

2 bytea, oznaèena (komplement od 2), -32,768 to 32,767

int

4 bytea, oznaèena (komplement od 2), od -2,147,483,648 do 2,147,483,647. Kao kod svih numerièkih tipova, moguæe je pretvaranje (casting) u ostale numerièke tipove (byte, short, long, float, double). Kod pretvaranja s gubitkom informacija (lossy casts), npr int u byte, konverzija se obavlja modulo duljina “kraæeg” tipa.

long

8 bytea oznaèenih (komplement od 2), od -9,223,372,036,854,775,808 do +9,223,372,036,854,775,807.

float

4 bytea, IEEE 754, od 1.40129846432481707e-45 do 3.40282346638528860e+38 (positivni ili negativni).

Kao kod svih numerièkih tipova, moguæe je pretvaranje (casting) u ostale numerièke tipove (byte, short, long, int, double). Kod pretvaranja s gubitkom informacija (lossy casts), npr float u short, decimalni dio se odbacuje, i konverzija se obavlja modulo duljina “kraæeg” tipa.

double

8 bytea IEEE 754, od 4.94065645841246544e-324d do 1.79769313486231570e+308d (positivni or negativni).

char

2 bytea, neoznaèena, Unicode, od 0 do 65,535

Vrijednosti tipa char nisu isto što i vrijednosti tipa byte, int, short ili Strings.


Operatori

Operator

Akcija

+

Zbrajanje brojeva, konkatenacija stringova

+=

Zbrajanje i pridruživanje brojeva, konkatenacija i pridruživanje stringova

-

Oduzimanje

-=

Oduzimanje i pridruživanje

*

Množenje

*=

Množenje i pridruživanje

/

Dijeljenje

/=

Dijeljenje i pridruživanje

|

Bitovski OR

|=

Bitovski OR i pridruživanje

^

Bitovski XOR

^=

Bitovski XOR i pridruživanje

&

Bitovski AND

&=

Bitovski AND i pridruživanje

%

Modulo (raèunanje ostatka)

%=

Modulo i pridruživanje

>

Veæe

>=

Veæe ili jednako

<

manje

<=

Manje ili jednako

!

booleovski NOT

!=

razlièito

++

Poveæavanje za jedan

--

Smanjivanje za jedan

>>

Shift – pomak bitova u desno, zajedno sa znakom

>>=

Shift – pomak bitova u desno, zajedno sa znakom i pridruživanje

<<

Shift – pomak bitova u lijevo

<<=

Shift – pomak bitova u lijevo i pridruživanje

>>>

Neoznaèeni bitovski shift u desno

>>>=

Neoznaèeni bitovski shift u desno i pridruživanje

&&

Booleovski AND

||

Booleovski OR

==

Booleovska jednakost

=

Pridruživanje

~

Bitovski NOT

?:

Uvjet

instanceof

Provjera tipa


Razmak (white space)

Razmak je u pravilu znak [space], koji dobijete kad pritisnete <spacebar> no u Javi postoje još 4 znaka za razmak: [horizontal tab], [form feed], [carriage return] i [linefeed]. Ovisno o platformi, kad pritisnete tipku <return> ili <enter>, dobit æete [carriage return] (MAC), [linefeed] (UNIX) ili oboje (DOS, Windows, VMS). To æe proizvesti tvrdi prijelom linije u tekstu izvornog programa.

Osim u literalima tipa String, jedan razmak je ekvivalentan nizu uzastopnih razmaka bilo koje vrste.

Unutar literala tipa String i char jedini dozvoljeni razmak je znak [space]. Umjesto znakova [horizontal tab], [form feed], [carriage return] i [linefeed] moraju se stavljati odgovarajuæe escape-sekvence, npr. \t, \r, \f i \n. Ne možete razlomiti string ovako:

String poem = "Mary had a little lamb
whose fleece was white as snow
and everywhere that Mary went
the lamb was sure to go.";
 

Umjesto toga trebate koristiti znakove \n i operator konkatenacije +, ovako:

 
String poem = "Mary had a little lamb\n" +
"whose fleece was white as snow\n" +
"and everywhere that Mary went\n" +
"the lamb was sure to go.";
 

Primijetite da naredbe možete razlomiti kroz nekoliko redaka, jedino ne možete to uèiniti sa literalima tipa String. Takoðer primijetite da \n funkcionira samo na UNIX-u. Ako želite svoj kod uèiniti neovisnim o platformi, umjesto \n upotrijebit æete metodu System.getProperty("line.separator") koja æe vratiti odgovarajuæi znak za danu platformu. Pogledajte takoðer i metodu System.getProperties().

Java nema sve escape-sekvence koje ima C. Osim veæ spomenutih, to su još samo \b za [backspace] i \\ za sam [backslash]. No mogu se koristiti i \u sekvence koje dozvoljavaju umetanje bilo kojeg Unicode znaka.


Literali

Literali tipa String oznaèavaju se dvostrukim navodnicima, npr “Hello World!”. Takoðer, “dva” + “dva” je isto što i “dvadva”. Navodnici, meðutim nisu dio literala. Vrijednost literala “Hello World!” je Hello World!, a ne “Hello World!”. Takoðer formatiranje znakova nema utjecaja na vrijednost stringa, dakle “Hello World!” je isto što i “Hello World!”.

Literali tipa char oznaèavaju se jednostrukim navodnicima i smiju sadržavati toèno jedno slovo, npr. ¸’c’ je literal tipa char èija vrijednost je slovo c.

Booleovski literali su true i false, a znaèe istinu i laž.

Brojevi mogu takoðer biti literali. Npr. 34 je literal tipa int i njegova je vrijednost broj 34, dok je 1.5 literal tipa double , a to su i 45.6, 76.4E8 (76.4 puta 10 na osmu) i -32.0.

Nadalje, 34L je literal tipa long i oznaèava broj 34, dok su 1.5F, 45.6f i 76.4E8F literali tipa float.


Identifikatori

Identifikatori su imena variabli, metoda, klasa, paketa i suèelja. Za razliku od literala to nisu same stvari nego naèin njihovog referenciranja. U programu HelloWorld identifikatori su HelloWorld, String, args, main i System.out.println.

Identifikatori moraju biti sastavljeni od slova, brojeva i znakova _ (underscore) i “$ (dollar sign). Poèetno slovo identifikatora smije biti samo slovo, _ ili $. Mala i velika slova se razlikuju. Ime ne može sadržavati razmak.

Ovo su primjeri legalnih varijabli u Javi:

Sljedeæih nekoliko primjera nisu valjana imena varijabli:


Kljuène rijeèi

Postoji 50 rezerviranih kljuènih rijeèi koje u Javi 1.1 (51 u Javi 1.2). U tablici je navedeno njih 48 koje se stvarno koriste.

Keyword

Purpose

abstract

Deklarira apstraktnu klasu ili metodu

boolean

Deklarira booleovsku varijablu ili povratni tip (return type)

break

Prijevremeni izlazak iz petlje

byte

Deklarira byte varijablu ili povratni tip

case

Jedna od grana u naredbi switch

catch

Obrada iznimke

char

deklarira char variablu ili povratni tip

class

Oznaèava poèetak definiranja klase

continue

Prijevremeni povratak na poèetak petlje

default

default akcija za switch naredbu

Do

Poèetak do while petlje

double

deklarira double variablu ili povratni tip

Else

Oznaèava dio koda koji se izvršava ako uvjet u if naredbi nije istinit

extends

Oznaèava da je promatrana klasa potklasa neke druge klase

Final

Deklarira da klasa ne može imati podklasu ili da varijabla ili metoda ne može bit pregažena

finally

Deklarira blok koda koji æe garantirano biti izveden

Float

deklarira float variablu ili povratni tip

For

Poèetak for petlje

If

Izvršava kod ako je uvjet istinit

implements

Deklarira da promatrana klasa implementira dano suèelje

import

Dopušta pristup klasi ili grupi klasa unutar paketa

instanceof

Ispituje da li je objekt instanca neke klase

Int

deklarira int (integer) variablu ili povratni tip

interface

Oznaèava poèetak definiranja suèelja

Long

deklarira long (long integer) variablu ili povratni tip

native

Deklarira da je metoda implementirana u drugom programskom jeziku

New

Alocira novi object

package

Definira paket kojemu pripada datoteka sa promatranim izvornim kodom

private

Deklarira metodu ili member varijablu kao privatnu

protected

Deklarira klasu, metodu ili member varijablu kao zaštiæenu

public

Deklarira klasu, metodu ili member varijablu kao javnu

return

Vraæa vrijednost iz metode

Short

deklarira short (short integer) variablu ili povratni tip

static

Deklarira da varijabla ili metoda pripada klasi, a ne objektu

Super

Referenca na roditelja promatranog objekta

switch

Ispituje istinitost nekoliko moguæih uvjeta

synchronized

Oznaèava da je promatrani dio koda osjetljiv na threadove

this

Referenca na sam promatrani objekt

throw

Odbacivanje iznimke

throws

Deklarira iznimke koje metoda odbacuje

transient

Varijabla ne smije biti serijalizirana

try

Pokušava izvršiti operaciju koja može eventualno odbaciti iznimku

void

Deklarira da metoda ne vraæa nikakvu vrijednost

volatile

Upozorava kompajler da se varijabla mijenja asinhrono

while

Poèetak while petlje

Još dvije, const i goto, rezervirane su, ali nisu implementirane. To omoguæuje kompajleru bolje kreiranje poruka o pogreškama u sluèaju krive upotrebe ovih uobièajenih kljuènih rijeèi jezika C++ u Java programima.

Java 1.2 dodaje kljuènu rijeè strictfp kojom se deklarira da metoda ili klasa mora biti izvršena sa egzaktnom IEEE 754 semantikom.

Primijetite da true and false nisu kljuène rijeèi nego booleovski literali. Svejedno, ni njih ne možete koristiti kao imena varijabli.


Separatori

Separatori pomažu u definiranju structure programa. U programu HelloWorld koriste se zagrade, ( ), vitièaste zagrade, { }, toèka, ., toèka-zarez, ;.

 

Separator

Svrha

( )

Zatvara argumente u definicijama i pozivima metoda; podešava prioritete izvršavanja u aritmetièkim izrazima; okružuje umjetno pretvorene tipove podataka (cast types); izdvaja uvjetne izraze u naredbama za kontrolu toka

{ }

Definira blokove koda; automatski inicijalizira polja

[ ]

Deklarira polje tipova; izdvaja vrijednosti elemenata polja

;

Završava naredbu

,

Razdvaja nanizane identifikatore u deklaracijama varijabli; ulanèava naredbe u uvjetnom dijelu for petlje

.

Selektira varijablu ili metodu nekog objekta; separira imena paketa od imena podpakete i imena klasa

:

Koristi se nakon labela u petljama


Zbrajanje cijelih brojeva

class AddInts {
 
  public static void main (String args[]) {
 
    int i = 1;
    int j = 2;
    int k;
 
    System.out.println("i je " + i);
    System.out.println("j je " + j);
  
    k = i + j;
    System.out.println("i + j je " + k);
    
    k = i - j;
    System.out.println("i - j je " + k);
 
  }
 
} 
 

Evo što se dogaða kad izvršite AddInts:

 
% javac AddInts.java
% java AddInts
i je 1
j je 2
i + j je 3
i - j je -1
%

Zbrajanje brojeva tipa double

Brojevi tipa double sadrže decimalnu toèku .

 
class AddDoubles {
 
  public static void main (String args[]) {
 
    double x = 7.5;
    double y = 5.4; 
    double z;
 
 
    System.out.println("x je " + x);
    System.out.println("y je " + y);
  
    z = x + y;
    System.out.println("x + y je " + z);
    
    z = x - y;
    System.out.println("x - y je " + z);
 
  }
 
 } 

Evo rezultata:

 
% javac AddDoubles.java
% java AddDoubles
x je 7.5
y je 5.4
x + y je 12.9
x - y je 2.0999999999999996

Množenje i dijeljenje

Operatori množenja i dijeljenja su * (množenje) i / (dijeljenje).

 
class MultiplyDivide {
 
  public static void main (String args[]) {
 
    int i = 10;
    int j = 2;
    int k;
 
    System.out.println("i je " + i);
    System.out.println("j je " + j);
  
    k = i/j;
    System.out.println("i/j je " + k);
    k = i * j;
    System.out.println("i * j je " + k);
 
  }
 
}

Rezultat: 

 
% javac MultiplyDivide.java
% java MultiplyDivide
i je 10
j je 2
i/j je 5
i * j je 20
%
 

Realni brojevi tipa float i double množe se i dijele na isti naèin. U sluèaju cjelobrojnog dijeljenja, rezultat se zaokružuje prema dolje. Npr. cjelobrojno dijeljenje 10 sa 3 daje 3.


Neoèekivani kvocijenti

2/3 = 0 

3/2 = 1

1/0 = ArithmeticException

0/0 = ArithmeticException

1.0/0.0 = Inf

1.0/0 = Inf

0.0/0.0 = NaN (not a number)

-1.0/0.0 = -Inf

Inf + 1 = Inf

Inf + Inf = Inf

Inf - Inf = NaN

Inf/Inf = NaN

NaN + anything = NaN

NaN - anything = NaN

NaN * anything = NaN

NaN - anything = NaN

NaN < NaN je false

NaN > NaN je false

NaN <= NaN je false

NaN >= NaN je false

NaN == NaN je false

NaN != NaN je true


Raèunanje ostatka - modulo

Operator za raèunanje ostatka dijeljenja dvaju brojeva (modulo) je %.

 
class Remainder {
 
  public static void main (String args[]) {
 
    int i = 10;
    int j = 3;
    int k;
 
    System.out.println("i je " + i);
    System.out.println("j je " + j);
  
    k = i%j;
    System.out.println("i%j je " + k);
  }
 
}

Izlaz:

 
% javac Remainder.java
% java Remainder
i je 10
j je 3
i%j je 1
%
 

Primijetite da se operacija modulo može u Javi primijeniti i na realne brojeve. Npr. 5.5 % 1.5 je 1.


Prioritet izvršavanja operatora

Više operatora može biti u istom izrazu:

int m = 1 + 2 + 3 + 4 + 5;

Sljedeæi program raèuna energiju ekvivalentnu masi jednog elektrona uz pomoæ Einsteinove formule E = mc2.

class mc2 {
  public static void main (String args[]) {
 
    double mass = 9.1096E-25;
    double c = 2.998E8;
    double E = mass * c * c;
    System.out.println(E);
  }
}
 

Izlaz:

 
% javac mc2.java
% java mc2
8.18771e-08
%
 

U sluèaju razlièitih operatora, prioritet je uobièajen: Sljedeæe tri naredbe su ekvivalentne

 
int n = 1 - 2 * 3 - 4 + 5;
int n = 1 - (2 * 3) - 4 + 5;
int n= -4;
 

Unutar do sada spomenutih operatora, operacije se izvršavaju sljedeæim prioritetom:

  1. *, /, % Sva množenja, dijeljenja i modulo od lijeva na desno.
  2. +, - Sva zbrajanja i oduzimanja od lijeva na desno.
  3. = Pridruživanje desne strane lijevoj

Zagrade

Zagrade se koriste za mijenjanje uobièajenog redosljeda operacija. Sljedeæi primjer pokazuje pretvaranje Fahrenheitovih stupnjeva u Celsiusove po formuli C = (5/9) (F - 32) gdje su C stupnjevi Celsiusa a F stupnjevi Fahrenheita. Program ispisuje tablicu konverzija izmeðu 0 i 300 stupnjeva Fahrenheita za svakih 20 stupnjeva.

 
// Ispisuje tablicu konverzije Fahrenheita u Celsiuse
 
class FahrToCelsius  {
 
  public static void main (String args[]) {
  
    double fahr, celsius;
    double lower, upper, step;
 
    // donja granica temperaturne tablice
    lower = 0.0;  
 
    // gornja granica temperaturne tablice
    upper = 300.0;
 
    // velicina koraka
    step  = 20.0; 
 
    fahr = lower;
    while (fahr <= upper) { 
      celsius = (5.0 / 9.0) * (fahr-32.0);
      System.out.println(fahr + " F = " + celsius + " C");
      fahr = fahr + step;
    } 
 
  } 
 
} 
 

Obrada i izlaz:

 
% javac FahrToCelsius.java
% java FahrToCelsius
0.0 F = -17.77777777777778 C
20.0 F = -6.666666666666667 C
40.0 F = 4.444444444444445 C
60.0 F = 15.555555555555557 C
80.0 F = 26.666666666666668 C
100.0 F = 37.77777777777778 C
120.0 F = 48.88888888888889 C
140.0 F = 60.0 C
160.0 F = 71.11111111111111 C
180.0 F = 82.22222222222223 C
200.0 F = 93.33333333333334 C
220.0 F = 104.44444444444444 C
240.0 F = 115.55555555555556 C
260.0 F = 126.66666666666667 C
280.0 F = 137.77777777777777 C
300.0 F = 148.88888888888889 C
%
 

 

U ovom programu nema mnogo novog u odnosu na prethodne primjere, no pažnju obratimo na sljedeæu liniju:

 
celsius = (5.0 / 9.0) * (fahr-32.0);
 

To je prijevod formule C = (5/9)(F - 32) gdje je dodana * za množenje jer Java ne podržava implicitno množenje faktora u zagradama. Zagrade se koriste kao i u obiènoj algebri, za prilagodbu pravila prioriteta. Za operacije koje koriste uobièajene aritmetièke operatore (+, -, *, /), pravila prioriteta su ista kao i u obiènoj algebri.


Miješanje tipova podataka

Razlièiti tipovi podataka mogu se pojaviti u istoj naredbi. Primjer pokazuje istovremenu upotrebu int i double.

 
class IntAndDouble {
 
  public static void main (String args[]) {
 
    int i = 10;
    double x = 2.5;
    double k;
 
    System.out.println("i je " + i);
    System.out.println("x je " + x);
  
    k = i + x;
    System.out.println("i + x je " + k);
    k = i * x;
    System.out.println("i * x je " + k);
    k = i - x;
    System.out.println("i - x je " + k);
    k = x - i;
    System.out.println("x - i je " + k);
    k = i / x;
    System.out.println("i / x je " + k);
    k = x / i;
    System.out.println("x / i je " + k);
 
  }
 
}
 

Izlaz:

 
% javac IntAndDouble.java
% java IntAndDouble
i je 10
x je 2.5
i + x je 12.5
i * x je 25.0
i - x je 7.5
x - i je -7.5
i / x je 4.0
x / i je 0.25%

 

Redoslijed može imati utjecaja na rezultat kad se tipovi podataka miješaju. Na primjer,

1 / 2 * 3.5 = 0.0
3.5 * 1 / 2 = 1.75
3.5 / 2 = 1.75

Kod miješanja tipova podataka, uobièajeni matematièki zakoni komutacije opæenito ne vrijede, posebno ne kad se miješaju cjelobrojne (integer) i realne (floating point) vrijednosti.

1.0 / 2 * 3.5 = 1.75
3.5 * 1.0 / 2 = 1.75
1 / 2.0 * 3.5 = 1.75
3.5 * 1.0 / 2.0 = 1.75


Automatsko dodjeljivanje tipova podataka (casting)

Ako int podijelimo sa int dobijemo int.

Ako double podijelimo sa double dobijemo double.

Ako int podijelimo sa double ili double sa double, dobijemo double jer u sluèaju nejednakosti tipova Java teži dodjeljivanju što šireg tipa kako se sprijeèilo gubljenje informacija.

Pravilo:

·        Ako je bilo koja varijabla u aritmetièkoj binarnoj operaciji (zbrajanje, oduzimanje množenje, dijeljenje, modulo) tipa double onda Java tretira obje vrijednosti kao double.

·        Ako ni jedna nije double, ali je jedna float, Java tretira obje vrijednosti kao float.

·        Ako ni jedna nije ni float ni double, ali je jedna long, Java tretira obje vrijednosti kao long.

·        Konaèno, ako ni jedna nije double, float ni long, Java tretira obje vrijednosti kao int, èak ako u jednadžbi uopæe nema cijelih brojeva.

Dakle, rezultat æe biti double, float, long ili int, ovisno o tipovima argumenata.

U naredbi pridruživanja, dakle ako postoji znak jednakosti, Java usporeðuje tip na lijevoj strani sa konaènim tipom na desnoj strani. Tip na lijevoj strani neæe se promijeniti, ali æe se provjeriti da li vrijednost sa desne strane (double, float, int or long) odgovara tipu na lijevoj strani. Sve se može smjestiti u double. Sve osim double može se smjestiti u float. Svaki cjelobrojni tip može se smjestiti u long, ali float i double ne mogu, dok se sve tipa int, short i byte može smjestiti u int. Ako se desna strana može smjestiti u lijevu, pridruživanje se normalno obavlja.

Pridruživanje vrijednosti tipa long varijablama tipa int ili pak vrijednosti tipa double varijablama tipa float može uzrokovati probleme i kompajler vam takva pridruživanja neæe dopustiti osim ako eksplicitno navedete da želite pretvaranje (casting). Prisilno pretvaranje tipova oznaèava se navoðenjem odgovarajuæeg tipa u okruglim zagradama neposredno prije izraza koji treba pretvoriti. Na primjer,

int i = (int) 9.0/4.0;

Kad se vrijednost pretvara u drugi tip prije pridruživanja, niz operacija se poduzima da bi se desna strana “skratila” na pravu velièinu. Za konverziju izmeðu realnih (floating point) i cijelih brojeva (npr. int ili long), razlomljeni dio se odbacuje (zaokružuje na nulu). To æe proizvesti cijeli broj. Ako je on dovoljno mali da stane u lijevu stranu, pridruživanje je završeno. U suprotnom, ako je prevelik, bit æe mu pridružena najveæa, a ako je premali, najmanja moguæa vrijednost za odgovarajuæi tip.

Valja voditi raèuna o tome da prisilno pretvaranje može uzrokovati pogreške kojima æe biti vrlo teško uæi u trag i zato ovu moguænost treba koristiti s oprezom.


Pretvaranje stringova u brojeve

Prilikom obrade korisnièkog inputa èesto je potrebno neki String pretvoriti u int. To se radi uz pomoæ statièke metode Integer.valueOf(String s) u kombinaciji s (nestatièkom) metodom intValue() koje pripadaju klasi java.lang.Integer. Npr. String "22" pretvorili bismo u int 22 na sljedeæi naèin:

 
int i = Integer.valueOf("22").intValue();
 

S tipovima double, float i long postupamo slièno, koristeæi statièke metode Double.valueOf(String s), Float.valueOf(String s) i Long.valueOf(String s) u kombinaciji s odgovarajuæim metodama doubleValue(), floatValue() i longValue() koje pripadaju, respektivno, klasama java.lang.Double, java.lang.Float i java.lang.Long. String "22" pretvorili bismo u long 22 ovako:

long l = Long.valueOf("22").longValue();

String "22.5" pretvorili bismo u float ili double ovako:

 
double x = Double.valueOf("22.5").doubleValue();
float y = Float.valueOf("22.5").floatValue();
 

Razlièite valueOf() metode relativno su inteligentne i mogu prepoznati znakove plus i minus, eksponente i ostale uobièajene brojèane formate. Meðutim, ako kao argument dobiju nešto potpuno ne-numerièko, npr. "Hello World",  vjerojatno æe izbaciti NumberFormatException. Za sad još niste uèili kako baratati s iznimakama pa u svojim programima izbjegavajte takve situacije.

Preradit æemo sada program E = mc2 tako da o masi u kilogramima bude prihvaæen kao korisnièki input sa komandne linije. Ovaj postupak tipièan je za mnoge programe.

class mc2 {
  public static void main (String args[]) {
 
    double mass;
    double c = 2.998E8;  // meters/second
    double E;
 
    mass = Double.valueOf(args[0]).doubleValue(); 
    E = mass * c * c;
    System.out.println(E + " Joules");
  }
}

Obrada i rezultati:

 
% javac mc2.java
% java mc2 0.0456
4.098529824E15 Joules
%
 

Primijetite da ne bi bilo dovoljno staviti

 
    Mass = Double.valueOf(args[0]); // izostavljena je metoda doubleValue()
 

Statièka metoda Double.valueOf(args[0]) vratit æe vrijednost tipa Double, a tek æe metoda doubleValue() pretvoriti tu vrijednost u vrijednost tipa double. Zato bi navedena linija izazvala grešku u kompajliranju:

 
% javac mc2.java
mc2.java:8: incompatible types
found   : java.lang.Double
required: double
    mass = Double.valueOf(args[0]);
                         ^
1 error
%

Podaci tipa char

Podatak tipa char je pojedinaèni znak, tj. slovo, brojka, toèka, tab, praznina i slièno. Literali tipa char su pojedinaèni znakovi zatvoreni unutar jednostrukih navodnika, npr.

 
char myCharacter = 'g';
 

Za znakove koji se ne mogu utipkati Java osigurava escape sekvence. To je backslash iz kojeg slijedi alfanumerièki kod. Npr. '\n' je znak za novi reda, '\t' je znak za tab, '\\' je sam backslash. Definirane su sljedeæe escape sekvence:

 

\b

backspace

\t

tab

\n

linefeed

\f

formfeed

\r

carriage return

\"

Dvostruki navodnici, "

\'

Jednostruki navodnici, '

\\

backslash, \

 

Escape sekvenca za dvostruke navodnike koristi se uglavnom u stringovima gdje bi pojava navodnika inaèe terminirala string. Npr.

 
System.out.println("And then Jim said, \"Who's at the door?\"");
 

Dvostruki navodnici unutar jednostrukih bit æe prepoznati i bez escape sekvence. Npr. sljedeæi redak je posve legalan u Javi.

 
char doublequote = '"';

Unicode

Java koristi Unicode skup znakova. Unicode je dvobajtni znakovni kod koji reprezentira gotovo sve znakove u gotovo svim alfabetima i pismovnim sustavima svijeta, ukljuèujuæi engleski, arapski, kineski i druge. Problem je, meðutim, što mnogi operacijski sustavi i web preglednici ne podržavaju Unicode. Java æe uglavnom pravilno tretirati input ne-Unicode znakova. Prvih 128 znakova u Unicode tablici identièni su sa uobièajenim ASCII znakovima. Drugih 128 znakova podudara se sa gornjih 128 znakova u ISO Latin1 proširenom ASCII skupu. Ostalih 65,280 predstavlja problem.

Pojedinaène Unicode znakove možete referencirati koristeæi escape sekvancu \u iz koje slijedi èetverocifreni heksadecimalni broj. Npr.

\u00AE

 

©

 

Znak za copyright

\u0022

 

"

 

Dvostruki navodnici

\u00BD

 

1/2

 

Razlomak ½

\u0394

 

Δ

 

Veliko grèko delta

\u00F8

 

ø

 

Malo o prekriženo znakom slash

 

Možete èak koristiti potpune Unicode znakovne nizove za imenovanje varijabli. Npr.

 
String Mj\u00F8lner = "Hammer of Thor";

Naredbe za kontrolu toka

Primijetite da je goto je rezervirana rijeè ali nije implementirana. O obradi iznimaka bit æe rijeèi kasnije.


Naredba if

Primijetimo da smo se u klasi emc2 koristili argumentom s komandne linije, ali nismo provjeravali je li on uopæe unešen. Sljedeæi program ispisuje prvi argument sa komandne linije, ali prvo uz pomoæ varijable arrayname.length provjerava ima li argumenata.

class Hello {
 
    public static void main (String args[]) {
    
      if (args.length > 0) {
        System.out.println("Hello " + args[0]);
      }
  }
 
}
 

System.out.println(args[0]) je ovdje umetnuta unutar testa, if (args.length > 0) { }. Blok koda unutar vitièastih zagrada, System.out.println(args[0]), bit æe izvršen ako i samo ako je duljina polja args veæa od nule.

Argumenti za kondicionalne naredbe kao što je if moraju biti booleovski, dakle izrazi koji se evaluiraju na true ili false. Cjelobrojni argumenti nisu dopušteni.

% javac Hello.java
% java Hello
% 
% java Hello world!
% Hello world!
%

Ispitivanje jednakosti

Testiranje jednakosti je nešto složenije. Oèekivali biste da se za ispitivanje jesu li dva broja jednaki koristi znak jednakosti =. Meðutim, on je rezerviran za operator pridruživanja pa je za ispitivanje jednakosti uveden novi znak, dvostruka jednakost, ==. Taj je znak posuðen iz C-a.

Ta se dva znaka greškom lako mogu zamijeniti, no kako u Javi nisu dozvoljeni na istim mjestima, kompajler æe to otkriti. Ipak, sljedeæa situacija može biti problematièna:

 
     boolean b = true;
      if (b = false) {
        System.out.println("b is false");
      }
 

Da bi to izbjegli, neki programeri pišu testiranje uvjeta ovako:

 
     boolean b = true;
      if (false = b) {
        System.out.println("b is false");
      }
 

Kako literalu ne možete pridružiti nikakvu vrijednost, kompajler æe u tom sluèaju otkriti da je ste umjesto == napisali =.


Klauzula else

class Hello {
 
    public static void main (String args[]) {
    
      if (args.length > 0) {
        System.out.println("Hello " + args[0]);
      }
      else {
        System.out.println("Hello whoever you are.");
      }
  }
 
}
 
% javac Hello.java
% java Hello
% Hello whoever you are
% 
% java Hello world!
% Hello world!
%

Klauzula else if

Naredba if nije ogranièena na samo dva sluèaja. Kombiniranjem else i if dobije se else if kako bi se mogle ispitati sve moguænosti. Preradimo sada Hello program tako da barata sa 4 imena s komandne linije.

 
class Hello {
 
    public static void main (String args[]) {
    
      if (args.length == 0) {
        System.out.println("Hello whoever you are");
      }
      else if (args.length == 1) {
        System.out.println("Hello " + args[0]);
      }
      else if (args.length == 2) {
        System.out.println("Hello " + args[0] + " " + args[1]);
      }      
      else if (args.length == 3) {
        System.out.println("Hello " + args[0] + " " + args[1] + " " + args[2]);
      }      
      else if (args.length == 4) {
        System.out.println("Hello " + args[0] +
          " " + args[1] + " " + args[2] + " " + args[3]);
      }      
      else {
        System.out.println("Hello " + args[0] + " " + args[1] + " " + args[2] 
         + " " + args[3] + " and all the rest!");
      }
 
  }
 
}
 
% javac Hello.java
% java Hello
% Hello whoever you are
% 
% java Hello prvi drugi treci cetvrti
% Hello prvi drugi treci cetvrti
% 
% java Hello prvi drugi treci cetvrti peti
% Hello prvi drugi treci cetvrti and all the rest!
% 
 

Ipak, takav naèin ispitivanja brzo postaje kompliciran. Postoje i bolja rješenja, kao što pokazuju sljedeæi primjeri.


while petlja

class Hello {
 
  public static void main (String args[]) {
 
    int i;
    
    System.out.print("Hello ");   // Ispis Hello
    i = 0;                        // Inicijaliziramo brojac prolaza kroz petlju
    while (i < args.length) {     // Testiramo i iteriramo
      System.out.print(args[i]);  
      System.out.print(" ");
      i = i + 1;                  // Povecamo brojac prolaza za 1
    }
    System.out.println();         // Zavrsimo liniju
  }
 
}
 
% javac Hello.java
% java Hello
% Hello
% 
% java Hello prvi drugi treci cetvrti
% Hello prvi drugi treci cetvrti
% 

for petlja

class Hello {
 
  public static void main (String args[]) {
 
    System.out.print("Hello ");                   // Ispis Hello
    for (int i = 0; i < args.length; i = i + 1) { // Testiramo i iteriramo
      System.out.print(args[i]);  
      System.out.print(" ");
    }
    System.out.println();                         // Zavrsimo liniju
  }
 
}
 
% javac Hello.java
% java Hello
% Hello
% 
% java Hello prvi drugi treci cetvrti
% Hello prvi drugi treci cetvrti
% 

 

Ponekad je u for petlji potrebno inicijalizirati i inkrementirati više varijabli odjednom. U tom sluèaju se inicijalizatori i inkrementori odvajaju zarezima kao u sljedeæem primjeru:

 
for (int i = 1,  j = 100;  i < 100;  i = i+1, j = j-1)  {    
    System.out.println(i + j); 
}
 

Ipak, višestruko ispitivanje uvjeta na ovaj naèin nije dopušteno. Sljedeæa naredba rezultirala bi porukom o greški u kompilaciji:

 
for (int i = 1,  j = 100;  i <= 100, j > 0;  i = i-1, j = j-1) { // pogresno !!!
 

Za višestruko ispitivanje uvjeta koriste booleovski logièki operatori && i || o kojima æe biti rijeèi kasnije.


do while petlja

class Hello {
 
  public static void main (String args[]) {
 
    int i = -1;
    do {
      if (i == -1) System.out.print("Hello "); 
      else {
        System.out.print(args[i]);  
        System.out.print(" ");
      }
      i = i + 1;
    } while (i < args.length);
    System.out.println();
  }
 
}
 
% javac Hello.java
% java Hello
% Hello
% 
% java Hello prvi drugi treci cetvrti
% Hello prvi drugi treci cetvrti
% 

Booleovski podaci

Svaka booleovska varijabla može poprimiti jednu od dvije vrijednosti true ili false. Primijetite da te vrijednosti nisu isto što i Stringovi "true" i "false", a nisu ni numerièke vrijednosti kao 1 i 0. Takoðer primijetite da su rijeèi true i false rezervirane rijeèi u Javi, nazivaju se booleovski literali i osjetljive su na velika i mala slova.

 
boolean test1 = true;
boolean test2 = false; 

Relacijski operatori

Java ima 6 relacijskih operatora koji usporeðuju dva broja i vraæaju booleovsku vrijednost. To su <, >, <=, >=, ==, i !=.

 

x < y

Manje

True ako je x manje od y, inaèe false.

x > y

Veæe

True ako je x iveæe od y, inaèe false.

x <= y

Manje ili jednako

True ako je x manje ili jednako y, inaèe false.

x >= y

Veæe ili jednako

True ako je x veæe ili jednako + y, inaèe false.

x == y

Jednako

True ako je x jednako y, inaèe false.

x != y

Nejednako

True ako je x razlièito od y, inaèe false.

 

Sljedeæi primjeri koda pokazju uporabu relacijskih operatora:

 
boolean test1 = 1 < 2;               // True
boolean test2 = 1 > 2;               // False
boolean test3 = 3.5 != 1;            // True
boolean test4 = 17*3.5 >= 67.0 - 42; // True
boolean test5 = 9.8*54 <= 654;       // True
boolean test6 = 6*4 == 3*8;          // True
boolean test7 = 6*4 <= 3*8;          // True
boolean test8 = 6*4 < 3*8;           // False
 

To, meðutim ne ilustrira tipiènu uporabu booleovskih varijabli. U praksi se one gotovo jedino koriste u kondicionalnim naredbama i ispitivanjima uvjeta u petljama. Veæ smo vidjeli primjer:

 
if (args.length > 0) {
  System.out.println("Hello " + args[0]);
}
 

gdje je args.length > 0 booleovska vrijednost, dakle true ili false. Zato možemo takoðer pisati:

 
boolean test = args.length > 0;
if (test) {
  System.out.println("Hello " + args[0]);
}

Prioritet izvršavanja relacijskih operatora

Pogledate li primjere u prethodnom odlomku, vidjet æete da se aritmetièke operacije obavljaju prije usporeðivanja. Inaèe bi npr.

 
boolean test8 = 6*4 < 3*8; // False
 

izazvalo grešku u kompiliranju jer 4 < 3 vraæa false, a to se ne može množiti sa 6 ili 8. Relacijski operatori izvršavaju se nakon aritmetièkih, a prije operatora pridruživanja. Operator == ima nešto manji prioritet nego <, >, <= i >=. Pogledajte revidiranu tablicu prioriteta:

  1. *, /, % Sva množenja, dijeljenja i modulo od lijeva na desno
  2. +, - Sva zbrajanja i oduzimanja od lijeva na desno
  3. <, >, >=, <= Sva usporeðivanja meðusobnih velièina
  4. ==, != Sva usporeðivanja jednakosti i nejednakosti
  5. = Pridruživanje desne strane lijevoj

Na primjer:

 
boolean b1 = 7 > 3 == true;
boolean b2 = true == 7 > 3;
b = 7 > 3;

Ispitivanje jednakosti objekata

Operatori <, >, <= i >= mogu se primijeniti jedino na brojeve i znakove. Ne mogu se koristiti sa Stringovima, booleovskim varijablama poljima (arrays) kao ni s drugim neprimitivnim tipovima za koje nije definiran linearni ureðaj. Za jednakost == vrijedi pravilo da je true jednako true i razlièito od false. Isto tako je “Jack went up the hill” razlièito od “Jill went up the hill”. Meðutim, pokušajte izvršite sljedeæi program:

class JackAndJill {
 
  public static void main(String args[]) {
 
    String s1 = new String("Jack went up the hill.");
    String s2 = new String("Jack went up the hill.");
 
    if ( s1 == s2 ) {
      System.out.println("Stringovi su jednaki.");
    }
 
    else if ( s1 != s2 ) {
      System.out.println("Stringovi nisu jednaki.");
    }
  }
}

 

Vidjet æete da je rezultat (neoèekivano):

 
Stringovi nisu jednaki.

 

To nije ono što oèekujemo. Da bismo usporeðivali stringove ili objekte bilo koje druge vrste, koristimo se metodom equals(Object o) iz paketa java.lang.String. Pogledajmo ispravnu verziju programa koja æe raditi onako kako oèekujemo. Razlozi za ovo sežu prilièno duboko u filozofiju Jave i prirodu objekata kakvi su npr. stringovi.

 
class JackAndJill {
 
  public static void main(String args[]) {
 
    String s1 = new String("Jack went up the hill.");
    String s2 = new String("Jack went up the hill.");
 
    if ( s1.equals(s2) ) {
      System.out.println("Stringovi su jednaki.");
    }
    else {
      System.out.println("Stringovi nisu jednaki.");
    }
  }
}
 
% javac JackAndJill.java
% java JackAndJill
Stringovi su jednaki.
% 

Naredba break

Naredba break uzrokuje izlazak izpetlje prije nego što uvjet za ulazak u sljedeæu iteraciju postane lažan. Na primjer, u sljedeæoj varijanti programa CountWheat koji raèuna parcijalne sume reda Si=1,…,64(2i) pri èemu se ispisuje poruka o pogreški i for petlja se prekida èim nastane overflow pa (2i) postane negativan.

 
class CountWheat  {
 
  public static void main (String args[]) {
  
    int total = 0;
    int grains = 1;
 
    for (int square=1; square <= 64; square++) {
      grains *= 2;
      if (grains <= 0) {
        System.out.println("Overflow: grains = " + grains);
        break;
      }
      total += grains;
      System.out.print(total + "\t  ");
      if (square % 4 == 0) System.out.println();
    } 
    System.out.println("Gotovo!");
 
  }
 
}

 

Pogledajmo obradu i izlaz:

 
% javac CountWheat.java
% java CountWheat
2            6           14              30
62           126         254             510
1022         2046        4094            8190
16382        32766       65534           131070
262142       524286      1048574         2097150
4194302      8388606     16777214        33554430
67108862     134217726   268435454       536870910
1073741822   2147483646      Overflow: grains = -2147483648
Gotovo!
%
 

Naredba break najèešæe se koristi unutar naredbe switch.


Naredba continue

Naredba continue vraæa kontrolu na poèetak najbliže unutarnje petlje kojom je obuhvaæena, ne izvršavajuæi pri tom ostatak naredbi u tijelu petlje. Ako je to for petlja, brojaè se inkrementira. Sljedeæi primjer pokazuje kako se može preskoèiti obrada parnih elemenata u polju:

for (int i = 0; i < m.length; i++) {
 
  if (m[i] % 2 == 0) continue;
  // obrada neparnih elemenata...
 
}
 

U praksi se nardba continue ipak rjeðe koristi jer se u veæini sluèajeva problem može riješiti i bez nje. Prethodni primjer mogao je izgledati i ovako:

 
for (int i = 0; i < m.length; i++) {
 
  if (m[i] % 2 != 0) {
    // obrada neparnih elemenata...
 
  }
 
}

Labelirane petlje

U pravilu unutar ugnjiježdenih petlji naredbe break i continue uzrokuju napuštanje najunutarnjije petlje koja ih obuhvaæa. Pogledajte sljedeæi primjer dvije ugniježdene petlje:

 
for (int i=1; i < 10; i++) {
  for (int j=1; j < 4; j++) {
    if (j == 2) break;
    System.out.println(i + ", " + j);
  }
}
 

Rezultat izvršavanja bio bi

 
1, 1
2, 1
3, 1
4, 1
5, 1
6, 1
7, 1
8, 1
9, 1
 

jer se unutarnja petlja prekine svaki put kad j postane 2, ali se vanjska petlja izvrši do kraja. Ako želimo prekinuti obje petlje, labelirajmo vanjsku petlju i navedimo tu labelu u break naredbi:

 
iloop: for (int i=1; i < 3; i++) {
  for (int j=1; j < 4; j++) {
    if (j == 2) break iloop;
    System.out.println(i + ", " + j);
  }
}
 

Sada bi rezultat izvršavanja bio

 
1, 1
 

jer je j postao 2, a vanjska petlja je prekinuta.


Naredba switch-case

Switch-case naredba je zapravo kratica za odreðene vrste if naredbi. Pogledajmo sljedeæi niz if naredbi koje se sve odnose na istu velièinu:

 
if (x == 0) doSomething0();
else if (x == 1) doSomething1();
else if (x == 2) doSomething2();
else if (x == 3) doSomething3();
else if (x == 4) doSomething4();
else doSomethingElse();
 

Ovaj bi se kod uz pomoæ switch-case naredbe mogao zapisati ovako:

 
switch (x) {
  case 0: 
    doSomething0();
    break;
  case 1: 
    doSomething1();
    break;
  case 2: 
    doSomething2();
    break;
  case 3: 
    doSomething3();
    break;
  case 4: 
    doSomething4();
    break;
  default: 
    doSomethingElse();
}
 

U ovom primjeru x mora biti varijabla ili izraz koji se izraèunava ili pretvara u int bez gubitka informacija To znaèi da varijabla mora biti, odnosno da izraz mora vraæati rezultat tipa int, byte, short ili char. Izraz x usporeðuje se redom s vrijednostima navedenim u svakoj case naredbi dok se ne naiðe na podudarnost. U našem primjeru se x usporeðuje s literalima, ali to takoðer mogu biti varijable ili izrazi koji vraæaju rezultat tipa int, byte, short ili char. Ako se ni u jednom sluèaju ne pronaðe podudarnost izvršava se akcija naznaèena sa default.

Kad je podudarnost pronaðena, izvršava se sve što slijedi do kraja switch bloka ili naredbe break. Uobièajeno je stavljati break naredbu na kraj svakog case bloka kako bi se izbjegli razni neoèekivani efekti.


Kondicionalni operator (? :)

Vrijednost neke varijable èesto ovisi samo o tome je li neka booleovska varijabla istinita ili ne. Npr. jedna od uobièajenih operacija je traženje maksimuma izmeðu dvije vrijednosti i pridruživanje te velièine nekoj varijabli:

 
if (a > b) {
  max = a;
}
else {
  max = b;
}
 

Kako je ovo èesta situacija, uveden je kondicionalni operator ? : kao kratica za ovakvu if-else strukturu. Ovaj bismo primjer mogli pisati ovako:

max = (a > b) ? a : b;

pri èemu je (a > b) ? a : b; izraz koji vraæa jednu od dvije vrijednosti, a ili b, ovisno o tome je li uvjet (a > b) istinit ili lažan. Ako je istinit, vraæa se a, u suprotnom b. Uvjet može biti bilo koji izraz koji vraæa booleovsku vrijednost.

Kondicionalni operator funkcionira jedino kod pridruživanja vrijednosti nekoj varijabli, korištenja vrijednosti za pozivanje metode ili u nekim drugim situacijama kad je tip njegovog drugog i treæeg argumenta definiran. Pogledajmo sljedeæi primjer:

 
if (name.equals("Rumplestiltskin")) {
  System.out.println("Give back child");
}
else {
  System.out.println("Laugh");
}
 

Ovo se ne može zapisati ovako:

 
name.equals("Rumplestiltskin")           // ovo je primjer pogresne upotrebe operatora ?:
 ? System.out.println("Give back child") 
 : System.out.println("Laugh");
 

Prije svega, drugi i treæi argument su void (ne vraæaju vrijednost). Takoðer, nikakvo pridruživanje ne naznaèuje tip koji bi trebalo oèekivati za drugi i treæi operator (iako se zna da to ne može biti void).

Prvi argument mora vraæati regularni booleovski tip, a drugi i treæi argument moraju vraæati vrijednosti koje su kompatibilne sa cijelim oèekivanim povratnim izrazom. Nikad ne možete koristiti void metode kao argumente kondicionalnog operatora.


Logièki operatori

Do sada uvedeni relacijski operatori (<, <=, >, >=, !=) dovoljni su za testiranje pojedinaènog uvjeta.Za ispitivanje višestrukih uvjeta, morali bismo koristiti više if naredbi:

 
if (x == 2) {
  if (y != 2) {
     System.out.println("Oba uvjeta su true.");
   }
}
 

To, meðutim, može biti nepregledno, a taj nedostatak rješava se uporabom logièkih operatora &&, || i !.

Operator && je logièki and koji za dvije booleovske vrijednosti i vraæa true ako i samo ako su oba operanda true. Npr.

boolean b;
b = 3 > 2 && 5 < 7; // b je true
b = 2 > 3 && 5 < 7; // b je sada false
 

Operator || je logièki or koji za dvije booleovske vrijednosti vraæa true ako je bar jedan operand true. Npr.

 
boolean b;
b = 3 > 2 || 5 < 7; // b je true
b = 2 > 3 || 5 < 7; // b je i dalje true
b = 2 > 3 || 5 > 7; // now b je false
 

Operator ! je logièka negacija koja za booleovsku vrijednost vraæa true ako je operand false i obrunuto. Npr.

 
boolean b;
b = !(3 > 2); // b je false
b = !(2 > 3); // b je true
 

Ovi operatori omoguæuju jednostavnje ispitivanje višestrukih uvjeta. Naš prvi primjer može se sada zapisati mnogo preglednije:

 
if (x == 2 && y != 2) {
  System.out.println("Oba uvjeta su true.");
}

Prioritet izvršavanja logièkih operatora

Prilikom izvršavanja operatora && ili||, prvo se izraèunava izraz na lijevoj strani operatora. Pogledajmo sljedeæi primjer:

 
boolean b, c, d;
b = !(3 > 2); // b je false
c = !(2 > 3); // c je true
d = b && c;   // d je false
 

Kad se izraèunava izraz d = b && c;, prvo se provjerava da li je b true. Ovjdjeje b false, pa onda takoðer b && c mora biti false bez obzira je li c true ili nije. Zato se vrijednost varijable c u ovom izrazu uopæe ne provjerava.

Na isti naèin, kad Java naiðe na operator ||, pokušat æe skratiti izraèunavanje èim ustanovi da je lijevi operand true, jer onda i cijeli rezultat mora biti true.

boolean b = (n == 0) || (m/n > 2);
 
boolean b = (n != 0) && (m/n > 0);
 

Èak ako je n jednako nuli, neæe se dogoditi dijeljenje s nulom jer se lijeva strana prva izraunava, a ako je istinita, onda se desna neæe ni raèunati. Ova skraæivanja nisu za Javu toliko znaèajna kao za C jer u Javi oba operanda za && i || moraju biti booleovska pa to reducira sporedne efekte koji ovise o tome jesu li ili operandi stvarno izraèunati. No svejedno, moguæe je eksplicitno specificirati raèunanje oba operanda, tj. izbjeæi skraæivanje.

 

Ako želite izraèunavati vrijednosti booleovskih izraza bez obzira na istinosnu vrijednost možete se koristiti operatorima & i | (bitovski and i bitovski or) umjesto && i ||. Meðutim, pazite da operandi budu zaista booleovski jer ovi operatori imaju svoj smisao i za numerièke tipove, a znaèenje im je ondje posve drugaèije.

 

Dodajmo konaèno operatore &&, ||, &, | i ? u tablicu prioriteta:

  1. *, /, % Multiplikativni operatori
  2. +, - Aditivni operatori
  3. <, >, >=, <= Relacijski operatori
  4. ==, != Usporedbe jednakosti i nejednakosti
  5. & Bitovski and
  6. | Bitovski or
  7. && Logièki and
  8. || Logièki or
  9. ? : Kondicionalni operator
  10. = Operator pridruživanja

Deklariranje polja

Polja moraju imati odreðeni tip, npr. byte, int, String ili double. Samo varijable odgovarajuæeg tipa mogu biti spremljene u isto polje. Jedno polje ne može istodobno sadržavati recimo brojeve i stringove. Polja moraju kao i ostale varijable biti deklarirana. Deklariraju se dodavanjem uglatih zagrada [] kao sufiks tipu varijable. Na primjer:

 

int[] k;
float[] yt;
String[] names;
 

Ovo znaèi da je k polje int-ova, yt polje float-a, a names polje String-ova. Uglate zagrade možete po vlastitom izboru dodati i varijabli umjesto tipu ili èak jednom i drugom.

 

int k[];
float yt[];
String names[];
 
int[] k[];
float[] yt[];
String[] names[];

Kreiranje polja

Deklarirajuæi polje samo smo rekli koje vrste vrijednosti æe polje sadržavati. Time ga još nismo kreirali. Polja se kao i ostali objekti u Javi kreiraju pomoæu kljuène rijeèi new. Varijable koje smo maloprije deklarirali možemo kreirati ovako:

 
k = new int[3];
yt = new float[7];
names = new String[50];
 

Brojevi u uglatim zagradama specificiraju duljinu polja, tj. Koliko ima komponenata koje æe sadržati vrijednosti. Polje k može imati 3 broja tipa int, polje yt može sadržati 7 brojeva tipa float, a polje names može sadržati 50 String-ova. Ovaj se korak ponekad naziva alociranjem polja jer se njime izdvaja potrebna memorija za polje.


Inicijaliziranje polja

Pojedinaène komponente polja referenciraju se imenom polja i cijelim brojem koji predstavlja poziciju komponente unutar polja. Ovi se brojevi nazivaju subskriptima ili indeksima komponenti u polju. Indeksi su cijeli brojevi poèevši od 0 (nula). Dakle gore deklarirano polje k ima komponente k[0], k[1] i k[2]. Buduæi da se poèinje od nule, ne postoji k[3]. Pokušaj referenciranja nepostojeæe komponente rezultirat æe odbacivanjem iznimke ArrayIndexOutOfBoundsException. Komponente polja mogu se upotrebljavati kao i druge varijable koje nisu komponente polja.

 
k[0] = 2;
k[1] = 5;
k[2] = -2;
yt[17] = 7.5f;
names[4] = "Fred";
 

Ovaj se korak naziva inicijaliziranjem polja, preciznije inicijaliziranjem komponenata polja. Pod inicijaliziranjem polja obièno se podrazumijeva inicijaliziranje svih komponenata polja. Naravno da za iole veæa polja neæemo inicijalizirati jednu po jednu komponentu, nego æemo se poslužiti petljom kao u sljedeæem primjeru:

 
float[] squares;
squares = new float[101];
 
for (int i=0; i <= 100; i++) {
   squares[i] = i*i;
}
 

Primijetimo da æe brojevi tipa int kad budu spremljeni u ovo polje postati float jer je polje tako deklarirano.


Metoda System.arraycopy()

Kopiranje polja nije neki težak zadatak, ali je efikasnije ako je implementirano u samom sustavu. Zato java.lang.System sadrži statièku metodu System.arraycopy() koju možete koristiti za kopiranje jednog polja u drugo. Definirana je ovako:

 
public static void arraycopy(Object source, int sourcePosition, 
 Object destination, int destinationPosition, int numberOfElements)
 

Metoda System.arraycopy() kopira numberOfElements elemenata iz polaznog poja source, poèevši s elementom na poziciji sourcePosition, na polje destination poèevši od pozicije destinationPosition. Polje destination mora veæ postojati u trenutku pozivanja metode System.arraycopy() jer ga ona sama neæe kreirati.. Polja source i destination moraju biti istog tipa. Na primjer,

 

 int[] unicode = new int[65536];
  for (int i = 0; i < unicode.length; i++) {
    unicode[i] = i;
  }
  int[] latin1 = new int[256];
  System.arraycopy(unicode, 0, latin1, 0, 256);

Deklariranje, alociranje i inicijaliziranje dvodimenzionalnih polja

Dvodimenzionalna polja se deklariraju, alociraju i inicijaliziraju slièno kao jednodimenzionalna. Specificirat æete dvije dimenzije umjesto jedne i vjerojatno koristiti dvije ugniježdene petlje. U sljedeæem primjeru se svakom elementu dvodimenzionalnog polja dodjeljuje suma njegovih indeksa.

 
class FillArray {
 
  public static void main (String args[]) {
  
    int[][] matrix;
    matrix = new int[4][5];
  
    for (int row=0; row < 4; row++) {
      for (int col=0; col < 5; col++) {
        matrix[row][col] = row+col;
      }
    }
    
  }
  
}
 

Naravno, algoritam za punjenje polja ovisi iskljuèivo o namjeni pojedinog polja. U sljedeæem primjeru raèunamo jediniènu matricu zadane velièine (kvadratnu matricu koja po dijagonali ima jedinice, a ostali elementi su nule).

 

class IDMatrix {
 
  public static void main (String args[]) {
  
    double[][] id;
    id = new double[4][4];
  
    for (int row=0; row < 4; row++) {
      for (int col=0; col < 4; col++) {
        if (row != col) {
          id[row][col]=0.0;
        }
        else {
          id[row][col] = 1.0;
        }
      }
    }
    
  }
  
}

 

U dvodimenzionalnom polju iznimka ArrayIndexOutOfBoundsException pojavljuje se kad god prekoraèite maksimalni indeks bilo po recima bilo po stupcija.

Dvodimenzionalno polje možete takoðer deklarirati, alocirati i inicijalizirati u jednom koraku, zadajuæi listu inicijalnih vrijednosti unutar ugniježdenih vitièastih zagrada. Npr. jedinièna 3x3 matrica može se zadati ovako:

double[][] ID3 = {
  {1.0, 0.0, 0.0},
  {0.0, 1.0, 0.0},
  {0.0, 0.0, 1.0}
};

 

Razmaci i prijelomi redaka su iskljuèivo zbog programera. Sljedeæi zapis bio bi posve ekvivalentan prethodnom:

 

double[][] ID3 = {{1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{0.0, 0.0, 1.0}};

Višedimenzionalna polja i neuravnotežena polja

Ne morate se ogranièavati na dvodimenzionalna polja. Java dopzšta polja od 3, 4 ili više dimenzija. Ipak, ako trebate više od 3 dimenzije za polje, vjerojatno koristite pogrešnu strukturu podataka. Èak su i trodimenzionalna polja rijetka osim u programima za znanstvene i inženjerske aplikacije.

Sintaksa za trodimenzionalna polja je direktna ekstenzija sintakse za dvodimenzionalna. Sljedeæi program deklarira, alocira i inicijalizira jedno trodimenzionalno polje. U svaki element spremljena je suma njegovih indeksa.

class Fill3DArray {
 
  public static void main (String args[]) {
  
    int[][][] M;
    M = new int[4][5][3];
  
    for (int row=0; row < 4; row++) {
      for (int col=0; col < 5; col++) {
        for (int ver=0; ver < 3; ver++) {
          M[row][col][ver] = row+col+ver;
        }
      }
    }
    
  }
  
}

 

Potrebna je dakle dodatna ugniježdena for petlja za baratanje dodatnom dimenzijom. Sintaksa za još više dimenzije je slièna.

 

Java kao ni C nema pravih višedimenzionalnih polja. Java simulira višedimenzionalna polja koristeæi polja èiji su elementi druga polja. To znaèi da je moguæe imati i neuravnotežena polja, dakle polja u kojima dimenzija nije jednaka za sve retke. U praksi, meðutim, takve strukture valja izbjegavati.