Tipi di dato Fondamentali. Tipi numerici int: interi, senza parte frazionaria double: numeri in...

Post on 01-May-2015

217 views 4 download

transcript

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)