Pole umožňuje elegantně pracovat s více hodnotami stejného typu.
Pro uložení např. deseti hodnot typu int
můžeme buď zavést deset proměnných nebo vytvořit pole o deseti
prvcích. V mnoha případech se s polem pracuje snadněji. Typ pole
zapisujeme v Javě pomocí hranatých závorek. Deklarace proměnné typu
pole položek typu int vypadá takto:
int[] p;
Proměnná typu pole je tzv. reference. Bude obsahovat odkaz
(referenci) na pole. Samotná deklarace pole nevytváří. Pole můžeme
vytvořit pomocí klíčového slova new:
p = new int[4];
V tomto případě jsme vytvořili pole o čtyřech prvcích typu
int. Počet prvků pole je v proměnné
length daného pole. Hodnota této proměnné
je nastavena při vytvoření pole a nelze ji změnit (je pouze pro
čtení).
System.out.printf( "pole p má %d prvků%n", p.length );
K jednotlivým prvkům pole přistupujeme pomocí indexů, které
zapisujeme do hranatých závorek:
p[1] = 5;
Indexy začínají vždy od nuly, tj. platné indexy jsou z intervalu
<0, length-1>. Pro pole p tedy
0, 1, 2 a 3. Platnost indexu se kontroluje za běhu programu.
Použití neplatného indexu způsobí běhovou chybu. Po vytvoření
jsou prvky pole inicializovány na hodnoty, jejichž vnitřní
reprezentace je 0. U číselných typů je to 0, u typu
boolean je to
false a u typu
char je to znak na pozici 0 v tabulce
Unicode. Pro načtení hodnot do pole používáme obvykle cyklus
for:
Scanner sc = new Scanner( System.in );
int[] p = new int[10];
for( int i = 0; i < p.length; i++ ) {
p[i] = sc.nextInt();
}
Výpis pole provedeme opět cyklem for:
for( int i = 0; i < p.length; i++ ) {
System.out.println( p[i] );
}
Délka pole musí být nezáporná. Pokus vytvořit pole záporné délky
způsobí chybu. Vytvoření pole lze spojit s inicializací. V takovém
případě se nepoužívá new:
int[] prvocisla = { 2, 3, 5, 7, 11, 13, 17, 19 };
Velikost pole je dána počtem hodnot ve složených závorkách. Pole
může být parametrem metody:
static int sectiPole( int[] cisla ) {
int soucet = 0;
for( int i = 0; i < cisla.length; i++ ) {
soucet += cisla[i];
}
return soucet;
}
Může být i návratovým typem:
static int[] zduplikujPole( int[] p ) {
int[] nove = new int[p.length * 2];
for( int i = 0; i < p.length; i++ ) {
nove[i] = nove[i + p.length] = p[i];
}
return nove;
}
Metoda zduplikujPole nejprve vytvoří
pole o dvojnásobném počtu prvků než má pole
p a pak pole p
dvakrát za sebou překopíruje do nově vytvořeného pole. Návratovou
hodnotou metody je nově vytvořené pole.
Velikost vytvářeného pole nemusí být konstantní výraz, tj. nemusí
být známa při překladu. Můžeme vytvořit pole, jehož počet prvků je
dán např. hodnotou proměnné.
Scanner sc = new Scanner( System.in );
int n = sc.nextInt();
double[] p = new double[n]; // velikost pole je dána proměnnou n
Proměnná typu pole obsahuje odkaz (referenci) na pole. Každá
reference zabírá v JVM 32 bitů. Do proměnné typu pole lze přiřadit
hodnotu jiné proměnné stejného typu. Při přiřazení dojde ke
zkopírování hodnoty reference.
Při předávání pole do metody se předává hodnota reference.
Nedochází tedy k žádnému kopírování pole. To umožňuje v metodě
měnit hodnoty prvků pole předaného jako parametr.
// prohodí první a poslední prvek v poli
static void prohod( int[] p ) {
int n = p.length – 1, pp = p[0];
p[0] = p[n];
p[n] = pp;
}
Při volání je do proměnné p zkopírována
hodnota skutečného parametru.
int[] cisla = { 1, 2, 3 };
prohod( cisla );
// pole cisla obsahuje hodnoty 3, 2, 1
System.out.printf( "%d, %d, %d%n", cisla[0], cisla[1], cisla[2] );
Hodnotu skutečného parametru ve volané metodě změnit nelze. Lze
měnit pouze hodnoty v poli, na které skutečný parametr odkazuje.
// tato metoda nemá žádný efekt, protože p je lokální proměnná
static void metodaNula( int[] p ) {
p = new int[2];
p[0] = 10;
p[1] = 20;
}
Po provedení metody metodaNula bude
hodnota skutečného parametru stejná jako před voláním.
int[] cisla = { 1, 2, 3 };
metodaNula( cisla );
// pole cisla obsahuje hodnoty 1, 2, 3
System.out.printf( "%d, %d, %d%n", cisla[0], cisla[1], cisla[2] );
Úloha 1
Doplňte vytvoření pole c tak, aby po
provedení cyklu obsahovalo všechny znaky anglické abecedy.
Úloha 2
Doplňte tělo metody, jež nastaví prvky v poli
h na hodnotu v.
Úloha 3
Doplňte tělo metody, která obrátí pořadí prvků v poli.
Úloha 4
Doplňte tělo metody obsahuje.
Metoda vrací true pokud pole
p obsahuje hodnotu
h, jinak vrací
false.
Úloha 5
Doplňte tělo metody, která sečte dva vektory typu
double. Vektory nemusí mít stejný počet
prvků.
Úloha 6
Napište ve správném pořadí.
Úloha 7
Rozhodněte, zda je tvrzení pravdivé.
Otázky a odpovědi
Studentka:
Mistře, pokud mám počet prvků pole v proměnné, můžu tuto
proměnou používat namísto proměnné
length? Např. v následujícím kódu
je počet prvků pole v proměnné n:
Scanner sc = new Scanner( System.in );
int n = sc.nextInt();
double[] h = new double[n];
Můžu proměnnou n použít v cyklu pro
práci s polem? Např. takto:
for( int i = 0; i < n; i++ ) {
//...
}
Java guru:
Můžeš, takto zapsaný cyklus je správně. Použití proměnné
length je však většinou lepší.
Představ si, že se po napsání tohoto kódu rozhodneš změnit
délku pole z n na
n+1.
Scanner sc = new Scanner( System.in );
int n = sc.nextInt();
double[] h = new double[n + 1]; // n změníme na n+1
for( int i = 0; i < h.length; i++ ) {
h[i] = sc.nextInt();
}
Pokud jsi dále v kódu používala důsledně proměnnou
length, stačí změnit délku pole na
jednom místě – při vytváření. Pokud jsi ovšem používala
n jako počet prvků pole, bude potřeba
každý výskyt n nahradit výrazem
n+1.
Studentka:
Mistře, patří new mezi operátory?
Java guru:
Nepatří. V některých učebnicích jej mezi operátory počítají,
není to však zcela správně. V Javě to operátor není. Nicméně
rozdíl mezi tím, zda to operátor je či není, je víceméně
formální. Takže si z toho nemusíš dělat těžkou hlavu.