====== 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:
* słowo kluczowe //public// to modyfikator dostępu (//access modifier//) - określa rodzaj dostępu do kodu z innych części programu,
* słowo kluczowe //class// - wszystko w Javie jest klasą,
* //Hai// to oczywiście nazwa klasy, musi być taka sama jak nazwa pliku zawierającego kod - w naszym przypadku ''Hai.java'',
* //static// - mówi, że metoda main() istnieje bez definiowania żadnego obiektu,
* //void// - informuje nas, że metoda nie zwraca żadnej wartości,
* //main// to metoda główna, która musi znajdować się w pliku źródłowym klasy,
* ''String[] args'' - argumenty z linii poleceń przechowywane są w tablicy args,
* instrukcja, powodująca wyświetlenie informacji w konsoli, zakończona średnikiem; używamy tutaj metody ''println()'' obiektu ''out'' klasy ''System''. Informacje w nawiasie to parametry, przekazywane do metody ''println()''.
====== 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:
* ''&'' - bitowa koniunkcja,
* ''|'' - bitowa alternatywa,
* ''^'' - bitowe wykluczenie,
* ''~'' - bitowa negacja.
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ęć:
* '<<' - przesuń w lewo, wypełniając zerami od prawej,
* '>>' - przesuń w prawo, propagując bit znaku od lewej,
* '>>>' - przesuń w prawo, wypełniając zerami od lewej.
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:
* ''char charAt(int index)'' - zwraca jednostkę kodową znajdującą się w określonej lokalizacji,
* ''int codePointAt(int index)'' 5.0 - zwraca współdzędną kodową znaku, która zaczyna się lub kończy w określonej lokalizacji,
* ''int offsetByCodePoints(int startIndex, int cpCount)'' 5.0 - ,
* ''int compareTo(String other)'' - ,
* ''boolean endsWith(String suffix)'' - ,
===== 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