Parti II e III - Dipartimento di Informatica e Sistemistica

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