Table of Contents

Pierwszy program w Javie

Oto przykład najprostszego programu napisanego w Javie:

public class Hai {
    public static void main(String[] args) {
        System.out.println("Haiii, mates!");
    }
}

Po kolei:

Typy danych

Typy całkowite

To oczywiście liczby pozbawione części ułamkowej. Mamy tu cztery typy:

Typ Liczba bajtów Zakres
int 4 -2 147 483 648 do 2 147 483 647
short 2 -32 768 do 32 767
long 8 -9 223 372 036 854 775 808 do 9 223 372 036 854 775 808
byte 1 -128 do 127

Najczęściej wystarcza typ int.

Typy zmiennoprzecinkowe

To liczby z częścią ułamkową. W Javie istnieją dwa takie typy:

Typ Liczba bajtów Zakres
float 4 około +/- 3,40282347E+38F (6 - 7 cyfr dziesiętnych)
double 8 około +/- 1,79769313486231570E+308 ( 15 cyfr dziesiętnych)

Najczęściej stosujemy double.

Typ char

To typ, służący do reprezentacji pojedynczych znaków. Trochę bardziej skomplikowany, później dopiszę. FIXME

public class CharCodeCalcs {
    public static void main(String[] args) {
        char litera1 = 'A';                   // litera1 = 'A'
        char litera2 = (char)(litera1+1);     // litera2 = 'B'
        char litera3 = litera2;               // litera3 = 'B'
 
        System.out.println("Oto sekwencja liter: " + litera1
                + litera2 + (++litera3));
        // litera3 to teraz 'C'
 
        System.out.println("A to kody dziesiętne liter:\n"
                      + litera1 + ": " + (int)litera1 +
                "   " + litera2 + ": " + (int)litera2 +
                "   " + litera3 + ": " + (int)litera3);
 
        System.out.println("Tu z kolei kody szesnastkowe:\n"
                      + litera1 + ": " + Integer.toHexString(litera1) +
                "   " + litera2 + ": " + Integer.toHexString(litera2) +
                "   " + litera3 + ": " + Integer.toHexString(litera3));
    }
}

wygeneruje:

Oto sekwencja liter: ABC
A to kody dziesiętne liter:
A: 65   B: 66   C: 67
Tu z kolei kody szesnastkowe:
A: 41   B: 42   C: 43

Typ boolean

Typ logiczny, przechowuje dwie wartości: true i false. Sprawdzamy dzięki nim warunki logiczne. Nie można ich konwertować na inne typy.

Zmienne

Każda zmienna musi mieć określony typ. Zmienne deklarujemy poprzez napisanie nazwy typu i nazwy zmiennej. Przykładowo:

int wiek;
double LiczbaP0rn;
boolean hawt;
 
/* Kilka deklaracji można umieścić w jednej linii */
 
int i, j;
 
/* Lub bardziej czytelnie: */
int mile    = 0,
    jardy   = 0,
    stopy   = 0,
    cale    = 0;

Inicjacja zmiennych

Po deklaracji koniecznym jest zainicjalizowanie zmiennych. Robimy to za pomocą operatora równości (=).

int wiek;
wiek = 25;
 
/* Lub w jednej linii */
 
int wiek = 25;

Dobry styl programowania nakazuje deklarowanie zmiennych jak najbliżej miejsca ich pierwszego użycia.

Stałe

Stałe w języku Java oznacza się słowem kluczowym final. Oznacza ono, że nie można zmieniać ich wartości. Dobrą praktyką jest pisanie stałych KAPITALIKAMI.

public class Stale {
    public static void main(String[] args) {
        final double LICZBA_P0RN = 12683.6;
        double trend = 3.4;
 
        System.out.println("Liczba p0rn na dysku po roku: " +
                LICZBA_P0RN * trend + ".");
    }
}

W Javie często korzysta się ze stałych klasowych, tj. stałych dostępnych dla metod jednej klasy. Takie stałe definiujemy za pomocą słowa kluczowego static final.

public class Stale {
    public static void main(String[] args) {
        double trend = 3.4;
 
        System.out.println("Liczba p0rn na dysku po roku: " +
                LICZBA_P0RN * trend + ".");
    }
    public static final double LICZBA_P0RN = 12683.6;
}

W tym przykładzie definicja stałej LICZBA_P0RN umieszczona została poza metodą main, dzięki czemu dostępna będzie dla innych metod klasy Stale. Dzięki słowu kluczowemu public stała dostępna jest także dla metod innych klas.

Operatory

Podstawowe operacje wykonujemy znanymi wszystkim operatorami matematycznymi ( +, -, *, /). Reszta z dzielenia to % (modulo). Dzielenie całkowitoliczbowe przez zero wygeneruje wyjątek, podczas gdy dzielenie zmiennoprzecinkowej liczby przez zero daje nieskończoność lub wartość NaN (Not a Number).

20 - 3 * 3 - 9 / 3    // wynik to oczywiście 8

Operatory relacyjne i logiczne

Operatory relacyjne:

2 == 4     // sprawdzamy czy argumenty są równe, wyrażenie zwróci wartość false
 
2 != 4     // operator różności; true
 
2 < 4      // true
 
2 <= 4     // true

Operatory logiczne to && (AND - koniunkcja) i || (OR - alternatywa).

Mamy również operator trójargumentowy w postaci ?:. Jeśli warunek ma wartość true, to wyrażenie ma wartość wyrażenie1. W przeciwnym wypadku wyrażenie2.

warunek ? wyrażenie1 : wyrażenie2
 
x < y ? x : y

Operatory bitowe

Operatory te umożliwiają dostęp bezpośrednio do bitów, z których składają się typy całkowitoliczbowe. Można, za pomocą technik maskowania, dobrać się do poszczególnych bitów w liczbie. Operatory bitowe to:

int czwartyBitOdLewej = (n & (1 << 3)) >> 3

Bitowe operatory AND i OR:

import static java.lang.Integer.toBinaryString;
 
public class BitwiseOps {
    public static void main(String[] args) {
        int wskazniki = 0xFF07;
        int wybierz3Bit = 0x4;      // maska do wybrania 3go bitu
 
        // wypróbujmy bitowe AND aby wybrać trzeci bit w 'wskazniki'
        System.out.println("wskazniki                = "
                + toBinaryString(wskazniki));
        System.out.println("wybierz3Bit              = "
                + toBinaryString(wybierz3Bit));
        wskazniki &= wybierz3Bit;
        System.out.println("wskazniki & wybierz3Bit  = "
                + toBinaryString(wskazniki));
 
        // wypróbujmy bitowe OR by włączyć trzeci bit
        wskazniki = 0xFF09;
        System.out.println("\nwskazniki                = "
                + toBinaryString(wskazniki));
        System.out.println("wybierz3Bit              = "
                + toBinaryString(wybierz3Bit));
        wskazniki |= wybierz3Bit;
        System.out.println("wskazniki | wybierz3Bit  = "
                + toBinaryString(wskazniki));
 
        // teraz znowu wyłączmy trzeci bit
        wskazniki &= ~wybierz3Bit;
        System.out.println("\nTrzeci bit poprzedniej wartości 'wskazniki'" +
                " został wyłączony");
        System.out.println("wskazniki & ~wybierz3Bit = "
                + toBinaryString(wskazniki));
    }
}

wygeneruje:

wskazniki                = 1111111100000111
wybierz3Bit              = 100
wskazniki & wybierz3Bit  = 100

wskazniki                = 1111111100001001
wybierz3Bit              = 100
wskazniki | wybierz3Bit  = 1111111100001101

Trzeci bit poprzedniej wartości 'wskazniki' został wyłączony
wskazniki & ~wybierz3Bit = 1111111100001001

Operatory przesunięć:

Przykład:

import static java.lang.Long.toHexString;
 
public class PackingCharacters {
    public static void main(String[] args) {
        char literaA = 'A';
        char literaB = 'B';
        char literaC = 'C';
        char literaD = 'D';
        long spakowana = 0L;
        spakowana = literaD;
 
        spakowana = (spakowana << 16) | literaC;    // przesuń i dodaj następną literę - C
        spakowana = (spakowana << 16) | literaB;    // przesuń i dodaj następną literę - B
        spakowana = (spakowana << 16) | literaA;    // przesuń i dodaj następną literę - A
        System.out.println("spakowana zawiera teraz 0x" + toHexString(spakowana));
 
        // rozpakujmy teraz litery i wyświetlmy je
        long maska = 0xFFFF;                             // 16 bitów jako 1 najbardziej na prawo
        char litera = (char)(spakowana & maska);    // wyciągnij najbardziej na prawo przesunięta literę
        System.out.println("Od prawej do lewej, litery zawarte w 'spakowana' to: ");
        System.out.println("   " + litera + "  0x" + toHexString(litera));
 
        spakowana >>= 16;                               // przesuń literę, która jest najbardziej na prawo
        litera = (char)(spakowana & maska);         // wyciągnij nową literę, najbardziej na prawo
        System.out.println("   " + litera + "  0x" + toHexString(litera));
 
        spakowana >>= 16;                               // przesuń literę, która jest najbardziej na prawo
        litera = (char)(spakowana & maska);         // wyciągnij nową literę, najbardziej na prawo
        System.out.println("   " + litera + "  0x" + toHexString(litera));
 
        spakowana >>= 16;                               // przesuń literę, która jest najbardziej na prawo
        litera = (char)(spakowana & maska);         // wyciągnij nową literę, najbardziej na prawo
        System.out.println("   " + litera + "  0x" + toHexString(litera));
    }
}

wygeneruje:

spakowana zawiera teraz 0x44004300420041
Od prawej do lewej, litery zawarte w 'spakowana' to: 
   A  0x41
   B  0x42
   C  0x43
   D  0x44

Metody bitowe:

import static java.lang.Long.*;
 
public class TryBitMethods {
    public static void main(String[] args) {
        long liczba = 0xF00000000000000FL;
        System.out.println("liczba:\n" + toBinaryString(liczba));
        long wynik = rotateLeft(liczba, 2);
        System.out.println("liczba obrócona w lewo o dwa bity:\n" +
                toBinaryString(wynik));
        wynik = rotateRight(liczba, 3);
        System.out.println("liczba obrócona w prawo o 3 bity:\n" +
                toBinaryString(wynik));
        wynik = reverse(wynik);
        System.out.println("Poprzedni wynik w odwrotnej kolejności:\n" +
                toBinaryString(wynik));
        System.out.println("Liczba bitów w liczbie: " + bitCount(liczba));
    }
}

wygeneruje:

liczba:
1111000000000000000000000000000000000000000000000000000000001111
liczba obrócona w lewo o dwa bity:
1100000000000000000000000000000000000000000000000000000000111111
liczba obrócona w prawo o 3 bity:
1111111000000000000000000000000000000000000000000000000000000001
Poprzedni wynik w odwrotnej kolejności:
1000000000000000000000000000000000000000000000000000000001111111
Liczba bitów w liczbie: 8

Funkcje i stałe matematyczne

W klasie Math znajduje się zestaw funkcji matematycznych. Aby przykładowo podnieść liczbę do potęgi musimy skorzystać z metody pow.

double x = Math.pow(y, a);

Pierwiastek drugiego stopnia to metoda sqrt.

double x = Math.sqrt(y);

Mamy również szereg innych metod, w tym trygonometryczne (Math.sin, Math.cos, etc.) jak również funkcję wykładniczą i logarytmiczną (Math.exp i Math.log) oraz stałe określające w maksymalnym przybliżeniu stałe Π i e (Math.PI, Math.E). Aby uniknąć konieczności stosowania przedrostka Math, można zaimportować klasę Math na początku pliku:

import static java.lang.Math.*;

Konwersja typów numerycznych

Czasami chcemy konwertować zmienną z jednego typu liczbowego na inny. Mamy kilka dozwolonych rodzajów konwersji. Niektóre są bezstratne, są jednak i takie, które mogą spowodować utratę części danych. Ponadto, gdy łączymy dwie wartości o różnych typach, zostaną one najpierw przekonwertowane na wspólny typ.

FIXME

Przykład konwersji stratnej:

public class Konwersje {
    public static void main(String[] args) {
        int n = 123456789;
        float f = n;
 
        long o = 123456789;
        double p = o;
 
        long q = 123456789;
        float r = q;
        System.out.println("Konwersja int -> float.");
        System.out.println("Wartość zmiennej n (int)   :  " + n);
        System.out.println("Wartość zmiennej f (float) :  " + f);
        System.out.println("---");
        System.out.println("Konwersja long -> double.");
        System.out.println("Wartość zmiennej o (long)  :  " + o);
        System.out.println("Wartość zmiennej p (double):  " + p);
        System.out.println("---");
        System.out.println("Konwersja long -> float.");
        System.out.println("Wartość zmiennej q (long)  :  " + q);
        System.out.println("Wartość zmiennej r (float) :  " + r);
    }
}

Wygeneruje w konsoli:

Konwersja int -> float.
Wartość zmiennej n (int)   :  123456789
Wartość zmiennej f (float) :  1.23456792E8
---
Konwersja long -> double.
Wartość zmiennej o (long)  :  123456789
Wartość zmiennej p (double):  1.23456789E8
---
Konwersja long -> float.
Wartość zmiennej q (long)  :  123456789
Wartość zmiennej r (float) :  1.23456792E8

Rzutowanie

Czasem jednak chcielibyśmy przekonwertować typ double na typ int. Jest to w Javie możliwe, choć oczywiście może powodować utratę części danych. Takie konwersje nazywa się rzutowaniem (casting). Aby dokonać rzutowania, musimy przed nazwą rzutowanej zmiennej wpisać nazwę typu docelowego w okrągłych nawiasach.

double x = 3.945;
int nx = (int) x;   // x ma tu wartość 3!

Jeśli chcielibyśmy zaokrąglić liczbę zmiennoprzecinkową do najbliższej liczby całkowitej (co jest bardziej przydatne), możemy wykorzystać metodę Math.round:

double x = 3.945;
int nx = (int) Math.round(x);   // x ma tu wartość 4

W powyższym przykładzie konwersja nadal jest konieczna, gdyż metoda round zwraca wartość typu long, a tego typu wartość możemy przypisać zmiennej typu int tylko na drodze rzutowania.

Typ wyliczeniowy

Czasami chcemy, by jakaś zmienna mogła przyjmować tylko pewne, zdefiniowane wcześniej, wartości. Wykorzystać możemy typ wyliczeniowy:

enum WowClasses { MAGE, PRIEST, ROGUE, WARRIOR, PALADIN, DEATH_KNIGHT, DRUID, HUNTER }
 
/* aby zadeklarować zmienną takiego typu: */
WowClasses r = WowClasses.ROGUE;

Inny przykład:

public class TryEnumeration {
    // definiujemy typ enumeration dla dni tygodnia
    enum Dzien {Poniedzialek, Wtorek, Sroda, Czwartek, Piatek, Sobota,
            Niedziela}
 
    public static void main(String[] args) {
 
        // definiujemy trzy zmienne dnia
        Dzien wczoraj = Dzien.Czwartek;
        Dzien dzisiaj = Dzien.Piatek;
        Dzien jutro = Dzien.Sobota;
 
        // wyświetlmy watości zmiennych dnia
        System.out.println("Dzisiaj jest " + dzisiaj);
        System.out.println("Jutro będzie " + jutro);
        System.out.println("Wczoraj był " + wczoraj);
    }
}

wygeneruje:

Dzisiaj jest Piatek
Jutro będzie Sobota
Wczoraj był Czwartek

Łańcuchy

W Javie łańcuchy to szereg znaków Unicode. Nie ma tutaj typu String, jest natomiast predefiniowana klasa o takiej nazwie i każdy łańcuch w cudzysłowach jest obiektem klasy String.

String be = "Beee";
String powitanie = "Haiii";

Podłańcuchy

Jeśli chcemy wydobyć kilka znaków z jakiegoś łańcucha, możemy użyć metody substring klasy String:

String motd = "p0rn is teh win";
String p0rn = motd.substring(0, 4);

co zwróci w konsoli p0rn. Drugi parametr metody substring to pierwsza litera, której nie chcemy skopiować.

Konkatenacja

Konkatenacja to inaczej łączenie łańcuchów za pomocą znaku +. Wygląda to mniej więcej tak:

String p0rn = "p0rn";
String ftw = "for teh win";
String konkatenacja = p0rn + ftw;

co spowoduje wyświetlenie p0rnfor teh win w konsoli.

Jeżeli połączymy łańcuch z wartością nim nie będącą (na przykład liczbą), zostanie ona automatycznie przekonwertowana na łańcuch, i tak:

int wiek = 16;
String bbking = "Sweet " + wiek;

wygeneruje Sweet 16.

Łańcuchów nie można modyfikować

Klasa String nie posiada metody, która umożliwiałaby zmianę znaków w łańcuchach. Komunikatu Hello nie możemy bezpośrednio zamienić na Help! poprzez zamianę dwóch ostatnich liter. Aby tego dokonać, musimy połączyć połączyć podłańcuch, który chcemy zachować, ze znakami, które chcemy wstawić.

String powitanie = "Hello";
powitanie = powitanie.substring(0, 3) + "p!";

na wyjściu otrzymamy Help!.

Porównywanie łańcuchów

Aby sprawdzić, czy dwa łańcuchy są identyczne, korzystamy z metody equals:

s.equals(t);                         // sprawdzamy, czy łańcuchy s i t są sobie równe
"Hello".equals(powitanie);           // taki zapis również jest poprawny
"Hello".equalsIgnoreCase("hello");   // ignorujemy wielkość liter

Do porównań nie używamy ==. Stwierdzilibyśmy jedynie, czy dwa łańcuchy są przechowywane w tej samej lokalizacji. Jeżeli są w tym samym miejscu, to muszą być równe, ale można przechowywać wiele kopii jednego łańcucha w różnych miejscach.

Współrzędne kodowe znaków i jednostki kodowe

API String

W klasie String możemy znaleźć ponad 50 różnych metod. Poniżej kilka najbardziej użytecznych i przydatnych.

java.lang.String 1.0:

Składanie łańcuchów

Gdybyśmy chcieli połączyć kilka łańcuchów w jeden, moglibyśmy do tego celu wykorzystać operator konkatencji. Byłoby to jednak rozwiązanie nieefektywne, gdyż za każdym razem tworzony byłby nowy obiekt klasy String, co zabiera dużo czasu i pamięci. Dużo lepiej w tym celu wykorzystać metody klasy StringBuilder.

StringBuilder builder = new StringBuilder();    // tworzymy pusty obiekt builder klasy StringBuiler
 
builder.append(ch);    // dodajemy znak;
builder.append(str);   // dodajemy łańcuch;
 
String kompletnyLancuch = builder.toString();    // przesyłamy sekwencję znaków w obiekcie builder do obiektu klasy String

Wejście i wyjście

Odbieranie danych wejściowych

Sprawa z wysyłaniem danych na wyjście jest prosta. Z odbieraniem nie jest już tak łatwo. Aby pobrać dane ze strumienia System.in musimy skorzystać ze skanera, będącego obiektem klasy Scanner.

import java.util.*;    // klasa Scanner nie jest w podstawowym pakiecie java.lang
 
Scanner wejscie = new Scanner(System.in);    // tworzenie nowej instancji obiektu
 
String name = wejscie.nextLine();    // metoda nextLine czyta jeden wiersz danych
String imie = wejscie.next();        // metoda next z kolei czyta tylko jedno słowo
int wiek = wejscie.nextInt();        // tu natomiast wczytujemy liczbę całkowitą
double przychod = wejscie.nextDouble();  // liczba zmiennoprzecinkowa

Formatowanie danych wyjściowych

O ile metoda wyświetlania danych w konsoli za pomocą instrukcji System.out.print(x) jest poprawna, brak w niej jednak możliwości sprecyzowania na przykład wyświetlanej ilości miejsc po przecinku. Tu z pomocą przychodzi nam metoda printf.

System.out.printf("%8.2f", x);           // 3333,33
System.out.printf("%, .2f", x);          // 3 333,33
System.out.println(new Date());          // Sun Jan 03 18:37:21 CET 2010
System.out.printf("%tc", new Date());    // N sty 03 18:37:21 CET 2010
System.out.printf("%1$s %2$te %2$tB %2$tY", "Data:", new Date());    // Data: 3 styczeń 2010

Zapis i odczyt z pliku

Aby odczytać dane z pliku, musimy utworzyć obiekt Scanner z obiektu File:

Scanner wejscie = new Scanner(new File("C:\\hiddenfolder\\mojplik.txt"));

Zapis:

PrintWriter wyjscie = new PrintWriter("mojplik.txt");

Przepływ sterowania

Do kontroli przepływu sterowania używamy w Javie instrukcji warunkowych oraz pętli.

Zasięg blokowy

Blok (instrukcja złożona), to dowolna liczba instrukcji Javy ujętych w nawiasy klamrowe. Blok określa zasięg zmiennych. Bloki można zagnieżdżać.

public static void main(String[] args) {
    int n;
    . . .
    {
        int k;
        int n;      // błąd, ponownie definiujemy zmienną n
        . . .
    }               // do tego miejsca dostępna jest zmienna k
}

Instrukcje warunkowe

Instrukcja warunkowa w Javie wygląda tak:

if (warunek) instrukcja
 
/* lub w przypadku wielu instrukcji */
 
if (warunek) {
   instrukcja1;
   instrukcja2;
}
 
/* bardziej ogólna postać /*
 
if (warunek) instrukcja1 else instrukcja2
 
/* często stosujemy kilka instrukcji else if */
 
if (warunek1) {
    instrukcja1;
    instrukcja2;
}
else if (warunek2) {
    instrukcja3;
    instrukcja4;
}
else if (warunek3) {
    instrukcja5;
    instrukcja6;
}
else {
    instrukcja7;
    instrukcja8;
}

Pętle

Pętla while wykonuje instrukcję tak długo, jak długo warunek ma wartość true:

while (warunek) instrukcja
 
/* aby mieć pewność, że instrukcja wywołana zostanie przynajmniej raz stosujemy */
 
do instrukcja while (warunek)

Pętle o określonej liczbie powtórzeń

Liczba iteracji instrukcji for jest określona za pomocą licznika (lub jakiejś innej zmiennej), którego wartość zmienia się po każdym powtórzeniu:

for (int i = 1; i <= 10; i++)
    System.out.println(i);

Wybór wielokierunkowy - instrukcja switch

Gdy mamy wiele opcji do wyboru, instrukcja if-else może być mało efektywna. Od takich sytuacji mamy instrukcję switch:

switch (wybor) {
  case 1:
      . . .
      break;
  case 2:
      . . .
      break;
  default:
      . . .
      break;
}

Instrukcje przerywające przepływ sterowania

Instrukcja break:

while (years <= 100) {
    balance += payment;
    double interest = balance * interestRate / 100;
    balance += interest;
    if(balance >= goal) break;    // można umieścić ten warunek w while()
    years++;                      // ale, by uniknąć powtórzenia...
}

Instrukcja break z etykietą:

Scanner in = new Scanner(System.in);
int n;
read_data:
    while(. . .) {    // ta pętla jest oznaczona etykietą
        for(. . .) {  // ta już nie
            System.out.print("Podaj liczbę >= 0: ");
            n = in.nextInt();
            if(n < 0) break read_data;    // wyjście z pętli o etykiecie read_data
            . . .
        }
    }
if (n < 0) {    // sprawdzamy, czy ma miejsce niechciana sytuacja
    // obsługa niechcianej sytuacji
} else {
    // normalny tok
}

Instrukcja continue:

Scanner in = new Scanner(System.in);
while (sum < goal) {
    System.out.print("Podaj liczbę: ");
    n = in.nextInt();
    if (n < 0) continue;    // przenosi sterowanie do nagłówka najbardziej zagnieżdżonej pętli
    sum += n;    // wyrażenie nie zostanie wykonane, jeśli n < 0
}

Wielkie liczby

Czasem precyzja dostępnych nam typów liczb jest niewystarczająca. Na szczęście mamy do dyspozycji klasy z pakietu java.math: BigInteger i BigDecimal. Można dzięki nim wykonywać działania na liczbach składających się z dowolnej liczby cyfr. BigInteger to oczywiście liczby całkowite a BigDecimal zmiennoprzecinkowe.

Aby przekonwertować liczbę na którąś z powyższych stosujemy statyczną metodę valueOf:

BigInteger a = BigInteger.valueOf(100);

Nie możemy używać znanych nam operatorów arytmetycznych, takich jak + czy *. Zamiast nich, mamy metody:

BigInteger c = a.add(b);    // c = a + b
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2))); // d = c * (b + 2)

Tablice

int[] a;    // deklaracja tablicy do przechowywania liczb całkowitych
int a[];    // tak też poprawnie
 
int[] a = new int[100];    // deklaracja i inicjacja tablicy
 
int liczbaElementow = a.lenght;   // liczba elementów tablicy a

Pętla typu for each

Użyteczna pętla do przechodzenia przez tablice, bez używania indeksów.

for (int element : a) System.out.println(element);    // drukujemy każdy element tablicy a
 
/* to samo można uzyskać zwykłą pętlą for */
 
for (int i = 0; i < a.length; i++) System.out.println(a[i]);
 
/* ale for-each jest bardziej zwięzła i mniej podatna na błędy */

Inicjowanie tablic i tworzenie tablic anonimowych

int[] smallPrimes = { 2, 3, 5, 7, 11, 13 };    // nie używamy operatora new
 
new int[] { 17, 19, 23, 29, 31, 37 };    // tablica anonimowa
 
/* wypełniać możemy też inaczej */
import java.util.Arrays;          // wcześniej trzeba zaimportować...
 
Arrays.fill(smallPrimes, 1.0);    // tablica smallPrimes wypełniona zostanie jedynkami
smallPrimes = new int[] { 17, 19, 23, 29, 31, 37 };
 
/* to skrócona wersja zapisu: */
 
int[] anonymous = { 17, 19, 23, 29, 31, 37 };
smallPrimes = anonymous;    // SPRAWDZIĆ!

Kopiowanie tablicy

int[] luckyNumbers = smallPrimes;
luckyNumbers[5] = 12;    // element smallPrimes[5] ma wartość 12
 
/* Obie zmienne wskazują na tą samą tablicę  *
 * Aby skopiować wszystkie elementy jednej   *
 * tablicy do drugiej, możemy użyć metody    *
 * copyTo dostępnej w klasie Arrays          */
 
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);

Drugi parametr to rozmiar nowej tablicy. Dodatkowe elementy zapełniane są zerami, jeżeli tablica przechowuje liczby.

Parametry wiersza poleceń

public class Message {
 
    public static void main(String[] args) {
 
        if (args[0].equals("-h")) System.out.print("Witaj");
        else if (args[0].equals("-g")) System.out.print("Zegnaj");
 
        // drukujemy pozostałe argumenty wiersza poleceń
        for (int i = 1; i < args.length; i++) System.out.print(" " + args[i]);
        System.out.println("!");
 
    }
 
}

Uruchamiamy z linii poleceń:

java Message -g okrutny swiecie

Zegnaj okrutny swiecie!

Sortowanie tablicy

FIXME nieczytelne, psia jego mać!

Tablice wielowymiarowe

Służą do reprezentacji tabel i innych złożonych struktur danych.

double[][] balances;                      // deklaracja
balances = new double[NYEARS][NRATES];    // inicjacja
 
int[][] magicSquare =     // skrócona notacja, ponieważ znamy elementy
    {
        {16, 3, 2, 13},
        {5, 10, 11, 8},
        {9, 6, 7, 12},
        {4, 15, 14, 1}
    };

Jeśli chcemy szybko wydrukować listę elementów tablicy dwuwymiarowej (lub innej):

System.out.println(Arrays.deepToString(a));

Tablice postrzępione (ang. ragged arrays)

W Javie nie ma prawdziwych tablic wielowymiarowych - są one symulowane przez “tablice tablic”.

FIXME