Le Collezioni (Java Collections)

Le Collezioni (Java Collections)
Le Collezioni (Java Collections)
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Liste e insiemi
Lista (sequenza)
Insieme
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Il framework Collection
Le collection di Java rappresentano n’architettura nificata
preposta all’uso e al trattamento di gruppi di oggetti.
Consistono di:
Interfacce: tipi di dati astratti che rappresentano collezioni,
come List, Queue, Set e Map
Implementazioni astratte: parziali implemetazioni di
interfacce facilmente riadattabili
Implementazioni concrete: classi basilari che
implementano le interfacce fondamentali
Algoritmi: implementazioni di funzioni basilari come
ordinamento e ricerca, applicabili a tutte le collezioni
Utilità: funzioni basilari applicate ad array di primitivi e
riferimento
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
La gerarchia delle interfacce
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
L’interfaccia Collection
public interface Collection<E> extends Iterable<E> {
//
Opera i
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(E element);
//
boolean remove(Object element); / /
Iterator iterator();
//
Optional
Optional
Opera
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear(); / / O p t i o n a l
//
Opera
Object[] toArray();
<T> T[] toArray(T[] a);
}
//
Optional
//
Optional
//
Optional
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Contratto del metodo add(E o) - opzionale
... Returns true if this collection changed as a result of
the call. (Returns false if this collection does not permit
duplicates and already contains the specified element.)
... limitations on what elements may be added to this
collection. In particular, some collections will refuse to add
null elements, and others will impose restrictions on the
type of elements that may be added. Collection classes
should clearly specify in their documentation any
restrictions on what elements may be added.
If a collection refuses to add a particular element for any
reason other than that it already contains the element, it
must throw an exception (rather than returning false)...
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Le interfacce di Collection
Collection è la radice della gerarchia delle collection.
Rappresenta gruppi di oggetti (elementi) che
possono essere duplicati oppure no. Alcune
possono essere ordinate altre no. Esistono
implementazioni concrete di sottointerfacce quali
List e Set
List cattura il concetto di lista ordinata (o sequenza):
gruppo di elementi posti in un qualche ordine.
Implementazioni: ArrayList, LinkedList e
Vector
Set cattura il concetto di insieme: gruppo di elementi
che non contiene duplicati (non contiene e1 e e2
se e1.equals(e2) . Implementazioni: HashSet
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Gerarchia (parziale) di Collection (List e Set)
Collection
List
ArrayList
LinkedList
Set
HashSet
!
List!
public void add(int index, E element)!
Inserts!the!specified!element!at!the!specified!posi2on!in!this!list!(op2onal!opera2on).!!
Shi7s!the!element!currently!at!that!posi2on!(if!any)!and!any!subsequent!elements!to!the!
right!(adds!one!to!their!indices).!
public E get(int index)!
Returns!the!element!at!the!specified!posi2on!in!this!list.!
public int indexOf(Object o) [lastIndexOf(Object o)]!
Returns!the!index!of!the!first![last]!occurrence!of!the!specified!element!in!this!list,!or!C1!if!
this!list!does!not!contain!the!element.!
public E remove(int index)!
Removes!the!element!at!the!specified!posi2on!in!this!list!(op2onal!opera2on).!!Shi7s!any!
subsequent!elements!to!the!le7!(subtracts!one!from!their!indices).!!Returns!the!element!
that!was!removed!from!the!list.!
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Esempio
class Gatto {
//
costruttore
public Gatto(int i)
//
restituisce
l’ identificativo
unico
public int getID()
}
public class Cane {
//
costruttore
public Cane(int i)
//
restituisce
l’ identificativo
public int getID()
}
unico
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Le Collezioni (Java Collections)
Esempio: uso di non-generici
import java.util.*;
public class CaniEGatti {
public static void main(String[] args) {
/*
definizione
tipica :
riferimento
piu ’
uso
del
astratto
*/
List gatti = new ArrayList();
for(int i = 0; i < 7; i++)
gatti.add(new Gatto(i));
/*
nessun
oggetti
problema
di
tipo
ad
aggiungere
diverso
for (int i = 0; i < 3; i++)
gatti.add(new Cane(i));
}
}
*/
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Svantaggi
Uno svantaggio tipico è la perdita di informazione sul tipo
quando si inseriscono oggetti nel contenitore. Infatti:
poiché non vi sono restrizioni sul tipo di oggetti inseribili
nel contenitore, è possibile inserire senza problemi cani in
una collezione di gatti (fonte di potenziali errori)
a causa della perdita del tipo, occorre eseguire una
forzatura (cast) “corretta”, a run time, all’atto
dell’estrazione dell’oggetto per non incorrere in
un’eccezione
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Le Collezioni (Java Collections)
Esempio
import java.util.*;
public class CaniEGatti {
public static void main(String[] args) {
List gatti = new ArrayList();
for(int i = 0; i < 7; i++)
gatti.add(new Gatto(i));
gatti.add(new Cane(7));
/*
Eccezione
rilevata
a
run
time
*/
for(int i = 0; i < gatti.size(); i++)
((Gatto)gatti.get(i)).id();
}
}
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Parametrizzare la lista
Per ovviare ai problemi precedenti è lecito definire una nuova
classe lista parametrizzat
List<Gatto> gatti = new ArrayList<Gatto>();
List<Cane> cani = new ArrayList<Cane>();
for (int i = 0; i < 7; i++)
gatti.add(new Gatto(i));
//
aggiungi
for (int i = 0; i < 3; i++)
cani.add(new Cane(i));
//
aggiungi
for (Gatto g : gatti)
out.println(g);
for (Cane c : cani)
out.println(c);
//
estrai
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Vantaggi nell’uso di generici
I principali vantaggi dovuti all’introduzione dei tipi generici sono:
Il compilatore può verificare qulasiasi operazione add di
oggetti alla collezione
il tipo dell’oggetto estratto da una collezione è noto, quindi
non vi è la necessità di operare un cast a un tipo diverso
(fonte di potenziali errori se il cast è fatto su tipi non
omologhi)
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
ArrayList vs LinkedList
ArrayList ottimizzato l’accesso casuale (basato su array),
non ottimizzati l’inserimento e l’eliminazione
all’interno della lista (grosso modo equivalente a
Vector)
LinkedList ottimizzato l’accesso sequenziale, l’inserimento e
l’eliminazione, indicato per implementare pile
(LIFO) e code (FIFO), infatti contiene i metodi:
addFirst(), addLast(), getFirst(),
getLast(), removeFirst( ),
removeLast()
!
Collections!
MeHe!a!disposizione!metodi!per!effeHuare!
operazioni!generiche!con!le!Collezioni.!
• 
• 
• 
• 
• 
Ordinare!una!lista!(sort)!
Mescolare!una!lista!(shuffle)!
Scambiare!elemen2!di!una!lista!(swap)!
Copiare!una!lista!(copy)!
…!
Ne!esiste!una!equivalente!anche!per!gli!
array!(Arrays).!
!
Collections!
Esempio:!metodi!sort!
!
static void sort(List<T> list)!
Sorts!the!specified!list!into!ascending!order,!according!to!the!
natural'ordering!of!its!elements.!
!!
static void sort(List<T> list, Comparator<? super T> c) !
Sorts!the!specified!list!according!to!the!order!induced!by!the!
!!
specified!comparator.
!
Collections!
Esempio:!metodo!sort!
Ordiniamo!una!lista!di!Integer!secondo!l’ordine!
naturale.!
List<Integer> listaInteri = new ArrayList<Integer>();!
listaInteri.add(5);!
listaInteri.add(2);!
listaInteri.add(9);!
Collections.sort(listaInteri);!
System.out.println("Lista di interi ordinata: ");!
for (int i:listaInteri) {!
System.out.println(i);!
}
!!
Comparable!
! Per!definire!l’ordinamento!naturale!di!una!classe,!la!classe!deve!
implementare!l’interfaccia!Comparable.!
E’#buona#norma#che#il#metodo#compareTo#sia#simmetrico#e#
consistente#con#equals!#
#
java.u7l#Interface#Comparable<T>#
T!C!the!type!of!objects!that!this!object!may!be!compared!to!
!
int!compareTo(T#o)!
Compares!this!object!with!the!specified!object!for!order.!Returns!a!
nega2ve!integer,!zero,!or!a!posi2ve!integer!as!this!object!is!less!than,!
equal!to,!or!greater!than!the!specified!object.!
! Un!comparatore!implementa!un!metodo!compare!per!
comparare!due!oggeV!secondo!un!ordine!totale.!Puo’!essere!
usato!come!secondo!argomento!del!metodo!
Collections.sort.!
E’#buona#norma#che#il#metodo#compare#sia#simmetrico#e#
consistente#con#equals!#
#
java.util Interface Comparator<T>!
T!C!the!type!of!objects!that!may!be!compared!by!this!comparator!
!
int compare(T o1, T o2)!
Compares!its!two!arguments!for!order.!Returns!a!nega2ve!integer,!zero,!
or!a!posi2ve!integer!as!the!first!argument!is!less!than,!equal!to,!or!
greater!than!the!second.!
!
!
Esempio:!GaHo!comparabile!
!
public class Gatto implements Comparable<Gatto> {!
// ....!
@Override!
public int compareTo(Gatto gatto) {!
if (gatto.getID() == getID()) {!
return 0;!
} else if (gatto.getID() < getID()) {!
return -1;!
} else {!
return 1;!
}!
}!
}
!!
!
!
Esempio:!GaHo!comparabile!
Creiamo#un#comparatore#che#ordini#i#gaB#in#base#al#nome.!
!
public class NomeGattoComparator implements Comparator<Gatto> {!
!
@Override!
public int compare(Gatto g1, Gatto g2) {!
return g1.getNome().compareTo(g2.getNome());!
}!
}
!!
!
sort!
Esempio:!ordinamento!di!gaV!in!base!al!nome!
!
List<Gatto> gatti = new ArrayList<Gatto>();!
gatti.add(new Gatto(1, "Tom"));!
gatti.add(new Gatto(1, "Felix"));!
gatti.add(new Gatto(1, ”Star"));!
!
System.out.println("Lista gatti:");!
for (Gatto gatto:gatti) {!
System.out.println(gatto.getNome());!
}!
Collections.sort(gatti, new NomeGattoComparator());!
System.out.println("Lista gatti ordinata:");!
for (Gatto gatto:gatti) {!
System.out.println(gatto.getNome());!
}!
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Scansione: for-each e Iteratori
Il costrutto for-each:
for (Object o : collection)
System.out.println(o);
L’interfaccia Iterator:
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Uso: for-each e Iteratori
Si usa l’iteratore
for-each quando:
si deve rimuovere il corrente oggetto (esempio filtraggio)
static void filter(Collection c) {
for (Iterator i = c.iterator(); i.hasNext();) {
if (!cond(i.next()))
i.remove();
}
si deve rimpiazzare un elemento nella lista o nell’array
durante l’attraversamento
ListIterator<E> extends Iterator<E>
occorre iterare su molteplici collezioni simultaneamente
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Uso di Iterator
Problema
Usare Iterator per modificare la classe CaniEGatti al fine
di eliminare dalla lista gatti i gatti con ID dispari e dalla lista
cani i cani con ID pari
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Codifica
List<Gatto> gatti = new ArrayList<Gatto>();
List<Cane> cani = new ArrayList<Cane>();
for (int i = 0; i < 7; i++)
gatti.add(new Gatto(i));
//
aggiungi
for (int i = 0; i < 3; i++)
cani.add(new Cane(i));
//
aggiungi
//
iterator
for (Iterator<Gatto> eG = gatti.iterator(); eG.hasNext();){
if ((eG.next().getID() % 2) == 1)
eG.remove();
}
for (Iterator<Cane> eC = cani.iterator(); eC.hasNext();) {
if ((eC.next().getID() % 2) == 0)
eC.remove();
}
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Indice
1
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di Liste
Scansione: for-each e Iteratori
Esempi di insiemi
Mappe
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
L’interfaccia Set
public interface Set<E> extends Collection<E> {
//
Operazioni base
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(E element);
//
boolean remove(Object element); / /
Iterator iterator();
//
Optional
Optional
O p e r a z i o n i su c o l l e z i o n i
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
//
Opera i
Object[] toArray();
<T> T[] toArray(T[] a);
//
Optional
//
Optional
//
Optional
//
Optional
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
La classe HashSet
Una della classi più utili nella gestione di insieme di oggetti è la
classe HashSet
Set<T> insieme = new HashSet<T>(c);
Osservazione: Notare che si usa il tipo interfaccia Set per la
variabile insieme (pratica fortemente raccomadata). Si
produce codice molto flessibile. Per esempio, per avere
l’elenco ordinato:
Set<T> insieme = new TreeSet<T>(c);
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Il codice hash associato agli oggetti
Funzione hash
Un funzione hash in Java è una funzione che mappa un
oggetto in un numero intero (codice hash)
Proprietà:
oggetti logicamente uguali devono avere lo stesso codice
hash
Oggetti distinti possono avere lo stesso codice hash
(collisione), l’importante è che questo fatto sia piuttosto
infrequente
Deve essere una funzione semplice e “veloce” da
calcolare, possibilmente dipendente da campi della classe
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Il metodo hashCode()
Contratto di Object.hashCode
Il metodo hashCode deve produrre lo stesso numero anche
quando invocato più volte sullo stesso oggetto. Se due oggetti
sono uguali in accordo al metodo equal (Object o), allora il
metodo hashCode invocato su entrambi gli oggetti deve
produrre lo stesso numero. Non è richiesto che oggetti diversi
producano codici hash distinti
Osservazioni: normalmente questo contratto viene disatteso!
Per usare HashSet è fondamentale osservarlo!
Regola: si deve sovrascrivere hashCode() in tutte le classi
ove viene sovrascritto equal (Object o)
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Esempi di codici hash
...
System.out.println("cane".hashCode());
System.out.println("cane".hashCode());
System.out.println("gatto".hashCode());
Quadrato q = new Quadrato(1);
System.out.println(q.hashCode());
q = new Quadrato(1);
System.out.println(q.hashCode());
q = new Quadrato(2);
System.out.println(q.hashCode());
Persona p = new Persona("Paolo","Rossi");
System.out.println(p.hashCode());
p = new Persona("Paolo","Rossi");
System.out.println(p.hashCode());
p = new Persona("Paola","Rossi");
System.out.println(p.hashCode());
...
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Stampa dei Risultati
Esecuzione del metodo main della classe HashCodeEx:
HashCode
HashCode
HashCode
HashCode
HashCode
HashCode
HashCode
HashCode
HashCode
di:
di:
di:
di:
di:
di:
di:
di:
di:
"cane" -> 3046037
"cane" -> 3046037
"gatto" -> 98127573
Quadrato(1) -> 19972507
Quadrato(1) -> 7754385
Quadrato(2) -> 2548785
Persona("Paolo","Rossi")
Persona("Paolo","Rossi")
Persona("Paola","Rossi")
//non definito
//non definito
//non definito
-> -1832489941
-> -1832489941
-> -1832490375
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Uso di HashSet
Problema
Usare la classe HashSet (TreeSet) per trovare le parole
duplicate in una stringa passata come argomento sulla linea di
comando
>java TrovaDuplicati ciao mamma ciao
Duplicati: ciao
2 parole distinte: [mamma, ciao]
Duplicati: ciao
2 parole distinte (ordinate): [ciao, mamma]
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Esempio
import java.util.*;
class TrovaDuplicati {
public static void main(String args[]) {
Set<String> s = new HashSet<String>();
for (String a : args)
if (!s.add(a))
System.out.println("Duplicati: " + a);
System.out.println(s.size() + " parole distinte: " + s);
s = new TreeSet<String>();
for (String a : args)
if (!s.add(a))
System.out.println("Duplicati: " + a);
System.out.println(s.size() + " parole distinte (ordinate): " + s)
}
}
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Indice
1
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di Liste
Scansione: for-each e Iteratori
Esempi di insiemi
Mappe
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
L’interfaccia Mappa
public interface Map<K,V> {
// Opera ion
V put(K key, V value);
V get(Object key);
V remove(Object key);
boolean containsKey(Object key);
boolean containsValue(Object value);
int size();
boolean isEmpty();
// Opera ion
void putAll(Map<? extends K,? extends V> t);
void clear();
// Collezioni
public Set<K> keySet();
public Collection<V> values();
public Set<Map.Entry<K,V>> entrySet();
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Mappe
Map Un gruppo di coppie di oggetti
chiave-valore. Una Map può
resti uire un Set di chiavi, una
Collection di valori o un Set
delle sue coppie.
Idea: associare oggetti (chiave) a
oggetti (valore), invece di
associare numeri a oggetti (come
ArrayList)
Map
HashMap
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Uso di HashMap
Problema
Usare la classe HashMap (TreeMap) per calcolare le
occorrenze di ogni singola parola
st
passat
argomento sulla linea di comando
>java FrequenzaParole ciao mamma ciao
2 parole distinte:
{mamma=1, ciao=2}
2 parole distinte (ordinate):
{ciao=2, mamma=1}
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Esempio
public class FrequenzaParole {
public static void main(String args[]) {
Map<String, Integer> m = new HashMap<String, Integer>();
for (String a : args) {
Integer freq = m.get(a);
m.put(a, (freq == null ? 1 : freq + 1));
}
System.out.println(m.size() + " parole distinte:");
System.out.println(m);
m = new TreeMap<String, Integer>();
for (String a : args) {
Integer freq = m.get(a);
m.put(a, (freq == null ? 1 : freq + 1));
}
System.out.println(m.size() + " parole distinte:");
System.out.println(m);
}
}
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Problema
Problema
Scrivere un programma che mostri la pseudo casualità del
generatore di numeri casuali implementato nella classe
java.util.Random utilizzando la classe Contatore per
contare le occorrenze dei numeri.
Metodo: genero molti (10000) numeri nell’intervallo [1, 10] e
mostro la frequenza con cui si manifestano, quindi stampo la
coppia (numero, frequenza)
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Risultato
>java DistUniformeDemo
Frequenze di 10000 numeri (tra 1 e 10) generati a caso:
[1=974, 2=1000, 3=954, 4=1010, 5=993, 6=1049, 7=996,
8=1000, 9=977, 10=1037]
Le Collezioni (Java Collections)
Modellare liste e insiemi
Esempi di liste
Scansione
Esempi di insiemi
Mappe
Problema con mappe ordinate per chiave
Problema
Scrivere un programma che gestisca una rubrica telefonica:
una chiave (ordinabile), per es. cognome e un valore per es.
Persona.
Si consiglia l’uso di java.util.TreeMap