1
Języki Programowania
Tablice i typy złożone
Wejście i wyjście
Wyjątki
2
Tablica
Tablice są
obiektami
do przechowywania „dużej porcji”
informacji
Tablica jest uporządkowaną listą wartości
Ta tablica przechowuje 10
wartości które mają indeksy od
0 do 9
Tablica o rozmiarze N ma indeksy od
zera do N-1
0 1 2 3 4 5 6 7 8 9
79 87 94 82 67 98 87 81 74 91
wyniki
Cała tablica ma
jedną nazwę
Każda wartość ma numeryczny
indeks
2
3
Tablice
– odwołanie do elementu
Do konkretnej wartości tablicy odwołujemy się
używając nazwy tablicy i indeksu w nawiasie
np. wyrażenie
wyniki[2]
odwołuje się do wartości
94
(trzecia
wartość
w
całej tablicy)
indeksy muszą być liczbą całkowitą
4
Tablice -
przykłady
przykłady odwołań do elementów tablicy (przypisanie, do obliczeń, do
wydruków)
wyniki
[2] = 89;
wyniki[pierwszy] = wyniki[pierwszy] + 2;
srednia = (wyniki[0] + wyniki[1])/2;
System.out.println („Max = " + wyniki[5]);
Wartości przechowywane w tablicy nazywane są tablicą elementów
Tablica przechowuje wiele elementów tego samego typu
Typ elementu może być
prymitywny
lub
może być
obiektem
Więc możemy utworzyć tablicę liczb int, znaków, tablicę obiektów
String
,
tablicę obiektów
Konto
, itp.
3
5
Tablice - definicja
Inny sposób
zobrazowania
tablicy
wyniki
:
wyniki
79
87
94
82
67
98
87
81
74
91
Tablica
wyniki
może być
zdefiniowana jako:
int
[]
wyniki
=
new
int
[10];
Typ pola
wyniki
jest
int
[] (tablica
liczb int)
N
ależy pamiętać, że tablica nie określa
rozmiaru elementu/obiektu, każdy
obiekt ma swój rozmiar
pole/zmienna
wyniki
jest ustawione
jako nowa tablica która może
przechowywać 10 liczb int
6
Deklarowanie tablic
Inne przykłady deklaracji tablic:
float
[] ceny =
new
float
[500];
boolean
[] flagi;
flagi = new
boolean
[20];
char
[] kody =
new
char
[1750];
„iterator” w pętli
for
może być używany do przetwarzania
tablicy elementów
Taki zapis jest tylko poprawny jeśli przetwarzamy wszystkie
elementy tablicy od najniższego do najwyższego indeksu
for
(
int
indeks :
wyniki
)
System.out.println (indeks);
objekt
wartość int
4
7
Sprawdzanie ograniczeń - Bounds Checking
Po utworzeniu tablicy, ma ona stały rozmiar
Oznacza to, że wartość indeksów musi być w granicach od 0 do N-1
interpreter Java
zgłasza:
ArrayIndexOutOfBoundsException
jeśli indeks tablicy jest poza granicami
nazywa to się automatyczne sprawdzanie ograniczeń -
bounds
checking
np.,
jeśli tablica
kody
może pomieścić 100 wartości, to ma indeksy
tylko od 0 do 99
jeśli zmienna
licznik
jest równa
100
, to referencja
kody[licznik]
spowoduje wyjątek
for
(
int
licznik=0; licznik <= 100; licznik++)
kody[licznik] = licznik*50 + epsilon;
problem
8
Sprawdzanie ograniczeń
każda tablica (obiekt) posiada pole (public) zwane
length
które
przechowuje rozmiar tablicy
do tego pola możemy odwołać się przez:
wyniki.length
pamiętaj, że pole
length
przechowuje liczbę elementów a nie
największy indeks
dopuszczalne są dwa sposoby deklaracji tablicy (nawiasy przy typie
elementów lub przy nazwie tablicy):
float
[] prices;
float
prices[];
Pierwszy z nich jest bardziej czytelny i powinien być używany
5
9
Inicjalizacja
– lista inicjalizacji
tworzenie instancji i wypełnianie tablicy w jednym kroku
wartości są podane w nawiasie i oddzielone przecinkami (muszą
być odpowiednie typy danych)
przykładu:
Kiedy używamy listy inicjalizacji:
nie używamy operatora
new
nie podajemy rozmiaru tablicy
rozmiar tablicy jest wyznaczany przez liczbę elementów z listy
lista inicjalizacji może być użyta tylko na etapie deklaracji
tablicy
int
[] jednostki = {147, 323, 89, 933, 540,
269, 97, 114, 298, 476};
char
[] litery = {'A', 'B', 'C', 'D', ’F'};
10
Deklaracja i inicjalizacja
Inny, prostszy sposób
Tablica jest obiektem i domyślne wartości
elementów to w tym przypadku 0!
6
11
Tablice jako parametry metod
cała tablica może być przekazana jako parametr do
metody/funkcji
podobnie jak inne obiekty przekazywana jest referencja
dlatego, zmiana elementu tablicy w metodzie zmienia
tablicę „w oryginale”
elementy indywidualne tablicy mogą być też
przekazywane ale w tym przypadku są one tylko
parametrami formalnymi
12
Tablice obiektów
elementami tablicy mogą być
referencje do obiektów
poniższa deklaracja rezerwuje przestrzeń dla 5.
referencji obiektów typu
String
String
[] slowa =
new
String
[5];
to nie tworzy
obiektów
String
początkowo tablica obiektów przechowuje referencje
na
null
każdy z obiektów takiej tablicy musi być ustawiony
oddzielnie
7
13
Tablice obiektów – c.d.
tablica
slowa
po deklaracji:
slowa
-
-
-
-
-
po takiej deklaracji wydrukuje się “null”:
System.out.println (
slowa
[0]);
natomiast,
poniższa referencja spowoduje wyjątek
NullPointerException:
System.out.println(
slowa
[0].toUpperCase());
elementy null
14
Tablice obiektów – c.d.
po kilku ustawieniach obiektów:
poniższa deklaracja tworzy tablicę obiektów i wypełnia ją
referencjami
“styczen”
slowa
-
-
“luty”
“marzec”
String
[]
impreza
= {„nudna", „ciekawa", „glosna"};
8
15
Listy o zmiennej długości
załóżmy, że chcemy napisać metodę, która przetwarza
różną liczbę danych (przy kolejnych wywołaniach)
np. metoda o nazwie
srednia
która zwraca wartość
średnia z wprowadzonych elementów int
// pierwsze wywołanie metody z 3. elementami
mean1 =
srednia
(42, 69, 37);
// inne wywołanie metody z 7. elementami
mean2 =
srednia
(35, 43, 93, 23, 40, 21, 75);
16
public
double
average (
int
...
list
)
{
// whatever
}
Listy o zmiennej długości
za pomocą specjalnej składni możemy przekazać do
metody różną (dowolną) liczbę elementów z tablicy
(listy)
dla każdego wywołania, parametry są automatycznie
wprowadzane do tablicy
typ
elementów
nazwa tablicy
wskazuje zmienną (listę) o możliwie rożnej długości
9
17
Lista o zmiennej długości - przykład
// example of variable length
// parameter list
public
double
srednia (
int
... lista){
double
wynik = 0.0;
if
(lista.length != 0)
{
int
sum = 0;
for
(
int
num : lista)
sum += num;
wynik = (
double
)sum/lista.length;
}
return
wynik ;
}
18
Tablice dwuwymiarowe
deklarowana przez określenie wielkości każdego wymiaru
oddzielnie :
int
[][]
wyniki
=
new
int
[12][50];
odwołanie do elementu tablicy:
value =
wyniki
[3][6];
10
19
Tablice dwuwymiarowe
20
Tablice dwuwymiarowe
11
21
Tablice wielowymiarowe
tablica może mieć wiele wymiarów - jeśli ma więcej niż
jeden wymiar, nazywana jest tablica wielowymiarowa
każdy wymiar ma swoje pole (stałe)
length
ponieważ każdy wymiar jest tablicą odwołań do tablic,
tablice w jednym wymiarze mogą mieć różne długości
czasami nazywane nierównymi tablicami -
ragged arrays
22
Typy generyczne - generics
czasami potrzebujemy różnych typów w programie
(prymitywne, obiekty, tablice obiektów)
ale czasami jeszcze bardzie zaawansowane struktury
danych
Java wspiera takie struktury, nazywane
generics
Collections (kolekcje
– elementy podlegają ściśle określonym
regułom)
Lists (rozszerzenie Collections o nowe metody)
Sets (do przechowywania nie powtarzających się elementów)
Maps (odwzorowania
– przechowywanie pary klucz-wartość)
12
Wejście – wyjście
24
Strumienie - streams
Stream
jednokierunkowy kanał danych
wszystkie zewnętrzne peryferia używają strumieni do komunikacji
drukarki, modemy, klawiatury, CD-ROM, itd.
odczyt danych
Input streams
Typowe metody
read(), readln()
...
zapis danych
Output streams
Typowe metody
write(char c), writeln(String s)
...
Wszystkie niezbędne klasy są w pakiecie
java.io
data
data
13
25
Strumienie znaków
Object
Reader
BufferedReader
InputStreamReader
FileReader
Writer
OutputStreamWriter
PrintWriter
BufferedWriter
FileWriter
………
………
Java ma wiele predefiniowanych strumieni dla zapisu i odczytu znaków.
Najbardziej przydatne są wymienione poniżej.
26
Strumienie binarne
Object
InputStream
FileInputStream
FilterInputStream
BufferedInputStream
FilterOutputStream
FileOutputStream
BufferedOutputStream
DataInputStream
OutputStream
DataOutputStream
PrintStream
... również do zapisu i odczytu
bajtów
14
27
Konsola i klawiatura
możemy użyć konsoli (ekranu) i klawiatury jako strumieni
danych
klawiatura to
InputStream
klasa
System
definiuje pole statyczne
in
public
class System{ static InputStream
in
; ...}
ekran to
PrintStream
klasa
System
definiuje pole statyczne
out
public
class System{ static PrintStream
out
; ...}
28
Wyjście (ekran) w Java
nazywane
“
Text Window
”….
System.out.print( Stuff_to_Print );
System.out.println( Stuff_to_Print );
Stuff_to_Print
może być to coś – nie tylko
String
– te dwie
metody mogą być
przeciążone
-
overloaded
15
29
Wyjście (ekran) w Java
jest też metoda
System.out.printf()
do
formatowania tekstu wyjściowego
Np.
System.out.printf("Pi to %5.2f", Math.PI);
wyświetla:
System.out.printf("Pi to %5.2f, E to %.5f",
Math.PI, Math.E);
wyświetla :
Pi to 3.14
Pi to 3.14, E to 2.71828
30
Wejście w Java
można użyć
InputStream
odnosi się do pola
System.in
ale łatwiej użyć klasy
Scanner
ma wiele funkcjonalnych metod
16
31
Wejście w Java
Klasa
Scanner
musi być importowana:
import
java.util.Scanner;
użycie w programie:
Scanner input =
new
Scanner(System.in);
i dalej:
System.out.print("Please enter a number: ");
double
aNum = input.nextDouble();
Wyjątki
17
33
Wyjątki - exceptions
Errors
– np. dzielenie przez 0
Exceptions
– nieprawidłowe sytuacje
generowane przez metody, które zwykle dają
prawidłowy wynik, ale czasami błędny
program powinien wykryć (przechwycić -
catch
)
wyjątki i je obsłużyć w odpowiedni sposób
34
Wyjątki
aby zdefiniować metodę, która może wygenerować wyjątek, używamy
słowa kluczowego
throws
w sygnaturze metody, np.
Object find(Object[]mySet, Object x)
throws
NotFoundException
{
...
}
Wyjątek mogą zawierać dodatkowe informacje
tekst
...
inne dane
więc wyjątki są
Obiektami
i Java ma odpowiednie klasy do ich obsługi
18
35
Wyjątki w Java
36
Przestępstwo bankowe jako wyjątek
public
class
AlarmException
extends
Exception {
int
kwota;
String zlodziej;
String ofiara;
AlarmException(String zlodziej,String ofiara,
int
kwota){
this
.zlodziej=zlodziej;
this
.ofiara=ofiara;
this
.kwota=kwota;
}
}
zwykle w bankach jest wszystko dobrze
ale czasami ktoś może chcieć ukraść
pieniądze; definiujemy więc wyjątek
AlarmException
Potrzebujemy znać:
złodzieja
ofiarę
kwotę
19
37
Pułapka na złodzieja
void
przelew(Konto odbiorca,
int
kwota)
throws
AlarmException{
if
(kwota >= 0) {
wyplata(kwota);
odbiorca.wplata(kwota);
}
else
throw new
AlarmException(
this
.wlasciciel,
odbiorca.wlasciciel, -kwota);
}
złodzieje będą próbować ukraść pieniądze przez
transfer negatywnej kwoty
aktywacja wyjątku – pułapki może wyglądać tak:
38
Wyjątki – zarządzać lub wyjść
istnieją dwa sposoby traktowania wyjątków
obsługa
wyjątku
w metodzie w której wystąpił
try
{ ... }
catch
(...){ ... }
delegowanie (przesłanie) wyjątku poza metodę
throws
delegowanie jest najprostszym sposobem ale jeśli
kolejna metoda zrobi to samo, to mamy:
run time
error
i wyjście z programu z odpowiednim
komunikatem
20
39
Obsługa wyjątków
public
class
MojeFinanse{
static
String wlasciciel = ”J. Bond”;
static
Konto mojeAktywa =
new
Konto(wlasciciel);
static
Konto akcje =
new
Konto(wlasciciel);
public static
void
sprzedaj(
int
kwota){
try
{
mojeAktywa.przelew(akcje,kwota);
}
catch
(AlarmException k){
System.out.println(
”Zlapany ”
+ k.zlodziej);
System.out.println(
”ukradl ”
+k.kwota+
” ”
+k.ofiara);
}
}
jeśli wszystko OK
jeśli wyjątek
40
Więcej wyjątków
metody mogą zgłaszać więcej wyjątków
delegowanie
myMethod()
throws
AlarmException, IOException{ ... }
obsługa
try
{...normal processing...}
catch
(AlarmException k) {...handler...}
catch
(IOException e){...handler}
...
finally
{...space for...}
opcjonalne wyrażenie
finally
oznacza działanie po obsłudze
wszystkich wyjątków
21
41
Pliki I/O
Pliki
zapewniają wygodny sposób przechowywania i
ponownego zapisywania w pamięci większej ilości
danych
Trzy rodzaje plików:
Text
(znaki)
Binary
(bajty)
Random access
omówienie tylko plików tekstowych, więcej w
Java
documentation
42
Zapis do pliku
Utworzenie
strumienia do zapisu
FileWriter
myLetter =
new
FileWritter(”C:/Examples/Jane.txt”);
taki plik będzie
automatycznie utworzony lub (jeśli już istnieje)
nadpisany (nową zawartością)
Zapis
myLetter.write(”Hello Jane,
\n
need coal
\n
”);
myLetter.write(”Your uncle
\n
Sam”);
Zamknięcie
pliku
myLetter.close();
22
43
Zapis do pliku
import
java.io.*;
public
class
LetterToJane{
static void
piszList(){
try
{ FileWriter myLetter =
new
FileWriter(
”C:\\examples\\Jane.txt”
);
myLetter.write(
”Hello Jane\nneed coal\n”
);
myLetter.write(
”always Yours\nuncle Sam”
);
myLetter.close();
}
catch
(IOException e){ }
}
}
DOS wymaga ”\\”
w nazwie ścieżki
\n – nowa linia
44
Czytanie z pliku
utworzenie
strumienia do czytania z pliku
FileReader aLetter =
new
FileReader(”Jane.txt”);
FileReader reads data as integers by default
czytanie
liczby int
int number;
number = aLetter.read();
while(number != -1){..do something..; number=aLetter.read();}
czytanie char
char ch;
ch = (char)aLetter.read();
zamknięcie
pliku
aLetter.close();
poza wyjątkiem
IOException
należy zwrócić uwagę na:
FileNotFoundException
23
45
Czytanie pliku -
przykałd
import
java.io.*;
public
class
JaneReads{
static
void
readAndEcho(){
try
{
FileReader aLetter =
new
FileReader(
”Jane.txt”
);
int
c = aLetter.read();
while
(c != -1){
System.out.print((
char
)c);
c = aLetter.read();
}
aLetter.close();
}
catch
(FileNotFoundException f){}
catch
(IOException e){}
}
}
Hello Jane
need coal
always Yours
uncle Sam
46
Buforowane wejście i wyjście
czytanie i zapis znak po znaku jest bardzo nieefektywne
w praktyce, RAM, dyski wymieniają dane blokami
dane są
buforowane
w głównej pamięci komputera
data
data
24
47
Buforowane wejście i wyjście
kiedy używamy bufora możemy czytać:
FileReader aData = FileRedaer(
”Jane.txt”
);
BufferedReader aLetter = new BufferedReader(aData);
lub w jednym kroku:
BufferedReader aLetter =
new BufferedReader(new FileReader(
”Jane.txt”
));
podobnie zapis przez bufor:
new
BufferedWriter(
new
FileWriter(
”Jane.txt”
)
48
import
java.io.*;
public
class
LetterToJane{
static void
piszList(){
try
{ BufferedWriter myLetter =
new
BufferedWriter(
new
FileWriter(
”Jane.txt”
));
myLetter.write(
”Hello Jane\nhow are You\n”
);
myLetter.write(
”always Yours\nuncle Sam”
);
myLetter.close();
}
catch
(FileNotFoundException f){}
catch
(IOException e){ }
}
}
Zapis przez bufor
FileWriter
zapisuje do
BufferedWriter
25
49
... i odczyt
import
java.io.*;
public
class
JaneReads{
static
void
readAndEcho(){
try
{
BuffereReader aLetter =
new
BufferedReader(
new
FileReader(
”Jane.txt”
));
String line = aLetter.readLine();
while
(line != null){
System.out.println(line);
line = aLetter.readLine();
}
aLetter.close();
}
catch
(FileNotFoundException f){}
catch
(IOException e){}
}
}
Hello Jane
How are You
always Yours
uncle Sam
FileReader
zapisuje do
BufferedReader
czytanie linia po linii
FileNotFoundException jest
podklasą dla IOException