Upload
filomena-mauro
View
219
Download
4
Embed Size (px)
Citation preview
Tipi di dato Fondamentali
Tipi numerici
• int: interi, senza parte frazionaria
• double: numeri in virgola mobile (precisione doppia)
1, -4, 0
0.5, -3.11111, 4.3E24, 1E-14
Tipi numerici
• Una computazione su tipi numerici può causare overflow.
• Java: 8 tipi primitivi, che includono quattro tipi interi e due in virgola mobile
int n = 1000000;System.out.println(n * n); // stampa -727379968
Tipi primitivi
Tipo Range di valori Dimensioneint –2,147,483,648 . . . 2,147,483,647 4 bytes
byte –128 . . . 127 1 byte
short –32768 . . . 32767 2 bytes
long 9,223,372,036,854,775,808 . . .
–9,223,372,036,854,775,807 8 bytes
Continua…
Tipi primitivi
Tipo Descrizione dei valori Dimdouble Virgola mobile, precisione doppia. Range ±10308
e 15 cifre decimali 8 bytes
float Virgola mobile, precisione singola. Range ±1038 e 7 cifre decimali
4 bytes
char Caratteri nel sistema Unicode 2 bytes
boolean false e true 1 byte
Float e double
• Attenzione agli errori derivanti dagli arrotondamenti
• Non è ammesso assegnare un double (o float) ad un intero … non è C !
double f = 4.35;System.out.println(100 * f); // stampa 434.99999999999994
double d = 13.75; int i = d; // Errore
Continua…
Float e double
• Cast: per convertire un double ad un int è quindi necessario un cast
• Cast equivale a troncamento.
• Math.round arrotondamento static long round(double a) static int round(float a)
int i = (int) d; // OK
Domande
• In quale caso il cast (long) x dà un risultato diverso da Math.round(x)?
• Quale istruzione utilizzereste per arrotondare x:double al valore int più vicino?
Risposte
• Quando la parte frazionaria di x è ≥ 0.5
• (int) Math.round(x) se assumiano che x è minore di 2 · 109
Stringhe
• Le stringhe sono oggetti
• Stringhe costanti
• Variabili di tipo stringa
• Lunghezza di una stringa
• La stringa vuota:
"Hello, World!"
String message = "Hello, World!";
int n = message.length();
""
Concatenazione
• Utilizziamo l’operatore +:
• Se uno degli argomenti dell’operatore è una stringa, l’altro argomento viene automaticamente convertito
String name = "Dave";String message = "Hello, " + name; // = "Hello, Dave"
String a = "Agente";int n = 7;String bond = a + “00” + n; // bond = “Agente007”
Concatenazione in output
• Utile per ridurre il numero di istruzioni System.out.print:
è equivalente a
System.out.print("The total is ");System.out.println(total);
System.out.println("The total is " + total);
Conversioni
• Da stringhe a numeri:
• Da numeri a stringhe
int n = Integer.parseInt(str);double x = Double.parseDouble(x);
String str = "" + n;str = Integer.toString(n);
Confronti
• s1 == s2 true se e solo se s1 e s2 sono riferimenti alla stessa stringa
(come per tutti i tipi reference)
• s1.equals(s2) true se e solo se s1 e s2 sono stringhe uguali (case sensitive)
• s1.equalsIgnoreCase(s2) come sopra ma case insensitive
• s1.compareTo(s2) < 0 se s1 precede s2 in ordine lessicografico = 0 se s1 e s2 sono uguali > 0 se s1 segue s2 in ordine lessicografico
Continua…
Confronti
• Attenzione
• Le chiamate a new creano sempre oggetti diversi, l’uso di costanti invece è ottimizzato
“str” == “str”
new String(“str”) == new String(“str”)
“str” == new String(“str”)
true
false
false
Stringhe e array di caratteri
• Le stringhe non sono array di caratteri
• Esistono conversioni String char[]
char[] String
char data[] = {‘s’, ‘t’, ‘r’ } String s = new String(data)
String s = “str” Char data[] = s.toCharArray()
Sottostringhe
•
• s.substring(i, j) restituisce la sottostringa di s dalla posizione i alla j-1 (estremi inclusi)
• s.substring(i) restituisce la sottostringa di s da i (incluso) al termine di s
• s.indexOf(s1) restituisce l’indice della prima occorrenza di s1 in s; -1 se non ci sono occorrenze
• s.indexOf(s1,i) l’indice della prima occorrenza di s1 in s da i (incluso); -1 se non ci sono occorrenze
Continua…
String greeting = "Hello, World!";String sub = greeting.substring(0, 5); // sub = "Hello"
Lettura da input• System.in (lo standard input) offre supporto
minimo per la lettura read(): lettura di una byte
• La classe Scanner di Java 5.0 permette di leggere da input in modo più strutturato
Scanner in = new Scanner(System.in);System.out.print("Enter quantity: ");int quantity = in.nextInt();
Continua…
Lettura da input
Metodi utili della classe Scanner
• nextDouble() legge un double
• nextLine() legge un linea la sequenza fino al primo newline
• nextWord() legge una parola la sequenza fino al primo spazio/tab/newline
File stringTester.javaimport java.util.Scanner;class stringTester { /** Legge da input linee di testo ed estrae i campi delimitati da ':' e ne estrae */ public static void main(String[] args) {
Scanner in = new Scanner(System.in);String record, field;char delim = ':'; // il delimitatore int record_count = 1;while (in.hasNextLine()) { System.out.println("Record " + record_count++); record = in.nextLine(); int begin, end, i; begin = 0; for (i=0; (end = record.indexOf(delim,begin)) >= 0; i++) {
// end = indice della prossima occorrenza del delimiterfield = record.substring(begin,end);begin = end + 1; // salta il delimitatore System.out.println("\tField" + i + ": " + field);
} field = record.substring(begin); // l'ultimo campo System.out.println("\tField" + i + ": " + field); }
}}
:
File stringTester.java
Gianni:Rossi:via Verdi 123:Milano:ItaliaMichele:Bugliesi:via Torino 155:Mestre:Italia:30173
Input
Record 1 Field 1: Gianni Field 2: Rossi Field 3: via Verdi 123 Field 4: Milano Field 5: Italia Record 2 ...
Output
Input da un Dialog Box
Input da un Dialog Box
•
• Converti le stringhe in numeri se necessario:
• La conversione lancia una eccezione se l’utente non fornisce un numero
• Aggiungete System.exit(0) al metodo main di qualunque programma che usi JOptionPane
String input = JOptionPane.showInputDialog(prompt)
int count = Integer.parseInt(input);
Domande
15. Perché non possiamo leggere input direttamente da System.in?
16. Supponiamo s sia un oggetto di tipo Scanner che estrae dati da System.in, e consideriamo la chiamata String name = s.next();Quale è il valore della variabile name se l’utente dà in input Hasan M. Jamil?
Risposte
15. Possiamo, ma il tipo di System.in permette solo letture molto primitive (un byte alla volta)..
16. Il valore è “Hasan".
Arrays Array Lists
Arrays
• Array: una sequenza di valori dello stesso tipo
double[] data = new double[10];
Continua…
Arrays
• Al momento della allocazione, tutti i valori sono inizializzati ai valori di default del tipo base numeri: 0 booleani: false riferimenti: null
Arrays
• Accesso agli elementi mediante l’operatore [ ]
• Lunghezza dell’array: data.length (N.B. non è un metodo)
• Indici compresi tra 0 e data.length - 1
data[2] = 29.95;
data[10] = 29.95;// ERRORE: ArrayIndexOutOfBoundException
Domanda
• Quali elementi contiene l’array al termine della seguente inizializzazione?
double[] data = new double[10];for (int i = 0; i < data.length; i++) data[i] = i * i;
Risposta
• 0 1 4 9 16 25 36 49 64 81 ma non 100
Domanda
• Cosa stampano i seguenti comandi. Ovvero, se causano un errore, quale errore causano? Specificate se si tratta di un errore di compilazione o di un errore run-time.
1. double[] a = new double[10]; System.out.println(a[0]);
2. double[] b = new double[10]; System.out.println(b[10]);
3. double[] c; System.out.println(c[0]);
Risposta
• 2. 0
3. errore run-time error: indice fuori range
4. Errore compile-time: c non è inizializzato
Array bidimensionali
• All’atto della costruzione specifichiamo il numero di righe e di colonne:
• Per accedere un elemento, utilizziamo i due indici: a[i][j]
final int ROWS = 3;final int COLUMNS = 3;(String[])[] board = new String[ROWS][COLUMNS];
board[i][j] = "x";
Copia di array
• Gli array sono oggetti, quindi l’assegnamento tra array è un assegnamento di riferimenti
double[] data = new double[10];// fill array . . .double[] prices = data;
Continua…
Copia di array
Copia di array – copia di elementi
Continua…
System.arraycopy(from, fromStart, to, toStart, count);
• Volendo duplicare gli elementi, il linguaggio fornisce metodi efficienti:
Copia di array – copia di elementi
Copia di elementi
• Array sorgente e destinazione possono coincidere
System.arraycopy(data, i, data, i+1, data.length-i-1);data[i] = x;
ArrayLists
• La classe ArrayList gestisce una sequenza di oggetti
• A differenza degli array può variare in dimensione
• Fornisce metodi corrispondenti a molte operazioni comuni inserzione, accesso e rimozione di elementi, …
Continua…
Array Lists
• La classe ArrayList è una classe parametrica (generica)
• ArrayList<T> contiene oggetti di tipo T:
• size():il metodo che calcola il numero di elementi nella struttura
ArrayList<BankAccount> accounts = new ArrayList<BankAccount>();accounts.add(new BankAccount(1001));accounts.add(new BankAccount(1015));accounts.add(new BankAccount(1022));
Accesso agli elementi
• get()
• Come per gli array gli indici iniziano da 0 errore se l’indice è fuori range posizioni accessibili: 0 .. size() – 1.
BankAccount anAccount = accounts.get(2); // il terzo elemento dalla arraylist
Continua…
Nuovi elementi
• set() sovrascrive un valore esistente
• add() aggiunge un nuovo valore, alla posizione i
• Oppure all’ultima posizione
Continua…
BankAccount anAccount = new BankAccount(1729);accounts.set(2, anAccount);
accounts.add(i, a)
accounts.add(a)
Nuovi elementi – add
accounts.add(i, a)
Rimozione di elementi
• remove() rimuove l’elemento all’indice i
accounts.remove(i)
Rimozione di elementi
Errori tipici
• Accesso fuori dai bounds indici legali 0..size()-1
int i = accounts.size();accounts.get(i); // errore!accounts.set(i,anAccount); // errore!accounts.add(i+1,anAccount); // errore!
Domanda
3. Quale è il contenuto della struttura names dopo le seguenti istruzioni?
ArrayList<String> names = new ArrayList<String>();names.add("A");names.add(0, "B");names.add("C");names.remove(1);
Risposta
3. contiene le stringhe "B" e "C" alle posizioni 0 e 1
Wrappers
• A differenza degli array, le arraylists possono solo contenere elementi di tipo reference
• È necessario quindi utilizzare le cosiddette classi “wrapper” che permettono di convertire valori primitivi in corrispondenti valori di tipo riferimento:
Continua…
ArrayList<Double> data = new ArrayList<Double>();data.add(new Double(29.95));double x = data.get(0).doubleValue();
Wrappers
Wrappers
• Ci sono classi wrapper per ciascuno degli otto tipi primitivi
Auto-boxing
• Da Java 5.0, la conversione tra tipi primitivi e i corrispondenti tipi wrapper è automatica.
Double d = 29.95; // auto-boxing; equivale a // Double d = new Double(29.95);
double x = d; // auto-unboxing; equivale a // double x = d.doubleValue();
Continua…
Auto-boxing
• Auto-boxing opera anche all’interno delle espressioni aritmetiche
Valutazione: auto-unbox d in un double aggiungi 1 auto-box il risultato in un nuovo Double Memorizza il riferimento nel wapper e
Double e = d + 1;
Auto-boxing
Attenzione!
• == è definito diversamente sui tipi primitivi e sul loro corrispettivo boxed
• == su interi significa uguaglianza di valori su integer significa identità di riferimenti
• Evitiamo l’uso di == sulle classi wrapper
Domanda
• Supponiamo che data sia un ArrayList<Double> di dimensione > 0. Come facciamo ad incrementare l’elemento all’indice 0?
Risposta
• data.set(0, data.get(0) + 1);
Array e for loops
• La soluzione tradizionale
double[] data = . . .;double sum = 0;for (int i = 0; i < data.length; i++){ double e = data[i]; sum = sum + e;}
“for each”: un for generalizzato
• Itera su tutti gli elementi di una collezione ad esempio sugli elementi di una array
Continua…
double[] data = . . .;double sum = 0;for (double e : data) // “per ciascun e in data"{ sum = sum + e;}
“for each”
• Si applica nello stesso modo alle ArrayLists:
ArrayList<BankAccount> accounts = . . . ;ArrayList<BankAccount> accounts = . . . ;double sum = 0;double sum = 0;for (BankAccount a : accounts)for (BankAccount a : accounts){{ sum = sum + a.saldo(); sum = sum + a.saldo();} }
“for each”
• Equivalente al seguente loop tradizionale:
double sum = 0;for (int i = 0; i < accounts.size(); i++){ sum = sum + accounts.get(i).saldo();}
Sintassi
for (Type variable : collection) statement
• Esegue il corpo del ciclo su ciascun elemento della collezione
• La variabile è assegnata ad ogni ciclo all’elemento successivo
“for each” – limitazioni
• La sintassi è deliberatamente semplice
• Si applica solo ai casi più semplici di gestione di collezioni.
• Spesso è necessario utilzzare la sintassi tradizionale
Continua…
“for each” – limitazioni
• Non utilizzabile per scorrere due strutture all’interno dello stesso loop
public static double dotProduct(double[] u, double[] v){ // assumiamo u.length == v.length;
double sum = 0,
for (x:u, y:v) sum = sum + x*y,
}
Continua…
public static double dotProduct(double[] u, double[] v){ // assumiamo u.length == v.length;
double sum = 0,
for (int i=0; i<u.length; i++) sum = sum + u[i]*v[i];
return sum;}
“for each” – limitazioni
• Non sempre utilizzabile per inizializzazioni
public static double dotProduct(double[] data) {
int i = 0;
for (x:data) { x = i*i; i++; }
}
Continua…
public static double dotProduct(double[] data) {
for (int i = 0; i<data.length; i++)
data[i] = i*i;
}
“for each” – limitazioni
• Iterazione su array bidimensionali
• tipicamente utilizziamo due cicli innestati: anche qui, il “foreach” non aiuta
for (int i = 0; i < ROWS; i++) for (int j = 0; j < COLUMNS; j++) board[i][j] = " ";
Esercizio
• Definiamo una classe per rappresentare un polinomio a coefficienti reali
Continua…
c0 + c1x + c2x2 + … cnxn
Esempio
• Definiamo una classe per rappresentare una tabella bidimensionale dinamica, formata da un numero fisso di righe ed un numero variabile di colonne
Continua…
Array e varargs
• Gli array possono essere utilizzati per passare liste di parametri di dimensione variabile
class Lists { public static <T> ArrayList<T> toList (T[] arr) { ArrayList<T> list = new ArrayList<T>(); for (T el : arr) list.add(el); return list; }}
Continua…
Lists.toList (new String[] {“hello”, “world!”} );Lists.toList(new Integer[] {1,2,3,4} );
Metodo parametrico
Array e varargs
• Da java 5.0 lo stesso effetto si ottiene utilizzando la sintassi vararg
• vararg è una sintassi più sintetica per specificare argomenti, nel caso in cui l’ultimo argomento di in metodo sia un array
Array e varargs
• Passare argomenti diventa più agevole
Lists.toList(“hello”, “world!”);Lists.toList(1,2,3,4);
class Lists { public static <T> ArrayList<T> toList(T... arr) { ArrayList<T> list = new ArrayList<T>(); for (T el : arr) list.add(el); return list; }}
Gioco del 15
Continua…
Gioco del 15
Due classi
• PuzzlePiece – i pezzi del puzzle
• PuzzleBoard – la tabella
PuzzlePiece – i pezzi del puzzle
class PuzzlePiece { public PuzzlePiece(int value) { face_value = value; }
public int valueOf() { return face_value; }
// il valore scritto su ciascun riquadro private int face_value; }
PuzzleBoard – Interfaccia class PuzzleBoard { /** * Costruisci una tabella con i pezzi in ordine decrescente. * La tabella ha sempre una posizione vuota. * @param s è la dimensione della tabella */ public PuzzleBoard(int s) { . . . }
/** * muovi il pezzo che ha il numero w se è in posizione * adiacente alla posizione vuota * @param w è il numero associato al pezzo da muovere * @return true sse il pezzo ha una mossa disponibile * nel qual caso effettua la mossa */ public boolean move(int w) { . . . }
/** * Decidi se la configurazione è vincente */ public boolean win() { . . . }}
PuzzleBoard – Rappresentazione
class PuzzleBoard { // dimensione della matrice private int size; // la matrice che tiene i riquadri PuzzlePiece[][] contents;
// una posizione sulla matrice deve essere vuota // invariante: contents[empty_row][empty_col] == null private int empty_row; private int empty_col;
PuzzleBoard – Costruttore /** * Costruisci una tabella iniziale con i pezzi in * ordine decrescente * @param s = lato della tabella */ public PuzzleBoard(int s) {
size = s;contents = new PuzzlePiece[size][size];// crea ogni pezzo e disponilo sulla matrice for ( int num = 1; num < size * size; num++ ) { PuzzlePiece p = new PuzzlePiece(num); int row = num / size; int col = num % size; // disponi in ordine discendente contents[size - 1 - row][size - 1 - col] = p;
}// tieni traccia della posizione vuotaempty_row = size - 1;empty_col = size - 1;
}
Domanda
• Quale è la configurazione iniziale della tabella?
Risposta
• Questa
PuzzleBoard
/** * muovi il pezzo che ha il numero w se è in posizione * adiacente alla posizione vuota * @param w è il numero associato al pezzo da muovere * @return true sse il pezzo ha una mossa disponibile * nel qual caso effettua la mossa */ public boolean move(int w) {
final int NOT_FOUND = -1;// cerca w nelle posizioni adiacenti alla posizione vuota// row and col saranno settati alla posizione di wint row = NOT_FOUND; int col = NOT_FOUND;if ( found(w, empty_row - 1, empty_col) ) { row = empty_row - 1; col = empty_col;}else if ( found(w, empty_row + 1, empty_col) ) { row = empty_row + 1; col = empty_col;}
• Metodi dell’interfaccia – move
PuzzleBoard
else if ( found(w, empty_row, empty_col - 1) ) { row = empty_row; col = empty_col - 1;}else if ( found(w, empty_row, empty_col + 1) ) { row = empty_row; col = empty_col + 1;}if ( row != NOT_FOUND ) { // muovi il pezzo nel riquadro vuoto contents[empty_row][empty_col] = contents[row][col]; // ricalcola la posizione vuota (quella che era di w) empty_row = row; empty_col = col; contents[empty_row][empty_col] = null; }return row != NOT_FOUND;
}
• Metodi dell’interfaccia – move
PuzzleBoard
/** * Decidi se la configurazione è vincente * @return true sse la configurazione corrente è vincente */ public boolean win() {
int curr = valOf(0,0); for (int i = 0; i < size; i++) for (int j = 0; j < size ; j++) {
if (curr <= valOf(i,j)) curr = valOf(i,j); else return false;
}return true;
}
• Metodi dell’interfaccia – win
PuzzleBoard
/** * decide se il pezzo v è in posizione (row, col) */ private boolean found(int v, int row, int col) {
boolean answer = false;if ( row >= 0 && row < size && col >= 0 && col < size ) { answer = ( contents[row][col].valueOf() == v ); }return answer;
}
• Metodi ausiliari (privati)
Continua…
PuzzleBoard
/** * Calcola il valore della posizione (i,j) * @param i riga * @param j colonna * @return il valore nella posizione (i,j) se non è vuota * altrimenti restituisci size * size */ private int valOf(int i, int j) {
if (contents[i][j] != null) return (contents[i][j]).valueOf();else return size * size;
}
• Metodi ausiliari (privati)