Parti II e III
1
Framework Collections in Java:
API Java http://java.sun.com/
Generics in Java
Tutorial Sun (in inglese)
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
Testo di Riferimento (usato nei corsi precedenti)
Horstmann - Concetti di informatica e fondamenti di
Java – Apogeo
2
Collection Framework (contd …)
3
Data la porzione di codice
static int segreto(ArrayList a) {
int r = ((Integer) a.get(0)).intValue();
Iterator i = a.iterator();
while (i.hasNext()) {
int c=((Integer)i.next()).intValue();
if (c<r)
r=c;
}
return(r);
}
Con input
ArrayList a = new ArrayList();a.add(3);a.add(5);
A) il metodo calcola la somma dei valori
B) il metodo calcola il minimo dei valori del vettore
C) il metodo calcola il massimo dei valori del vettore
D) il metodo genera una eccezione in esecuzione
Data la porzione di codice
static boolean segreto2(Iterator i) {
int prec = ((Integer) i.next());
while (i.hasNext()) {
int c=((Integer)i.next()).intValue();
if (prec>c)
return false;
}
return(true);
}
Con input
ArrayList a = new ArrayList();
a.add(“3”);
a.add(“5”);
segreto2(a.iterator())
A) il metodo genera una eccezione in esecuzione
B) il metodo calcola il massimo dei valori del vettore
C) il metodo ritorna vero se la sequenza di valori è crescente
D) il metodo ritorna vero se la sequenza di valori è decrescente
Data la porzione di codice
static void segreto3(ArrayList a, Object v) {
for (int i = a.size(); i < a.size()+10; i++)
{
final Object valore = a.get(i);
if (valore == null)
a.set(i, v);
}
}
A) il metodo sostituisce gli elementi nulli del vettore con v
B) il metodo genera una eccezione di cast in esecuzione
C) il metodo genera una eccezione di “index out of bound” in
esecuzione
D) il metodo stampa i valori del vettore
B – A - C
7
In stazione c’e’ un treno passeggeri pronto a partire.
Due amici devono prendere il treno ma non vogliono
viaggiare in piedi; chiedono allora al capotreno se ci sono posti
a sedere e gli viene risposto che ce n’è rimasto uno solo in
tutto il treno.
I due amici decidono allora di salire uno in testa e uno in coda
e procedendo alla stessa velocità vanno alla ricerca del vagone
in cui si trova il posto libero: il primo che lo trova si siederà.
Rappresentando il treno come una lista di interi che indicano i
posti rimasti liberi in ciascun vagone, scrivere una funzione in
grado di dire quale dei due amici si siederà (quello salito in
testa o quello salito in coda)
static int trovaPosto(ArrayList treno)
Ritorna 1 se si siede l’amico salito in testa, 2 se quello salito in cosa e 0
se arrivano insieme al vagone con l’unico posto libero
0
0
0
0
0
0
1
0
0
0
static int trovaPosto(ArrayList treno) {
boolean trovato = false;
int i = 0;
do {
Integer postiLiberi = (Integer) treno.get(i);
if (postiLiberi.intValue() > 0) {
trovato = true;
} else
i++;
} while (!trovato && i < treno.size());
if (!trovato) return -1;
if (i<treno.size()/2)return 1;
else if (i>treno.size()/2)return 2;
else return 0;
}
9
I Generics
10
Le liste e gli insiemi sono collezioni di variabili Object
Ogni volta che si vuole accedere agli elementi occorre fare il
cast
ArrayList a=new ArrayList();
a.add(“una stringa”);
String s=(String) a.get(0);
Ad una stessa collezione posso aggiungere elementi di tipi
differenti
non posso specificare che sono ammessi solo oggetti di un certo
tipo
ArrayList a=new ArrayList();
a.add(new Integer(10));
a.add(“una stringa”);
Si possono definire collezioni di tipi particolari?
Esempio: lista di Point, insieme di Studente, ecc.
11
Si può specificare che una lista contiene solo elementi di
un certo tipo:
LinkedList<Studente> l = new LinkedList<Studente>();
Una volta fatto questo, è come se la lista fosse una
sequenza di variabili Studente, invece che una lista di
variabili Object:
si possono solo inserire oggetti Studente (o sottoclassi):
l.add(new Point(20,30)); è un errore;
il valore di ritorno di get è di tipo Studente
Cosa cambia
si mette <Tipo> nella dichiarazione di variabile e nel
costruttore;
al posto di Object, si usa sempre Tipo in tutti i metodi (get,
add, ecc.)
12
Definire una Lista di studenti:
import java.util.*;
class ListStud {
public static void main(String args[]) {
LinkedList<Studente> l;
l=new LinkedList<Studente>();
l.add(new Studente("Ciccio", 932222));
l.add(new Studente("Franco", 234325));
// errore
// l.add(new Point(20,30));
Studente s=l.get(1);
}
}
13
Introduzione
Programmazione generica: creazione di costrutti di
programmazione che possano essere utilizzati con tipi di
dati diversi.
In Java si può raggiungere l’obiettivo della
programmazione generica usando l’ereditarietà oppure le
variabili di tipo.
Esempio: ArrayList di Java ArrayList<String>
Classe generica: è stata dichiarata usando una variabile
di tipo E. La variabile di tipo rappresenta il tipo degli
elementi:
public class ArrayList<E>
// si può usare "ElementType" invece di E
{
public ArrayList() { . . . }
public void add(E element) { . . . }
. . .
}
14
Creazione di variabili di classi generiche
Le variabili di tipo possono essere sostituite, all’atto
della creazione di esemplari, con nomi di classe o di
interfacce
ArrayList<String>
ArrayList<MyClass>
Non si può usare come sostituto uno degli otto tipi
di dati primitivi
ArrayList<double> // Sbagliato!
Usate un esemplare di ArrayList<Double>
Esempi:
ArrayList<String> a = new ArrayList<String>();
LinkedList<String> b = new LinkedList<String>();
15
I metodi delle classi generiche
Il tipo di dato che indicate va a sostituire la variabile di
tipo utilizzata nella definizione dell’interfaccia o della
classe generica
Esempio: nel metodo add di un oggetto di tipo
ArrayList<String> la variabile di tipo E viene
sostituita dal tipo String
public void add(String element)
public String get(int index)
Esempi:
ArrayList<String> a =new ArrayList<String>();
String s=a.get(0);//no cast
Iterator<String>=a.iterator(); //ritorna un iterator
generico
a.add(“paperino”);//non posso usare tipi differenti da
String
16
Caratteristiche delle classi generiche
Le variabili di tipo rendono più sicuro e di più facile
comprensione il codice generico.
E’ impossibile aggiungere un oggetto di tipo Integer
ad un esemplare di ArrayList<String>
È invece possibile aggiungere un oggetto di tipo
Integer ad un esemplare di ArrayList (senza
generics) che sia stato creato con l’intenzione di usarlo
per contenere stringhe
Tutte le classi del JCF sono generiche
Collection<E>, Set<E>, List<E> …
ArrayList<E>, LinkedList<E> …
Iterator<E> …
17
Esempi di utilizzo
ArrayList<String> a1 = new ArrayList<String>();
Integer numero=new Integer(30);
// Dovrebbe contenere oggetti di tipo String
LinkedList a2 = new LinkedList();
// errore di compilazione
a1.add(numero);
// errore non individuato dal compilatore
a2.add(numero);
//errore di esecuzione
String account = (String) a2.get(0);
18
ArrayList<E>
boolean add(E e)
void add(int index, E element)
E get(int index)
E set(int index, E element)
void clear()
Iterator<E> iterator()
int size()
Iterator<E>
boolean hasNext()
E next()
void remove()
19
Scrivere un metodo java
int somma(ArrayList<Integer> a)
che somma gli elementi del vettore di interi.
5
3
4
8
2
Somma: 22
Tempo 5 minuti …
20
public static int somma(ArrayList<Integer> a){
int somma=0;
for (int i=0;i<a.size();i++){
Integer elem=a.get(i)
somma=somma+elem.intValue();
}
return somma;
}
Per esercizio: implementare il metodo somma
utilizzando gli iteratori
21
Collection<E>:
List<E>
ArrayList<E>
LinkedList<E>
Vector<E>
Set<E>
SortedSet<E>
TreeSet<E>
HashSet<E>
LinkedHashSet<E>
Altre interfacce disponibili
Queue<E>,Dequeue<E>,Stack<E>, Map<K,V>,
SortedMap<K,V> …
22
PARTE 1: Confrontare il codice delle varie
implementazioni del metodo somma ed
evidenziarne le differenze
PARTE 2: Scrivere un metodo Java che dato un
ArrayList<String> di stringhe restituisca una unica
stringa che e’ la concatenazione di tutti i suoi
elementi.
23
Scrivere il metodo Java
void inverte(ArrayList<Integer> a)
che prende un ArrayList<Integer> e ne inverte l’ordine
degli elementi
L’elemento in posizione “i” va scambiato con quello
in posizione “n-i-1”
1
2
3
4
5
5
4
3
2
1
Scrivere il metodo Java
ArrayList<Integer> duplica(Integer v, int n)
che prende un valore v e un numero n e ritorna un
ArrayList<Integer> contenente n elementi di valore v
24
Data la porzione di codice:
ArrayList<String> s=new ArrayList<String>();
a.add(new Integer(10));
ArrayList p=new ArrayList ();
p.add(new Integer(10));
Indicare quali, tra le istruzioni seguenti, genera un errore in compilazione o in
esecuzione (eccezione):
1. s.add(“paperino”);
2. s.add(new Integer(10));
3. String q=s.get(0);
4. Object o=s.get(0);
5. Integer i=s.get(0);
6. s.add(s.get(0));
7. p.add(“paperino”);
8. p.add(new Integer(10));
9. String q=p.get(0);
10. Object o=p.get(0);
11. Integer i=p.get(0);
12. p.add(p.get(0));
Verificare le risposte al calcolatore
25
Comparable
Si può ordinare un array di Object?
No, perchè non esiste un ordinamento per tutti gli
oggetti
Per ordinare un insieme di oggetti, deve esistere una
funzione di confronto di questi oggetti
Interfaccia predefinita Comparable: rappresenta tutti
gli oggetti sui quali è definito un ordinamento totale
27
interface Comparable<T> {
public int compareTo(T o); }
interface Comparable {
public int compareTo(Oject o); }
Se una classe implementa Comparable, allora ha un
metodo compareTo(T o)
Quando si definisce una classe, il metodo compareTo
viene implementato in modo tale che
a.compareTo(b) ritorna:
un valore minore di zero se a è minore di b
uguale a zero se a è uguale a b
un valore maggiore di zero se a è maggiore di b
28
La definizione del metodo compareTo è semplicemente
che si tratta di un metodo che ha un Object come
argomento e ritorna un int
Il fatto che a.compareTo(b) dice se a è minore, uguale o
maggiore di b è una convenzione
Non c'è nessun vincolo sintattico che ci obbliga a
implementare compareTo come il confronto:
class Strana implements Comparable<Strana> {
public int compareTo(Strana o) {
return (int) Math.random()*2-1; }
}
È un errore semantico/concettuale
Effetto di un errore del genere: i metodi che lavorano su
oggetti Comparable si comportano in modo anomalo
Una cosa simile succede per equals
29
public static class Studente implements
Comparable<Studente> {
private String nome;
private String cognome;
public Studente(String nome, String cognome) {
this.nome = nome;
this.cognome = cognome;
}
public int compareTo(Studente o) {
int compCognome=cognome.compareTo(o.cognome);
if (compCognome != 0)
return compCognome;
else return nome.compareTo(o.nome);
}
public String getCognome() {return cognome;}
public String getNome() {return nome;}
}
Esercizio per casa: ordinare gli studenti in ordine decrescente
30
Metodo che ordina un array di due elementi:
static void ordina(Comparable c[]) {
Comparable t;
if(c[0].compareTo(c[1])<=0)
return;
t=c[0]; c[0]=c[1]; c[1]=t;
}
Esempio di programma:
public static void main(String args[]) {
Integer a[]=new Integer[2];
a[0]=new Integer(4);
a[1]=new Integer(2);
ordina(a);
System.out.println(a[0]+" "+a[1]);
}
31
Lo stesso metodo funziona per qualsiasi classe che
implementa l'interfaccia Comparable
String implementa Comparable
L'ordinamento fra stringhe è quello lessicografico
(detto anche alfabetico...)
String b[]=new String[2];
b[0]="Ciccio";
b[1]="Bruno";
ordina(b);
System.out.println(b[0]+" "+b[1]);
Uso lo stesso metodo per le stringhe
32
Principali interfacce definite nel JCF
Collection un multiinsieme non ordinato
List una sequenza ordinata di elementi
Set un insieme (non ordinato) di elementi
SortedSet un insieme ordinato per compareTo
Map un tabella (non trattata nel corso)
33
Differenza List e SortedSet
List gli elementi sono in una sequenza qualsiasi
SortedSet gli elementi sono ordinati secondo
l'ordinamento specificato da compareTo
Attenzione! Nell'interfaccia SortedSet non esiste il metodo
get(int index)
Gli iteratori di SortedSet scandiscono l'insieme in
ordine crescente
34
Esempio: inserisco alcuni interi e poi li stampo:
La classe TreeSet implementa l'interfaccia SortedSet
public static void main(String args[]) {
SortedSet<Integer> s=new TreeSet<Integer>();
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
35
Implementare il bubble sort di un vettore di elementi
comparable
void bubbleSort(ArrayList<Comparable> a)
Suggerimenti:
Utilizzare il metodo compareTo per confrontare gli
elementi
36
public static void bubbleSort(ArrayList<Comparable> a) {
int end = a.size() - 1;
boolean scambio = true;
while (scambio) {
scambio = false;
for (int i = 0; i < end; i++) {
//a[i+1]<a[i]
if (a.get(i + 1).compareTo(a.get(i)) < 0)
{
scambia(a, i, i + 1);
scambio = true;
}
}
//Ho gia' portato l'elemento
//piu' pesante in fondo all'array
end--;
}
}
37
private static void scambia
(ArrayList<Comparable> a, int i, int j) {
Comparable temp = a.get(i);
a.set(i, a.get(j));
a.set(j, temp);
}
38