se invoco un metodo di Object che è ridefinito in Point, viene invocato il metodo definito in Point

Documenti analoghi
Nota: questo discorso vale solo per i metodi e le componenti che esistono in tutte e due le classi

I costruttori. Il costruttore standard. Esempio di valori di default. Alterare il costruttore standard

Bank. Bank. BankAccount. Bank. Bank. private BankAccount[] conti; // Posizione attuale private int posizioneattuale;...

18 - Vettori. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Introduzione Generics Iteratori. Collezioni in Java. Dr. Giulio Pellitta. 13 aprile 2011

Esempio su strutture dati dinamiche: ArrayList

Esempio su strutture dati dinamiche: ArrayList

Testo di Riferimento (usato nei corsi precedenti)

Algoritmi di Ricerca. Esempi di programmi Java

Muoversi all interno di un Vector. Vector e Enumeration. Enumeration. Collezioni di oggetti: Vector. La classe Object. Aggiungere oggetti a un Vector

Il Java Collections Framework

19 - Eccezioni. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Introduzione al Java Collections Framework. Java Collections Framework (cont.) Interfacce del Collections Framework

Collezioni. (a cura del Prof. Marco Patella)

Introduzione al Java Collections Framework

Algoritmi di Ricerca. Esempi di programmi Java

Esercizi di riepilogo (Fondamenti di Informatica 1 Walter Didimo)

SOLUZIONE. Requisiti. Requisiti (cont.) Requisiti (cont.) Sapienza - Università di Roma Facoltà di Ingegneria

Esempio su strutture dati dinamiche: ArrayList

Corso: Fondamenti di Informatica (Gruppo 2) a.a Corsi di laurea: Ing. Settore Informazione

STRUTTURE DATI: OLTRE GLI ARRAY LISTE

Corso di Laurea Ingegneria Civile Fondamenti di Informatica. Esercizi sui metodi. Carla Limongelli. Maggio Esercizi 1

Introduzione Programmazione Java

Programmazione II Compitino (Vers. B)

Programmazione Java Struttura di una classe, Costruttore, Riferimento this

Generics & Collections

22 - Strutture Dati (Java Collections Framework)

La classe Object. Ce li ha anche HelloWorld!!!

Esercizi riassuntivi (Fondamenti di Informatica 2 Walter Didimo) Soluzioni

Il linguaggio Java: aggiunte in Java 1.5

Richiami di Fondamenti di Informatica - 1

Uguaglianza e copia di oggetti

Programmazione II Compitino (Vers. A)

Creazione, eliminazione, lettura e scrittura di file di testo

TIPI PRIMITIVI: LIMITI

Esercitazione n 2. Obiettivi

Classi e array. Viene ora affrontato un problema di definizione di una classe in cui una variabile d istanza è di tipo array

Corso di Laurea Ingegneria Civile Elementi di Informatica. Esercizi. Carla Limongelli. Esercizi 1

Programmazione II Compitino (Vers. B)

Fondamenti di Informatica e Laboratorio T-AB T-15 Strutture dati

9 - Array. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Argomenti della lezione. Tipo di dato astratto. Array. Tipo di dato Lista. Liste Implementazione di liste in Java Stack Code

Fondamenti di Informatica I

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1

STRINGHE IN JAVA In Java, le stringhe non sono pezzi di memo-ria con dentro dei caratteri, come in C: sono oggetti appartenenti alla classe

Programmazione orientata agli oggetti La classe Object, metodi e classi final, this. Object

Classi astratte e progettazione OOP Esempio: l enciclopedia degli animali. Esempio Animali

Corso di Progettazione del Software

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a luglio 2011

Laboratorio di Programmazione Lezione 2. Cristian Del Fabbro

Notazione grafica UML

Capitolo 17. Introduzione alle strutture di dati. Capitolo 17 Introduzione alle strutture di dati

Calcolare x n = x x x (n volte)

ESERCIZIO 1 (FILE DI TESTO)

Algoritmi e Strutture Dati. Tipo di dato astratto e Strutture dati elementari

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

Classi astratte e progettazione OOP Esempio: l enciclopedia degli animali. Esempio Animali

Il TDA Dictionary. Definizione informale. I metodi del TDA Dictionary 1. Applicazioni. I metodi del TDA Dictionary 2. I metodi del TDA Dictionary 3

Fondamenti di Informatica L-B Esercitazione n 5 Java: Interfaccia Comparable, Array

7 - Programmazione procedurale: Dichiarazione e chiamata di metodi ausiliari

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

ADT Mappa. Le chiavi (il mezzo per accedere agli elementi) hanno lo scopo di rendere efficiente la ricerca. Strutture Dati

COLLEZIONI. SOMMARIO Collezioni: Liste: ITERATORI ITERATORI

public static boolean occorre (int[] a, int n) { int i = 0; boolean trovato = false;

Metodi di una Collection

Variabili e Metodi di classe Interfacce e Package Gestione di File in Java

Eccezioni Precisazioni e approfondimenti

Un esempio per iniziare. Il controllo del programma in C. Altri cenni su printf() Esercizi (printf) printf( 8!=%d, fatt);

Programmazione 1 A.A. 2015/2016

liste ogni nodo ha un successore, tranne l ultimo della lista che ne ha zero; alberi binari ogni nodo ha zero, uno oppure due figli

3. un metodo che restituisce l elenco delle matricole di tutti gli studenti del corso;

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

Strutture dati. Il che cosa e il come. F. Damiani - Alg. & Lab. 04/05

Fondamenti di Informatica 1. Prof. B.Buttarazzi A.A. 2010/2011

Ricerca e ordinamento su array di oggetti. Corso di Programmazione 2 Esercitazione 5

La classe java.lang.object

Classi astratte e progettazione OOP Esempio: l enciclopedia degli animali

Laboratorio di Programmazione 1 [Java]

SAPIENZA Università di Roma, Facoltà di Ingegneria

Programmazione con Java

Lezione 6 programmazione in Java

16 - Ereditarietà, tipi e gerarchie

Programmazione a Oggetti e JAVA. Prof. B.Buttarazzi A.A. 2012/2013

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a settembre 2012

Metodi statici. Dichiarazione e chiamata di metodi statici

Java, Oggetti e Strutture Dati di G. Callegarin - Edizioni CEDAM

Modulo 2: Strutture fondamentali della programmazione Java

Laboratorio di Sistemi Classi e relazioni Java

SOLUZIONE. Requisiti. Requisiti (cont.) Requisiti (cont.)

Classe Vettore (i) Creare una classe che consenta di gestire un vettore di N elementi reali (double), che preveda i seguenti metodi:

TIPI PRIMITIVI E CLASSI WRAPPER

Le liste con array. Rimuovere la perla rossa costringe a spostare molte altre perle. Dove mettere la perla verde se si è esaurito il filo?

Astrazioni sui dati : Specifica di Tipi di Dato Astratti in Java

Implementazione ADT: Alberi

Le basi del linguaggio Java

GESTIONE DEGLI ERRORI

Corso di Laurea in Bioinformatica Dipartimento di Informatica - Università di Verona

Programmazione. Cognome... Nome... Matricola... Prova scritta del 22 settembre Negli esercizi proposti si utilizzano le seguenti classi:

Laboratorio di Programmazione 1 [Java]

Le collezioni di oggetti. Prof. Accarino IIS Altiero Spinelli via Leopardi 132 Sesto San Giovanni

Transcript:

Gli HashSet Tipo predefinito che rappresenta insiemi di Object Cosa succede se... Posso mettere un riferimento a un Point in una variabile Object Object o=new Point(12,3); è quasi tutto come se l oggetto fosse un Object Unica eccezione: se invoco un metodo di Object che è ridefinito in Point, viene invocato il metodo definito in Point Cosa succede se faccio queste cose: o.x non funziona (x non è una componente di Object) o.move(...) non funziona (il metodo move non è un metodo di Object) o.equals(...) questo metodo sta sia in Object che in Point: viene invocato l equals di Point Funziona tutto come se l oggetto fosse un Object, tranne quando si invoca un metodo che sta sia in Object che in Point Dopo un cast Point p=(point) o: variabile Point con dentro un riferimento a un Point: funziona tutto come al solito Cosa hanno in comune Array, liste e insiemi Hanno in comune: una variabile rappresenta un insieme di oggetti Cosa hanno di diverso Differenze operazioni elementari negli array non si può inserire un elemento in mezzo: per farlo, devo creare un nuovo array e poi spostare gli elementi successivi ordine negli array e nella liste c è un ordine degli elementi (primo elemento, secondo elemento, ecc) Negli insiemi non c è nessun ordine 1

Il tipo HashSet Rappresenta insiemi non ordinati di elementi Non esiste un primo, secondo, ecc. elemento Creazione di un insieme vuoto: HashSet h; h=new HashSet(); Metodi sugli insiemi add(object o) aggiunge un elemento (se non è già presente) contains(object o) vede se l insieme contiene un elemento equals ad o remove(object o) rimuovo l oggetto, se presente isempty() vede se l insieme è vuoto size() ritorna il numero di elementi Nota: non c è un ordine degli elementi Quindi, non si può dire inserisci in prima posizione oppure trova l elemento in ultima posizione Esercizio Creare un insieme che contiene i numeri interi da -5 a 5 Soluzione Dato che negli HashSet ci posso solo mettere oggetti, devo usare il tipo Integer Implementazione Ciclo da -5 a 5 Ogni valore lo metto in un oggetto Integer import java.util.*; class Valori { public static void main(string args[]) { HashSet s; s=new HashSet(); int i; 2

Integer v; for(i=-5; i<=5; i++) { v=new Integer(i); s.add(v); System.out.println(s); Cosa stampa? L istruzione println(s) converte l insieme in una stringa, e poi la stampa Viene stampato: [5, -1, 4, -2, 3, -3, 2, -4, 1, -5, 0] Gli elementi non sono nell ordine in cui li ho messi! Insiemi e ordine Per definizione, in un insieme non devo tenere conto dell ordine in cui gli elementi vengono inseriti {1, 2, 3 e {2, 1, 3 sono lo stesso insieme Sono due stringhe che rappresentano lo stesso insieme Il metodo tostring degli insiemi dà una stringa fra quelle che rappresentano l insieme Esercizio Scrivere un metodo statico che verifica se un insieme contiene due interi consecutivi fra -10 e 10 static boolean consecutivi(hashset s) {... Soluzione Non abbiamo ancora visto come fare cicli su tutti gli elementi Facciamo un ciclo da -10 a 9 A ogni passo, verifichiamo la presenza static boolean consecutivi(hashset s) { int i; Integer v, t; for(i=-10; i<=9; i++) { v=new Integer(i); 3

t=new Integer(i+1); if(s.contains(v) && s.contains(t)) return true; Esempio Se viene passato l insieme: [3, 1, 8, 0] Cosa restituisce il metodo? Risposta true L insieme [3, 1, 8, 0] contiene i numeri 0 e 1 che sono consecuitivi Come fare cicli Si usa un meccanismo che esiste anche sulle liste Si crea un iteratore, che è un oggetto che serve a fare cicli sugli insiemi Esempio di ciclo Questo ciclo stampa gli elementi dell insieme s Iterator it; it=s.iterator(); while(it.hasnext()) { v=(integer) it.next(); System.out.println(v); Si può fare la stessa cosa anche se s è una LinkedList Cosa fa un iteratore Crea un ordine fra gli elementi dell insieme, e permette di passare da un elemento a quello dopo it=s.iterator(); 4

Crea un iteratore sull insieme s it.next(); Trova il prossimo elemento dell insieme it.hasnext() Ritorna true se ci sono altri elementi nell insieme Schema di ciclo Per fare la stessa cosa su tutti gli elementi di una lista o di un array: for(i=0; i<l.size(); i++) { elemento=l.get(i); opera su elemento Per liste e insiemi, si può fare il ciclo con un iteratore: Iterator it; it=s.iterator(); while(it.hasnext()) { elemento=it.next(); opera su elemento Per gli insiemi, non esiste ordinamento (non esiste l indice di un element), quindi non c è il metodo get (che ha come argomento un indice). L unico modo di fare cicli per gli insiemi è quello di usare un iteratore Esempio Dato un insieme di punti, stampare solo quelli che stanno nel primo quadrante static void primoquadrante(hashset s) {... Algoritmo risolutivo per ogni elemento dell insieme se e nel primo quadrante, stampalo Nelle liste, la parte "per ogni elemento" si può implementare con un iteratore oppure con il ciclo solito 5

Per gli insiemi, posso solo usare l iteratore Soluzione Creo un iteratore, e lo uso nel ciclo Per vedere le coordinate, devo fare il cast static void primoquadrante(hashset s) { Point p; Iterator i; while(i.hasnext()) { p=(point) i.next(); if(p.x>=0 && p.y>=0) System.out.println(p); Altro esercizio Verificare se un insieme di interi contiene due numeri consecutivi static boolean consecutivi(hashset s) {... Il metodo di prima lo faceva solo per interi da -10 a 10 Ora lo voglio per tutti gli interi Non si può fare un ciclo su tutti i possibili valori interi Soluzione Si fa un ciclo su tutti gli elementi dell insieme Per ogni elemento, se c è anche quello più grande di uno, si ritorna true Se questo non è mai vero, si ritorna false Implementazione del metodo static boolean consecutivi(hashset s) { int i; Integer v, t; Iterator it; it=s.iterator(); while(it.hasnext()) { 6

v=(integer) it.next(); i=v.intvalue(); t=new Integer(i+1); if(s.contains(t)) return true; Metodi dell insieme e dell iteratore Attenzione a non confondere s e it, e usare i metodi sull oggetto sbagliato: s.contains(...) la verifica di contenimento, cosí come l inserimento, cancellazione, ecc. vanno fatte sull insieme it.hasnext() e it.next() questi due sono i metodi degli iteratori: sono quelli che permettono di fare il ciclo (trova l elemento successivo, e verifica se ci sono elementi successivi) Iteratori e rimozione Se: si crea un iteratore con it=s.iterator() si modifica la lista con s.add oppure s.remove L iteratore diventa non più valido (non si può più usare) Quindi, dopo la modifica non si può più invocare it.hasnext() oppure it.next() Esercizio Eliminare tutti gli elementi di valore pari da un insieme di interi di interi Soluzione sbagliata Faccio il solito ciclo Quando trovo un elemento pari, lo elimino 7

static void eliminapari(hashset s) { Integer v; Iterator i; while(i.hasnext()) { v=(integer) i.next(); if(v.intvalue()%2==0) s.remove(v); Perchè non funziona? Modifiche e iteratori Dopo una modifica a un insieme, tutti i suoi iteratori diventano non validi Invocare un metodo su un iteratore non valido produce un errore Nel metodo di prima, dopo aver fatto s.remove(v), si proseguiva il ciclo, per cui venivano fatte le invocazioni i.hasnext() e i.next(), che producono un errore Prima soluzione corretta Ogni volta che viene invocato s.iterator() viene creato un nuovo iteratore Questo iteratore riparte dall inizio La soluzione: ogni volta che trovo un elemento pari, lo elimino e ricreo l iteratore static void eliminapari(hashset s) { Integer v; Iterator i; while(i.hasnext()) { v=(integer) i.next(); if(v.intvalue()%2==0) { s.remove(v); Seconda soluzione corretta Richiede due metodi verifica se ci sono elementi pari elimina un elemento pari (es. il primo che si incontra) 8

Intanto: implementare questi due metodi Verifica se ci sono elementi pari Solita cosa: ciclo su tutti gli elementi static boolean contienepari(hashset s) { Integer v; Iterator i; while(i.hasnext()) { v=(integer) i.next(); if(v.intvalue()%2==0) return true; Eliminazione di un elemento pari Solito ciclo: quando trovo un elemento pari lo elimino Dopo l eliminazione, esco static void eliminaunpari(hashset s) { Integer v; Iterator i; while(i.hasnext()) { v=(integer) i.next(); if(v.intvalue()%2==0) { s.remove(v); break; Attenzione: se invoco un metodo su i dopo una modifica, viene dato errore in esecuzione Verificare che non vengano fatte, per sbaglio, invocazioni di metodo sugli iteratori dopo una modifica Cosa ci faccio con questi due metodi? Domanda: ora che ho realizzato i due metodi, come faccio il metodo di eliminazione di tutti gli elementi? 9

Soluzione Devo seguire questo algoritmo: elimina un elemento pari elimina un elemento pari elimina un elemento pari elimina un elemento pari... Quando non ho più elementi pari, mi posso anche fermare Implementazione Per eliminare tutti gli elementi pari da un insieme: Finchè ci sono elementi pari, ne elimino uno static void eliminapari(hashset s) { while(contienepari(s)) eliminaprimopari(s); Metodo remove degli iteratori Elimina l elemento corrente (l ultimo che è stato ritornato da next) Dopo, l iteratore si può ancora usare Note: contrariamente al remove degli insiemi, non ha argomenti (l elemento da rimuovere è l ultimo ritornato da next) invalida tutti gli altri iteratori dello stesso insieme, tranne l iteratore su cui è invocato Esempio HashSet uninsieme, unaltro;... Iterator a=uninsieme.iterator(); Iterator b=uninsieme.iterator(); Iterator c=unaltro.iterator();... Object o=a.next(); a.remove(); Viene eliminato l oggetto o dall insieme uninsieme 10

Ora a si può ancora usare, mentre b (e tutti gli eventuali altri iteratori di s) non sono più validi Iteratori di altri insiemi sono ancora validi; in questo caso c è ancora valido Insiemi di oggetti arbitrari Si possono fare insiemi di Point, String, Integer, ecc. Se creo una nuova classe, come Studente, questa deve avere due metodi: equals confronta due oggetti hashcode dà un intero che viene usato dalla classe Metodo hashcode Vedremo poi perchè va messo Questo qui sotto funziona: class NomeClasse {... public int hashcode() { return 0; Nella classe devono essere presenti sia equals che hashcode! Cosa succede se non lo metto? Non viene dato nessun errore, nè in compilazione, nè in esecuzione Cosa cambia? con hashcode i metodi lavorano correttamente senza hashcode i metodi lavorano come se equals fosse quello di Object Senza hashcode, il metodo contains verifica se c è un oggetto == a quello passato, invece di verificare se c è un oggetto equals 11

Attenzione a equals! Ci vuole anche il metodo equals class Studente { String nome; int esami; double media; public String tostring() { return "["+this.nome+" "+ this.esami+" "+ this.media+"]"; public boolean equals(object o) { if(o==null) if(this.getclass()!=o.getclass()) Studente s; s=(studente) o; if(s.nome==null) { if(this.nome!=null) else if(!s.nome.equals(this.nome)) return ((s.esami==this.esami) && (s.media==this.media)); public int hashcode() { return 0; Un esempio complesso Aggiungere a Studente un metodo statico leggistudente che legge uno studente da un BufferedReader (ogni componente sta su una linea) Scrivere un metodo statico leggifile della classe Studente che legge un intero file, il cui nome viene passato come argomento, e resituisce un oggetto HashSet che contiene gli studenti letti Soluzione Dato che serve un HashSet, devo avere i metodi equals e hashcode: 12

class Studente { String nome; int esami; double media; public String tostring() { return "["+this.nome+" "+ this.esami+" "+ this.media+"]"; public boolean equals(object o) { if(o==null) if(this.getclass()!=o.getclass()) Studente s; s=(studente) o; return ((s.nome.equals(this.nome)) && (s.esami==this.esami) && (s.media==this.media)); public int hashcode() { return 0; // altri metodi Il metodo tostring va messo sempre, perchè è comodo Lettura di uno studente da file Il metodo prende come paramentro un BufferedReader Deve solo leggere tre linee, e convertirle se necessario Dato che uso i file, serve l import, e devo fare throws IOException import java.io.*; class Studente { // componenti e metodi static Studente leggistudente (BufferedReader b) throws IOException { Studente t; t=new Studente(); String s; s=b.readline(); if(s==null) return null; 13

t.nome=s; s=b.readline(); if(s==null) return null; t.esami=integer.parseint(s); s=b.readline(); if(s==null) return null; t.media=double.parsedouble(s); return t; Sembra lungo, ma fa solo questo: legge tre linee, per ogni linea controlla se vale null (e in questo caso, ritorna null), la converte se necessario, e la mette nell oggetto creato Perchè tornare null? Il metodo leggistudente ritorna null quando il file è finito Il metodo/programma che lo invoca, può vedere il valore di ritorno per capire se il file è finito Esempio: il metodo leggifile (prox pagina) usa questo fatto per capire quando non ci sono più oggetti da leggere Lettura di un HashSet Qui il parametro è il nome di un file Quindi, il FileReader e il BufferedReader vanno creati Dato che sono operazioni su file, bisogna mettere throws IOException Dato che serve il tipo HashSet, devo anche fare import java.util.*; import java.io.*; import java.util.*; class Studente { // componenti e altri metodi static HashSet leggifile(string nomefile) throws IOException { FileReader r=new FileReader(nomefile); BufferedReader b=new BufferedReader(r); HashSet h; h=new HashSet(); Studente s; while(true) { s=leggistudente(b); if(s==null) 14

break; h.add(s); return h; Si tratta soltanto di leggere oggetti Studente da file, e metterli nell insieme, fino a che non si legge un oggetto null Un programma di prova Leggere il file roma1.txt in un HashSet Stampare l insieme (un oggetto per linea) Contare quanti studenti hanno dato meno di cinque esami Stampare i dati dello studente Totti, se si trova nell insieme Soluzione Anche se non è richiesto: conviene fare un metodo per ognuna delle cose da fare Metodo di stampa: static void stampa(hashset s) { Iterator i; while(i.hasnext()) System.out.println(i.next()); Trovare studenti con pochi esami Metodo che trova gli studenti con meno di un certo numero di esami: static int contameno(hashset s, int quanti) { Iterator i; int conta=0; Studente q; while(i.hasnext()) { q=(studente) i.next(); if(q.esami<quanti) conta++; return conta; 15

Perchè il parametro quanti? È bene cercare di fare metodi generali, perchè si possono riusare In questo caso: l unica cosa che cambiava era che: if(q.esami<5) diventa if(q.esami<quanti) Se la differenza è piccola conviene cercare di scrivere metodi più generali Se la generalità comporta una complicazione, meglio il metodo non generale Stampa i dati di Totti Faccio un ciclo di scansione Se il nome dello studente è Totti, stampo tutto lo studente static void stampastudente(hashset s, String nome) { Iterator i; Studente q; while(i.hasnext()) { q=(studente) i.next(); if(q.nome.equals(nome)) System.out.println(q); Notare anche qui: fare un metodo generale comporta solo una piccola complicazione (un parametro in più, e poi la modifica della condizione dell if) Il metodo main Il programma completo è fatto cosí import java.util.*; import java.io.*; class ProvaStudente { // altri metodi public static void main(string args[]) throws IOException { HashSet tutti; tutti=studente.leggifile("roma1.txt"); stampa(tutti); System.out.println(contaMeno(tutti, 5)); stampastudente(tutti, "Totti"); 16

Notare che il metodo main invoca il metodo Studente.leggiFile che opera con file. Quindi, devo fare throws IOException In generale: se si presenta l errore di compilazione unreported exception..., basta aggiungere throws 17