Contiene tutte le interfacce e classi che realizzano insiemei ordinati o no di elementi
Dalle API:
Interface Collection: the root interface in the collection hierarchy. A collection represents a group of objects, known as its elements. Some collections allow duplicate elements and others do not. Some are ordered and others unordered.
Idea: mettere in una interfaccia tutte le caratteristiche comuni degli insiemi di oggetti (ordinati o no, con duplicazioni o no).
I più importanti:
Il metodo remove ritorna un booleano
Questo booleano dovrebbe valere True se la collezione cambia come risultato della remove (l'elemento da eliminare era presente)
Dei metodi delle interfacce si distinguono:
Per esempio, il contratto di remove è che si tratta di un metodo che rimuove un elemento e che il valore di ritorno indica se la rimozione è stata effettuata.
La firma dice soltanto che è un metodo che ha un Object come argomento e un boolean come valore di ritorno
In Java si può solo specificare la firma
Il contratto viene dato a parole
Se non si rispetta il contratto o la firma:
| Non si rispetta | quando per esempio | cosa succede |
| firma | viene implementato un metodo remove che non ha come argomento un Object o un valore di ritorno boolean | la classe non implementa l'interfaccia, e quindi viene segnalato un errore |
| contratto | il metodo remove ha la firma giusta, ma invece di rimuovere l'elemento lo aggiunge | chi usa la classe non riesce a far funzionare i suoi programmi |
Non rispettare la firma è un errore di linguaggio
Non rispettare il contratto è un errore semantico
Le interfacce non possono contenere costruttori (è nel linguaggio)
Il contratto dell'interfaccia Collection specifica però che ci deve essere un costruttore vuoto, che crea la collezione senza elementi
Le classi che implementano direttamente Collection rappresentano multi-insiemi non ordinati di oggetti.
Esempio di implementazione: usiamo una lista.
import java.util.*;
class MultiSet implements Collection {
private LinkedList l;
public MultiSet() {
l=new LinkedList();
}
public void add(Object o) {
l.add(o);
}
public boolean contains(Object o) {
return l.contains(o);
}
public boolean isEmpty() {
return l.isEmpty();
}
public Iterator iterator() {
return l.iterator();
}
public boolean remove(Object o) {
return l.remove(o);
}
public int size() {
return l.size();
}
// mancano altri metodi
}
Posso aggiungere un metodo add(int i, Object p)?
Le interfacce del collection framework sono organizzate cosí:
Il loro significato:
Attenzione! Nell'interfaccia SortedSet non esiste il metodo get(int index)
Gli iteratori di SortedSet scandiscono l'insieme in ordine crescente
La classe TreeSet implementa l'interfaccia SortedSet
Esempio: inserisco alcuni interi e poi li stampo:
public static void main(String args[]) {
SortedSet s=new TreeSet();
s.add(new Integer(21));
s.add(new Integer(0));
s.add(new Integer(4));
Iterator i=s.iterator();
while(i.hasNext())
System.out.println(i.next());
}
Viene stampato:
0 4 21
Gli iteratori scandiscono l'insieme in ordine
L'ordinamento che is usa è quello dato da compareTo
Si puè creare un oggetto TreeSet che non usa l'ordinamento dato da compareTo
Gli elementi sono nell'ordine dato da compare di questa classe, e non più nell'ordine di compareTo degli oggetti dell'insieme
class Compara implements Comparator {
public int compare(Object o1, Object o2) {
int i, j;
i=((Integer) o1).intValue();
j=((Integer) o2).intValue();
if(i<j)
return 1;
else if(i==j)
return 0;
else
return -1;
}
}
È l'ordine inverso di confronto fra interi
Il programma di prima, modificato:
class Inverso {
public static void main(String args[]) {
Compara c=new Compara();
SortedSet s=new TreeSet(c);
s.add(new Integer(21));
s.add(new Integer(0));
s.add(new Integer(4));
Iterator i=s.iterator();
while(i.hasNext())
System.out.println(i.next());
}
}
Ora viene stampato:
21 4 0
Servono a implementare "tavole con due colonne"
Esempio: una tavola con un numero di matricola e il nome dello studente:
| 980123 | "Ciccio" |
| 879231 | "Aldo" |
| 843098 | "Totti" |
| 732108 | "Aldo" |
Due studenti possono avere lo stesso nome, ma non lo stesso numero di matricola
Gli oggetti mappa sono una generalizzazione
Una tabella è caratterizzata da:
Due caselle della prima riga non possono contenere lo stesso valore
Le due colonne non hanno lo stesso significato:
Metodi fondamentali:
| 980123 | "Ciccio" |
| 879231 | "Aldo" |
| 843098 | "Totti" |
| 732108 | "Aldo" |
Questa tabella si può creare cosí:
public static void main(String args[]) {
HashMap m;
m=new HashMap(); // tabella vuota
m.put(new Integer(980123),
"Ciccio");
m.put(new Integer(879231),
"Aldo");
m.put(new Integer(843098),
"Totti");
m.put(new Integer(732108),
"Aldo");
}
In memoria: la tabella contiene in effetti i riferimenti agli oggetti inseriti
Per verificare se c'è uno studente con una certa matricola:
public static void main(String args[]) {
HashMap m;
// creazione tabella
if(m.containsKey(new Integer(843040)))
System.out.println("Matricola "+843040+" esistente");
else
System.out.println("Matricola "+843040+" non esistente");
if(m.containsKey(new Integer(843098)))
System.out.println("Matricola "+843098+" esistente");
else
System.out.println("Matricola "+843098+" non esistente");
}
}
Trovare un elemento con una certa matricola:
public static void main(String args[]) {
// creazione tabella
// verifica presenza matricola 843098
System.out.println("Lo studente con matricola "+843098+
" e': "+m.get(new Integer(843098)));
}
}
Come key e value, al posto del numero di matricola e del nome, posso usare oggetti qualsiasi
Esempio: numero di matricola e oggetto Studente
In effetti, gli HashSet sono realizzati usando una HashMap in cui si usa solo il campo key
Un interatore è un oggetto che permette la scansione di un insieme
Esiste un metodo della interfaccia Collection che restituisce un iteratore
Quindi, tutte le collezioni devono avere un iteratore associato
Esistono due interfacce:
Un oggetto ListIterator è un cursore per un oggetto che implementa List
Consente di andare avanti e indietro
Consente di inserire un elemento nella posizione corrente
Nelle interfacce, viene spesso specificato che un metodo è opzionale
Naturalmente, deve essere implementato, altrimenti viene dato errore
throw new UnsupportedOperationException("Operation not supported");
L'interfaccia Collection contiene un metodo add opzionale
Ogni classe che implementa Collection lo deve contenere (altrimenti il compilatore dà errore)
Dal momento che è opzionale, si può anche implementare in questo modo:
class Prova implements Collection {
...
public boolean add(Object o) {
throw new UnsupportedOperationException("Add operation not supported");
}
}