• Non ci sono risultati.

22 - Strutture Dati (Java Collections Framework)

N/A
N/A
Protected

Academic year: 2022

Condividi "22 - Strutture Dati (Java Collections Framework)"

Copied!
32
0
0

Testo completo

(1)

22 - Strutture Dati (Java Collections Framework)

Programmazione e analisi di dati Modulo A: Programmazione in Java

Paolo Milazzo

Dipartimento di Informatica, Universit`a di Pisa http://pages.di.unipi.it/milazzo

milazzo di.unipi.it

Corso di Laurea Magistrale in Informatica Umanistica A.A. 2017/2018

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 1 / 32

(2)

Sommario

1 Collezioni: insiemi e liste

2 Iteratori

(3)

Collezioni di oggetti (1)

La libreria standard di Java fornisce una serie di classi che consentono di lavorare con gruppi di oggetti (collezioni)

Tali classi della libreria standard prendono il nome di Java Collections Framework

Sono tutte classi contenute nel package java.util della libreria standard di Java

La classe Vector, che consente di lavorare con sequenze di oggetti indicizzate, fa parte del Java Collections Framework

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 3 / 32

(4)

Collezioni di oggetti (2)

Il Java Collections Framework prevede due tipologie principali di collezione: insiemie liste

Un insiemecorrisponde a un gruppo di oggetti tutti distinti tra loro gli elementi possono

(facoltativamente) essere mantenuti secondo qualche ordinamento

Unalista corrisponde a un gruppo di oggetti in cui possiamo avere elementi ripetuti

(5)

Interfacce e Classi del Java Collections Framework (1)

Il Java Collections Framework descrive le caratteristiche generali delle principali tipologie di collezioni tramite opportune interfacce

Collection`e l’interfaccia che descrive genericamente le funzionalit`a di una collezione

Set`e l’interfaccia (estensione di Collection) che descrive le funzionalit`a di un insieme

List`e l’interfaccia (estensione di Collection) che descrive le funzionalit`a di una lista

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 5 / 32

(6)

Interfacce e Classi del Java Collections Framework (2)

Inoltre, il framework fornisce una serie di implementazioni di queste interfacce, tra cui:

HashSet implementa l’interfaccia Set non mantenendo gli elementi in nessun ordine particolare

TreeSetimplementa l’interfaccia Set mantenedo gli elementi secondo

(7)

Interfacce e Classi del Java Collections Framework (3)

In realt`a la gerarchia di classi `e anche pi`u articolata:

Per gli scopi di questa lezione `e sufficiente lo schema semplificato visto prima...

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 7 / 32

(8)

Attenzione!

Nel resto della lezione verranno descritte le principali classi del Java Collection Framework

La descrizione si baser`a su concetti ed esempi. Per i dettagli sui metodi implementati nella varie classi si veda la documentazione della libreria

standard di Java (Java API).

(9)

L’Interfaccia Collection

L’interfaccia Collection indica i metodi che devono essere presenti in una classe che descrive una generica collezione di oggetti

non si fanno assunzioni sulla natura di tale collezione (elementi ripetuti o meno, ordinamento degli elementi, ecc...)

perci`o, l’interfaccia `e volutamente generale e prevede metodi per:

— assicurarsi che un elemento sia nella collezione add

— rimuovere un elemento dalla collezione remove

— verificare se un elemento `e nella collezione contains

— verificare se la collezione `e vuota isEmpty

— sapere il numero di elementi della collezione size

— generare un array con gli elementi della collezione toArray

— verificare se due collezioni sono “uguali” equals

— ... e altri ... (si veda la doc. della libreria di Java) I metodi add e remove prendono come parametro l’elemento da aggiungere/rimuovere, non la sua posizione.

Abbiamo gi`a visto molti di questi metodi quando abbiamo parlato di Vector (che implementa Collection).

(10)

L’Interfaccia Set

L’interfaccia Set estende Collection introducendo l’idea di insieme di elementi

in quanto insieme, non ammette elementi duplicatie non ha una nozione di sequenza o di posizione

non aggiunge nessun metodo in pi`u rispetto a Collection. Pone per`o dei vincolisull’uso dei metodi:

I add aggiunge un elemento solo se esso non `e gi`a presente

I equals restituisce true se i due Set confrontati contengono gli stessi elementi indipendentemente dall’ordine

(11)

L’Interfaccia List

L’interfaccia List estende Collection introducendo l’idea di sequenzadi elementi

tipicamente ammette elementi duplicati

in quanto sequenza, ha una nozione di posizione

pone per`o dei vincoli sull’uso dei metodi di Collection, e aggiunge ad essi alcuninuovi metodi per l’accesso posizionale

I add aggiunge un elemento in ultima posizione (append)

I equals restituisce true se i due List confrontati contengono gli stessi elementi nelle stesse posizioni

I nuovi metodi add, remove, get che agiscono sulla posizione passata loro come parametro

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 11 / 32

(12)

La classe HashSet

La classe HashSet `e l’implementazione di Set che viene utilizzata pi`u comunemente

La classe HashSet `e implmentata in modo da rendere particolarmente efficienti le operazioni di inserimento, ricerca e cancellazione di un elemento

Utilizza al suo interno una tabella hash

Le operazioni possono essere eseguite in tempo costante (ossia indipendente dal numero di elementi contenuti nell’insieme)

(13)

In breve: le tabelle hash

Unatabella hash rappresenta un insieme come un array di liste

usa unafunzione hash che, dato un elemento, restituisce un numero dato un elemento e dell’insieme, la lista che lo conterr`a `e quella che si trova in posizione hash(e) dell’array

se la funzione hash riesce a “spalmare” bene gli elementi nelle posizioni, le operazioni di ricerca, inserimento e cancellazione di un elemento diventano veloci (accesso diretto alla posizione giusta dell’array e scansione di una breve lista)

(14)

Esempio di HashSet

Programma che chiede all’utente di inserire 10 parole, e stampa un messaggio ogni volta che si inserisce una parola gi`a inserita in precedenza.

sfrutta il fatto che il metodo add di Set restituisce false se l’elemento non era presente

i m p o r t j a v a . u t i l . H a s h S e t ; i m p o r t j a v a . u t i l . S c a n n e r ; p u b l i c c l a s s P a r o l e R i p e t u t e {

p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { S c a n n e r i n p u t = new S c a n n e r ( S y s t e m . in );

HashSet < String > set = new HashSet < String > ( ) ; for (int i =0; i < 1 0 ; i ++) {

S t r i n g s = i n p u t . n e x t L i n e ();

// c e r c a di i n s e r i r e s in set , se gia ’ p r e s e n t e s t a m p a un msg . if (! set . add ( s ))

(15)

Altro esempio di HashSet

Programma che simula il gioco della tombola, ma in cui i numeri vengono rimessi nel sacchetto dopo l’estrazione. Quante estrazioni ci vogliono prima di vedere tutti e 90 i numeri?

i m p o r t j a v a . u t i l . H a s h S e t ; i m p o r t j a v a . u t i l . R a n d o m ;

p u b l i c c l a s s T o m b o l a C o n R i p e t i z i o n i { p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) {

HashSet < Integer > n u m e r i E s t r a t t i = new HashSet < Integer > ( ) ; R a n d o m g e n e r a t o r = new R a n d o m ();

int c o n t =0;

w h i l e ( n u m e r i E s t r a t t i . s i z e ( ) ! = 9 0 ) { c o n t ++;

int n u m e r o = 1+ g e n e r a t o r . n e x t I n t ( 9 0 ) ; n u m e r i E s t r a t t i . add ( n u m e r o );

S y s t e m . out . p r i n t l n ( c o n t +" : "+ n u m e r o +" ( "+ n u m e r i E s t r a t t i . s i z e ()+" ) ");

} } }

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 15 / 32

(16)

La classe TreeSet

La classe TreeSet `e l’implementazione di Set che viene utilizzata quando

`

e utile mantenere gli elementi ordinati (secondo il loro ordine naturale) Esempi di situazioni in cui `e conveniente mantenere un insieme ordinato:

quando si deve frequentemente visualizzare o rappresentare gli elementi dell’insieme in modo ordinato

quando si devono frequentemente confrontare due insiemi (confrontare due insiemi ordinati `e pi`u facile che confrontare due insiemi disordinati)

La classe TreeSet `e implementata in modo da rendere per quanto possibile efficienti le operazioni di inserimento, ricerca e cancellazione di un elemento

(17)

In breve: la rappresentazione ad albero

Un insieme ordinato pu`o essere rappresentato da un albero binario

Per vedere se un elemento `e presente si parte dalla radice dell’albero

si scende a destra o a sinistra a seconda che l’elemento cercato sia minore o maggiore di quello corrente

si ripete il procedimento finch`e non si trova l’elemento e non si raggiunge una foglia

Questo procedimento di ricerca richiede di fare circa log2(n) passi, se l’insieme contiene n elementi.

(18)

Esempio di TreeSet

Programma che inserisce 10 stringhe in un HashSet e in un TreeSet e stampa il contenuto delle due strutture dati.

i m p o r t j a v a . u t i l .*;

p u b l i c c l a s s T e s t S e t {

p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { H a s h S e t s1 = new HashSet < String > ( ) ; r i e m p i S e t ( s1 );

S y s t e m . out . p r i n t l n (" s1 = " + s1 );

T r e e S e t s2 = new TreeSet < String > ( ) ; r i e m p i S e t ( s2 );

S y s t e m . out . p r i n t l n (" s2 = " + s2 );

}

// l ’ uso d e l l ’ i n t e r f a c c i a Set per il p a r a m e t r o c o n s e n t e di u s a r e // il m e t o d o a u s i l i a r i o sia con o g g e t t i H a s h S e t che T r e e S e t p r i v a t e s t a t i c v o i d r i e m p i S e t ( Set < String > s ) {

for (int i =0; i < 1 0 ; i ++) s . add (" str " + i );

(19)

Altro esempio con HashSet e TreeSet

Programma che legge il testo della Divina Commedia, ne conta le parole (con ripetizioni) e le parole distinte.

Si vedano i programmi allegati:

ParoleDivinaCommedia.java— usa Vector per raccogliere le parole e HashSet per raccogliere le parole distinte

ParoleDivinaCommedia2.java — usa Vector per entrambi gli scopi

ParoleDivinaCommedia3.java — usa Vector e TreeSet

I tre programmi usano il file divina commedia.txt(allegato) contenente il testo dell’opera, e visualizzano il tempo impiegato per completare l’operazione.

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 19 / 32

(20)

Le classi ArrayList e Vector

Le classi ArrayList e Vector (molto simili tra loro) sono le implementazioni di List che si usano pi`u comunemente.

Le classi ArrayList e Vector sono implementate tramite array dinamici Memorizzano gli oggetti della lista in un array

Quando l’array `e pieno, ne creano uno pi`u grande, ci copiano gli elementi e lo sostituiscono al precedente

Le operazioni di lettura di un elemento tramite la posizione possono essere eseguite rapidamente (accesso diretto all’array tramite indice) La ricerca di un elemento richiede un tempo proporzionale al numero di elementi nella lista (scansione sequenziale dell’array, tempo lineare)

(21)

La classe LinkedList

La classe LinkedList `e l’implementazione di List da preferirsi quando si deve frequentemente inserire/rimuovere elementi nel mezzo della lista.

La classe LinkedList `e implementata tramite unalista doppiamente puntata

Ad ogni elemento `e aggiunto un riferimento all’elemento successivo e un riferimento al precedente nella lista

La ricerca di un elemento richiede di scandire la lista da un’estremit`a (tempo lineare, come per ArrayList e Vector)

Anche le operazioni di accesso tramite la posizione richiedono di scandire la lista...

L’inserimento nel mezzo della lista (una volta trovata la posizione) richiede solo di aggiustare i riferimenti al precedente/successivo nel punto in cui si inserisce il nuovo elemento

Un ArrayList o Vector, invece, deve anche spostare tutti gli elementi seguenti avanti o indietro di una posizione (memorizzazione contigua degli elementi)

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 21 / 32

(22)

In breve: la lista doppiamente puntata

Rappresentazione:

Rimozione dal mezzo della lista:

(23)

Esempio di confronto tra Vector e LinkedList

Di esempi con Vector ne abbiamo gi`a visti in passato Si veda il programma allegato: TestList.java

Questo programma esegue delle operazioni di inserimento e lettura (tramite posizione) in liste implementate tramite Vector e LinkedList, confrontando i tempi di esecuzione.

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 23 / 32

(24)

Sommario

1 Collezioni: insiemi e liste

2 Iteratori

(25)

Iteratori (1)

Un iteratore`e un oggetto di supporto usato per accedere agli elementi di una collezione, uno alla volta e in sequenza

Un iteratore `e sempre associato ad un oggetto collezione (lavora su uno specifico insieme o lista)

Per funzionare, un oggetto iteratore deve conoscere (e poter accedere) alla rappresentazione interna della classe che implementa la collezione (tabella hash, albero, array, lista puntata, ecc...)

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 25 / 32

(26)

Iteratori (2)

Un iteratore `e un oggetto di una classe che implementa l’interfaccia Iterator

L’interfaccia Collection contiene il metodo iterator() che restituisce un iteratore per la collezione

le varie implementazioni di Collection quali HashSet,Vector, ecc...

implementano il metodo iterator() restituendo un oggetto iteratore specifico per quel tipo di collezione (ossia, una specifica

implementazione di Iterator)

L’interfaccia Iterator prevede gi`a tutti i metodi necessari per usare un

(27)

L’interfaccia Iterator

L’interfaccia Iteratorprevede i seguenti metodi:

next() che restituisce il prossimo elemento della collezione e contemporaneamente sposta il “cursore” dell’iteratore all’elemento successivo

hasNext() che verifica se c’e’ un elemento successivo da fornire o se invece si `e raggiunto la fine della collezione

remove() che elimina l’elemento restituito dall’ultima invocazione di next()

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 27 / 32

(28)

Come si usa un iteratore (1)

Un iteratore si usa come nel seguente schema

// c o l l e z i o n e di o g g e t t i di t i p o T che v o g l i a m o s c a n d i r e C o l l e c t i o n < T > c = . . . .

...

// i t e r a t o r e s p e c i f i c o per la c o l l e z i o n e c I t e r a t o r < T > it = c . i t e r a t o r ()

// f i n c h e ’ non a b b i a m o r a g g i u n t o l ’ u l t i m o e l e m e n t o w h i l e ( it . h a s N e x t ()) {

// o t t i e n i un r i f e r i e n t o all ’ o g g e t o c o r r e n t e , ed a v a n z a T e = it . n e x t ();

. . . . // usa l ’ o g g e t t o c o r r e n t e ( a n c h e r i m u o v e n d o l o ) }

(29)

Come si usa un iteratore (2)

Un esempio concreto su un insieme di interi (rimuove i pari e stampa di dispari)

HashSet < Integer > set = new HashSet < Integer > ( ) ; . . . .

I t e r a t o r < Integer > it = set . i t e r a t o r () w h i l e ( it . h a s N e x t ()) {

I n t e g e r i = it . n e x t ();

if ( i % 2 == 0) it . r e m o v e ();

e l s e

S y s t e m . out . p r i n t l n ( i );

}

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 29 / 32

(30)

Come si usa un iteratore (3)

Si noti che l’iteratore non ha alcuna funzione che lo “resetti”:

una volta iniziata la scansione, non si pu`o fare tornare indietro l’iteratore

una volta finita la scansione, l’iteratore non `e pi`u utilizzabile (bisogna crearne uno nuovo)

Gli iteratori sono in realt`a il meccanismo usato da Java per realizzare i cicli for-each

scrivere for(String s : v) corrisponde in realt`a a creare implicitante un iteratore per v

usare gli iteratori in maniera esplicita consente di fare pi`u cose

I suddividere (sospendere) la scansione della collezione in due cicli

(31)

Attenzione!

Nel mentre che si sta usando un iteratore su una collezione, `e benenon apportare modifiche alla collezione stessa (aggiungere/rimuovere elementi) se non tramite il metodo remove() di Iterator

Il comportamento dell’iteratore dopo una modifica della collezione `e in generale impredicibile!

Paolo Milazzo (Universit`a di Pisa) Programmazione - Strutture Dati A.A. 2017/2018 31 / 32

(32)

Altre classi spesso usate del Java Collection Framework

Collections(notare la ’s’ finale) Contiene parecchi metodi utili per l’elaborazione di collezioni (di qualunque tipo)

I ordinamento di collezioni

I calcolo di massimo e minimo

I rovesciamento, permutazione, riempimento di una collezione

I confronto tra collezioni (elementi in comune, sottocollezioni, ...)

I ....

HashMap (implementazione di Map) non `e un’implementazione di Collection, ma `e comunque una struttura dati molto usata del Java Collection Framework

I realizza una struttura dati “dizionario” che associa termini chiave (univoci) a valori

Queue,Dequecollezioni specializzate nella gestione di code FIFO

Riferimenti

Documenti correlati

Se memorizziamo n chiavi in una tabella hash con m = n 2 slot utilizzando una funzione hash h scelta a caso da una classe universale di funzioni hash, la probabilit`a che si

Si definisce grado di squilibrio di un nodo il valore assoluto della differenza tra la somma delle chiavi nei nodi foglia del sottoalbero sinistro e la somma delle chiavi dei

boolean addAll(Collection&lt;? extends E&gt; c); // Optional boolean removeAll(Collection &lt;?&gt; c); // Optional boolean retainAll(Collection &lt;?&gt; c); //

Il referente scolastico per il Covid-19 deve mantenere monitorato l’andamento delle assenze per motivi di salute degli alunni e del personale scolastico della propria

Fondamenti di Informatica 1 A.A.. variabili, costanti, espressioni) sono associati ad un tipo che li caratterizza..  tipo

Fondamenti di Informatica 1 A.A. variabili, costanti, espressioni) sono associati ad un tipo che li caratterizza..  tipo

 valore di ritorno di un metodo per definire una procedura void azzera(){x=y=z=0;}. Tipi e array in Java , Paolo

o Scegliere Chiudi dal menu File oppure fare clic su nella barra del titolo oppure fare clic col tasto destro del mouse sul nome del programma sulla barra delle applicazioni e