Linguaggi di Programmazione: Paradigmi di Programmazione Array

Linguaggi di
Programmazione: Paradigmi
di Programmazione
Strutture Dati:
Array & Co.
Matteo Baldoni
Dipartimento di Informatica - Universita` degli Studi di Torino
C.so Svizzera, 185 - I-10149 Torino (Italy)
e-mail: [email protected] - URL: http://www.di.unito.it/~baldoni
Array
• Gli array sono oggetti veri e propri (e quindi vanno
prima creati esplicitamente dal programmatore per
essere utilizzati)
• Hanno una dimensione fissa (dopo la creazione)
• Esistono solo unidimensionali (ma e` possibile
definire array di array)
• Il primo elemento ha indice “0”
• La creazione avviene mediante l’operatore new
Strutture Dati
2
1
Array
• Es.: la dichiarazione di un array che puo`
contenere 100 numeri interi
• Gli elementi saranno indicizzati da 0 a 99
• Controllo a run time sul valore dell’indice
tipo di un
elemento
dell’array
int[] arrayOfInt = new int[100];
tipo array
nome dell’array
operatore che
permette di
creare un oggetto
numero di
elementi
dell’array
arrayOfInt[5]
indice
Strutture Dati
3
Array
• Il nome dell’array e` un puntatore ad una struttura
contenente i vari elementi
• ma differenza del C/C++ il nome dell’array non
indica anche il primo elemento dell’array stesso
(non esiste un’aritmetica dei puntatori)
• In Java non esistono analoghi di & e * del C/C++
int array_interi[];
int *array_interi;
in C/C++ sono equivalenti
array_interi[2]
*(array_interi + 2)
in C/C++ sono equivalenti
Strutture Dati
4
2
Array
• Se assegno un array ad un altro non copio gli
elementi che esso contiene ma semplicemente il
valore del puntatore, i due array condivideranno la
stessa struttura (esiste pero` arraycopy nella
classe System)
• length (campo read-only) restituisce la lunghezza
di un array
arrayOfInt
int[] arrayOfInt = new int[6];
[…]
int[] altroArrayOfInt;
[…]
altroArrayOfInt
altroArrayOfInt = arrayOfInt;
[…]
System.out.println(arrayOfInt.length);
stampa 6
5
Strutture Dati
Inizializzazione di array
• Mediante un loop (tipicamente un ciclo for)
• oppure durante la definizione stessa
• array anonimi come parametri attuali
int[] arrayOfInt = new int[100];
for (int i=0; i<100; i++)
arrayOfInt[i] = i;
int[] arrayOfInt = {1, 2, 4, 10};
new int[] {1, 2, 4, 10}
[…]
a.metodo(new int[] {1, 2, 4, 10});
[…]
Strutture Dati
utile per array con
pochi elementi
utile per essere passato
come parametro attuale
di un metodo senza dover
creare solo per questo una
variabile
6
3
Array multidimensionali
• Ossia array di array (ma non matrici!)
• Ossia un elemento di un array puo` essere a sua
volta un array
int[][] arrayOfArrayOfInt = new int[10][5];
quadrato di
elementi 10 x 5
int[][] arrayOfArrayOfInt = new int[10][];
for (int i=0; i<10; i++)
arrayOfArrayOfInt[i] = new int[5];
int[][] arrayOfArrayOfInt = new int[10][];
for (int i=0; i<10; i++)
arrayOfArrayOfInt[i] = new int[i];
triangolo di elementi
7
Strutture Dati
Array
• Gli array sono oggetti di “prima classe”
• Gli array sono built-in nel linguaggio
• L’operatore [] e`un costruttore di tipo!
Definisce il tipo Counter
public class Counter {
private int c;
[…]
}
Counter[] arrayOfCounters = new Counter[10];
Definisce il tipo array di Counter
Strutture Dati
8
4
Array
class ProvaArray {
public static void
main(String[] args) {
ClasseUno[] arrayClasseUno;
ClasseDue[] arrayClasseDue;
ClasseTre[] arrayClasseTre;
ClasseDue[] arrayClasseDueBis;
arrayClasseDue = new ClasseDue[]
{new ClasseDue(2,3),
new ClasseDue(3,4)};
arrayClasseUno = arrayClasseDue;
arrayClasseDueBis =
(ClasseDue[]) arrayClasseUno;
arrayClasseTre = new ClasseTre[]
{new ClasseTre("ab"),
new ClasseTre("cd")};
arrayClasseUno = arrayClasseTre;
...
}
Upcast di tutti gli elementi
Errore!
Downcast di tutti gli elementi
Strutture Dati
9
Array
class ProvaArray {
public static void
main(String[] args) {
ClasseUno[] arrayClasseUno;
ClasseDue[] arrayClasseDue;
...
arrayClasseDue
= new ClasseDue[]
{new ClasseDue(2,3),
new ClasseDue(3,4)};
...
arrayClasseUno = arrayClasseDue;
...
arrayClasseUno[0]
=
new
ClasseUno(2);
}
Errore a run-time!!
A tempo di compilazione è corretto
assegnare ad un campo dell’array di tipo ClasseUno un elemento di tipo
ClasseUno ma a run-time questo contiene un elemento di tipo ClasseDue,
piu` specifico di ClasseUno, e quindi viene sollevata un’eccezione di tipo
ArrayStoreException
Strutture Dati
10
5
La classe java.util.Arrays
• Mette a disposizione una serie di metodi statici di
utilita` per trattare con array:
– equals
Fa uso di equals e non di ==
– fill
Fa uso di compareTo
– sort
dell’interfaccia Comparable per
parametrizzare l’algoritmo di
– binarySearch
ordinamento rispetto gli elementi
Permette di usare anche oggetti
di tipo Comparator (interfaccia) per
parametrizzare rispetto al confronto
• I metodi sono overloaded per ogni tipo primitivo e
per Object.
11
Strutture Dati
Strutture dati: Interfacce
• Collection: un arbitraio
gruppo di oggetti
• List: un gruppo di oggetti
memorizzati in una data
sequenza
• Set: un gruppo di oggetti
senza duplicati
• Map: un gruppo di coppie
(oggetti) chiave-valore
Strutture Dati
Sono tutte interfacce!
12
6
Strutture dati:
Implementazioni
• Ogni interfaccia ha piu` implementazioni che possono essere
scelte in modo indifferente a seconda delle esigenze (anche
di efficienza)
Strutture Dati
13
Strutture dati
• Tassonomia
completa delle
strutture dati
disponibili nel
package java.util
• Si noti Vector
ancora consentito
sebbene gli venga
ora preferito
ArrayList
Strutture Dati
14
7
Strutture dati
• Gli oggetti che possono essere contenuti in una
qualsiasi struttura dati sono di tipo Object, quindi
un oggetto qualsiasi
• Un oggetto di tipo, ad esempio, ArrayList puo`
contenere oggetti di tipo diverso, anche non
omogenei (perche` comunque di tipo Object)
• Viene persa l’informazione sul tipo di un oggetto
quando è inserito in una struttura dati di questo
genere (è come fare upcasting ad Object!)
• Estratti gli oggetti è necessario fare downcasting
per poterli riutilizzare correttamente (invocare
metodi della loro classe di appartenenza), in
contrapposizione agli array
Strutture Dati
15
Un esempio
• Tratto da: B. Eckel, Thinking in Java, Prentice Hall, 2000.
Cap. 9, pag. 450 e seguenti.
public class Cat {
private int catNumber;
Cat(int i) { catNumber = i; }
void print() {
System.out.println("Cat #" + catNumber);
}
}
public class Dog {
private int dogNumber;
Dog(int i) { dogNumber = i; }
void print() {
System.out.println("Dog #" + dogNumber);
}
}
Strutture Dati
16
8
Un esempio
ArrayList non ha nessun
riferimento a cosa conterra`
in seguito!
public class CatsAndDogs {
public static void main(String[] args) {
ArrayList cats = new ArrayList();
for(int i = 0; i < 7; i++)
cats.add(new Cat(i));
Posso benissimo
cats.add(new Dog(7));
aggiungere un
for(int i = 0; i < cats.size(); i++)
oggetto di tipo
((Cat)cats.get(i)).print();
Dog in cats!
}
Senza downcast non potrei invocarlo
}
import java.util.*;
Durante la compilazione non viene rilevato nessun errore ma
durante l’esecuzione (run-time) verra` sollevata un’eccezione
(ClassCastException) poiche` verra` trovato un elemento non
di tipo Cat (il downcast non è un cast alla C ma sono una
verifica che l’oggetto sia effettivamente di un certo tipo)
17
Strutture Dati
Un esempio
public class Cat1 {
private int catNumber;
Cat(int i) { catNumber = i; }
public String toString() {
return "Cat #" + catNumber;
}
}
A differenza di prima
abbiamo un metodo
toString() per stampare
public class Dog1 {
private int dogNumber;
Dog(int i) { dogNumber = i; }
public String toString() {
return "Dog #" + dogNumber;
}
}
Strutture Dati
18
9
Un esempio
import java.util.*;
public class CatsAndDogs {
public static void main(String[] args) {
Posso aggiungere
ArrayList cats = new ArrayList();
un oggetto di tipo Dog
for(int i = 0; i < 7; i++)
cats.add(new Cat1(i));
Viene invocato
cats.add(new Dog1(7));
implicitamente non è
for(int i = 0; i < cats.size(); i++)
necessario scriverlo
//((Cat)cats.get(i)).print();
System.out.println(cats.get(i).toString());
}
Durante la compilazione nessun errore poiche`
}
String toString() è un metodo disponibile in Object
Non viene sollevata nessuna eccezione durante l’esecuzione!!
Tutto funziona perfettamente. Questo perche` abbiamo fatto
overriding di un metodo appartenente alla classe Object e
quindi sopraclasse sia di Cat1 che di Dog1. Il binding
dinamico associera` il corretto codice durante l’esecuzione
Strutture Dati
19
Iteratori
• È un oggetto che permette di attraversare
agevolmente una struttura dati qualsiasi
(indipendentemente dalla sua implementazione)
• nest(), hasNext(), remove()
import java.util.*;
public class CatsAndDogs2 {
public static void main(String[] args) {
Collection cats = new ArrayList();
for(int i = 0; i < 7; i++)
cats.add(new Cat(i));
Iterator e = cats.iterator();
while(e.hasNext())
((Cat)e.next()).print();
}
}
Strutture Dati
20
10