MultiSet, Liste Ordinate

Slides:



Advertisements
Presentazioni simili
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
Advertisements

29 febbraio 2008 Progettare tipi di dato astratti.
Liste di Interi Esercitazione. Liste Concatenate Tipo di dato utile per memorizzare sequenze di elementi di dimensioni variabile Definizione tipicamente.
Le gerarchie di tipi.
Esercitazione Frame. Argomento Realizzazione di un tipo di dato astratto Usare le eccezioni per segnalare situazioni particolari Invariante e funzione.
LIP: 19 Aprile Contenuto Soluzione Compitino Tipo di dato MultiSet, estensione con sottoclasse.
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
PolyFun. Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
Liste Ordinate 3 Maggio Ultima Lezione Abbiamo visto i tipi di dato astratti IntList e StringList Realizzano liste di interi e di stringhe Realizzati.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
1 Le gerarchie di tipi. 2 Supertipi e sottotipi 4 un supertipo –class –interface 4 può avere più sottotipi –un sottotipo extends il supertipo ( class.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.
Multiset. Progettare (specifica con identificazione delle eventuali astrazioni necessarie, incluse eccezioni, e implementazione) del tipo di dato Multiset,
Astrazione procedurale ed eccezioni
Polimorfismo Significato Significato Varie famiglie Varie famiglie Polimorfismo in java Polimorfismo in java Polimorfismo di Sottotipo: Apparato in Java.
1 Un esempio con iteratore: le liste ordinate di interi.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 7 Tipi di dato e strutture dati Specifica e realizzazione di strutture informative come classi.
Astrazione di dati Dati Astratti: cosa e perchè Dati Astratti: due meccanismi differenti Dati Astratti: due meccanismi differenti Astrazione e incapsulamento.
1 Astrazioni polimorfe. 2 Perché il polimorfismo 4 non vogliamo definire versioni differenti dell’astrazione corrispondente ad una collezione di elementi.
Astrazione di dati Esercizio 1. Si completi l’implementazione Poly.add data a lezione con la specifica e l’implementazione degli ausiliari min e max data.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterarare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Liste di Interi Esercitazione. Una variante Liste concatenate di Integers Non modificabile Costruttori per creare la lista vuota o un nodo Metodi d’istanza.
Primo Compitino Primo esercizio Identificare gli errori segnalati dal compilatore Verifica statica del codice Regole di binding per i nomi (quelle.
1 Progettazione dettagliata di un Tipo di Dato Astratto: l’ambiente di metodi.
Ripasso su Java. Introduzione Per risolvere problemi complessi, i linguaggi di programmazione forniscono costrutti per realizzare nuove funzioni che trasformino.
Liste di Interi Esercitazione. IntList Lista di interi Problema tipico: memorizzare una sequenza di valori [6,0,9,3….9] Vediamo un tipo di dato utile.
Compitino del 2004 Alberi Generici. Idea Si vuole un tipo di dato astratto che definisca una struttura ad albero in cui nodi e foglie hanno associato.
Liste Concatenate 11 Aprile E’ una delle strutture dati fondamentali in tutti i linguaggi di programmazione di alto livello Una Lista Concatenata.
Liste di Interi Esercitazione. IntList Lista di interi Una lista è una disposizione ordinata di elementi ( non in modo crescente-descrescente, ma per.
Si dia la specifica del tipo di dato astratto Tabella.Una Tabella ha due colonne e un numero variabile di righe. Gli elementi della prima colonna sono.
1 Gerarchie e polimorfismo: liste. 2 Generalizzare le liste di interi  List 4 lista di oggetti –non modificabile 4 vorremo poi definire un sottotipo.
Esercitazione Object, Vettori, Liste. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo lo.
1 Laboratorio di Introduzione alla Programmazione §II MODULO §3 crediti §Esame e voto unico (su 6 crediti totali)
1 Astrazione sul controllo: gli iteratori. 2 Gli iteratori 4 perché vogliamo iterarare “in modo astratto” 4 iteratori e generatori in Java –specifica.
LIP: 9 Maggio Esercizi Riprendiamo un esercizio proposto Definire un tipo di dato Persona che definisce oggetti che rappresentano le informazioni.
1 Progettare un Tipo di Dato Astratto. 2 Scelte di Progetto (astrazione) 4 Caratteristiche degli oggetti –Modificabilità 4 Scelta delle operazioni –Realizzare.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
1 Un esempio: le liste ordinate di interi. 2 Liste ordinate  OrderedIntList 4 lista ordinata di interi –modificabile.
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterarare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
Ese 3 (del 31 Marzo 2004). Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare.
LIP: 22 Marzo 2005 Eccezioni. Eccezioni-Richiami Come si definiscono eccezioni Come si lanciano Come si gestiscono (gestione esplicita o di default)
1 Le s-espressioni. 2  Sexpr 4 alberi binari (possibilmente “vuoti”) che hanno sulle foglie atomi (stringhe) 4 sono la struttura dati base del linguaggio.
Esercizio 3. Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare i commenti.
PolyFun. Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti.
LIP: 2 Maggio 2008 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays.
Esercitazione. Problema Vogliamo definire in modo gerachico un tipo di dato che definisce Tabelle multi-dimensionali con un numero di righe variabili.
Primo Compitino Terzo Esercizio Implementare il tipo di dato astratto Table un oggetto di tipo Table ha due colonne e un numero variabile di righe.
Progettare una classe 21 Febbraio La classe BankAccount Vogliamo realizzare una classe i cui oggetti sono dei semplici conti bancari. * Identifichiamo.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
Ese 1 e 3 (del 6 Aprile 2005). Primo Ese Si identifichino gli errori che il compilatore segnalerebbe per il seguente programma Tipi Legami tra dichiarazioni.
Alcune Classi Standard Object, Vettori. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
LIP: 11 Maggio 2007 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
Esercitazione 14 Marzo Esercizio dell’altra volta Definire un tipo di dato Abbonato i cui oggetti descrivono le informazioni relative ad un abbonato.
Esercitazione del 9 marzo 2007 Ereditarieta’. Richiami Definire sottoclassi (ereditarieta’) Overriding Specificatori di accesso (private, protected) Principio.
Liste Concatenate 28 Marzo Avviso Martedi’ 4 Aprile: Verifica di LIP Per iscriversi (obbligatorio) inviare un e- mail entro venerdi’ 31 Marzo a.
1 Astrazioni polimorfe. 2 Perché il polimorfismo 4 Abbiamo visto come si definiscono insiemi di stringhe, insiemi di interi, insiemi di caratteri, etc.
1 Un esempio con iteratore: le liste ordinate di interi.
LIP: 4 Maggio 2007 Interfacce. Cos’e’ una Interfaccia una interfaccia e’ un particolare tipo di classe contiene solo la specifica non ha implementazione.
LIP: 15 Marzo 2005 Vettori di interi. Esercizio proposto Definire una classe VectorInt i cui oggetti sono vettori omogenei di interi ordinati in modo.
LIP: 18 Aprile 2008 Interfacce. Rappresentazione Lista val next vuota Lista vuota: any true Lista non vuota: any true 154 false 24 false.
Ex.1 - Astrazioni su Dati Si abbia il tipo di dato stack di interi, IntStack, specificato sotto: public class IntStack { \\ OVERVIEW: uno Stack è una collezione.
Sommario cos’è un tipo di dato astratto astrazione tramite specifica:
Transcript della presentazione:

MultiSet, Liste Ordinate Esercizi MultiSet, Liste Ordinate

Progettare specifica ed implementazione (e relativa invariante ed astrazione) del tipo di dato Multiset, multiinsieme di dati del medesimo tipo. In aggiunta al costruttore si abbiano come operazioni primitive: inserimento, rimozione, ricerca. Insieme: collezione di elementi, non esiste il concetto di numero di occorrenze (Ex. {1,7,8}) Multiinsieme: collezione di elementi, che possono occorrere zero o piu’ volte (Ex. {1,7,8,7,1,1}). Le operazioni aggiungono e rimuovono una occorrenza

Si progetti poi il tipo di dato MaxMultiset che estende Multiset fornendo un metodo che ritorna il valore che rappresenta la massima molteplicità degli elementi del multiinsieme. {1,1,3,5,5,5} e’ 3 Provare che i metodi realizzati soddisfano l'invariante e la loro specifica. Discutere il principio di sostituzione

Specifica Multiset public class Multiset { //OVERVIEW: un Multiset e' un insieme di elementi omogenei in //cui ogni elemento puo' occorrere piu' volte, es. {1,5,4,1,4}. //E' modificabile //metodi public Multiset () { //EFFECTS: inizializza this al multiinsieme vuoto public int isin(Object x) { //EFFECTS: restituisce il numero di occorrenze di x (0 se non compare)

Specifica public void insert(Object x) throws NullPointerException, ClassCastException { //EFFECTS: se x e' null solleva NullPointerException, se x non e' omogeneo //agli elementi di this solleva ClassCastException, altrimenti inserisce un’occorrenza di x in this //MODIFIES: this} public void remove(Object x){ //EFFECTS: rimuove una occorrenza di x da this //MODIFIES: this

Specifica public Iterator elements(){ //EFFECTS: restituisce un generatore che restituisce //gli elementi di this, fornendo per ogni elemento, el //ed il numero di occorrenze} Si vuole che restuisca (1,3) se appaiono 3 occorrenze di 1, e non 1, 1, 1 Tipo ausiliario Pair

Implementazione La scelta fondamentale e’ quella della rappresentazione deve permettere di implementare i metodi in modo efficiente Deve permettere la definizione di sottoclassi (possibilmente senza rende accessibile la rappresentazione)

Una possibilita’ Utilizzare un vettore come per l’insieme Differenza: occorrenze multiple Non molto efficiente: metodo IsIn [1,6,8,6,8,1,1] rappresenta {1,6,8,6,8,1,1}

Implementazione Vettore di coppie (valore, numero di occorrenze) Tipo record ausiliario Pair, due variabili d’istanza left e right di tipo Object e int, che contengono l’oggetto ed il numero di occorrenze (molteplicita’) Piu’ efficiente isIn (rispetto al caso in cui inserisco gli elementi direttamente nel vettore)

Insieme omogeneo Manteniamo in una variabile di tipo Class il tipo del primo oggetto inserito (si usa getClass()) Nota: una variabile di tipo Class prende come valori tutti I tipi (gli posso assegnare direttamente Integer, String…vedi costruttore che prende il tipo)

La rappresentazione La variabile type memorizza il tipo public class Multiset { //OVERVIEW: un Multiset e' un insieme di elementi omogenei in //cui ogni elemento puo' occorrere piu' volte, es. {1,5,4,1,4}. //E' modificabile private Vector els; private Class type; La variabile type memorizza il tipo Il vettore els memorizza le coppie Quali devono essere le loro proprieta’ ? L’ invariante esprime le proprieta’ delle due variabili d’istanza che servono a garantire la correttezza

Invariante IMultiset(c) = c.els  null & (c.els.size()>0  c.type  null) & i,j 0  ij < c.els.size() ( c.els.get(i) e’ un Pair & c.els.get(i).left.getClass()=c.type & c.els.get(i).right>0 & c.els.get(i).left  c.els.get(j).left Le ultime condizioni vietano casi tipo: (a,3),(b,1),(b,3) o (c,0) Rendono l’implementazione piu’ efficiente

Funzione di astrazione: mappa in multiinsiemi aMultiset(c) = S tale c.els.get(i).left occorre c.els.get(i).right volte in S i:0i<c.els.size() mappa un MultiSet in un multiinsieme: (a,3),(b,1)------> {a,a,a,b}

Metodi Pair q=(Pair) els.get(i); if (x.equals(q.left)) { public Multiset (){ //EFFECTS: inizializza this al multiinsieme vuoto {els=new Vector();} public int isIn(Object x){ //EFFECTS: ritorna il numero di occorrenze di x in //this, eventualmente o {if (x==null} {return 0;} for (int i=0; i<els.size(); i++) { Pair q=(Pair) els.get(i); if (x.equals(q.left)) { return q.right;}} return 0;}

Correttezza Soddisfano l’invariante (banale) Soddisfano la specifica? Notiamo per isIn sono necessarie le proprieta’ dell’invariante, che garantisce che non ci siano situazioni tipo (a,3),(b,1),(b,3) Altrimenti potrebbe riportare per b una sola occorrenza

Insert 1 public void insert(Object x) throws NullPointerException, ClassCastException { //EFFECTS: se x e' null solleva NullPointerException, se x non e' omogeneo //agli elementi di this solleva ClassCastException, altrimenti inserisce un’occorrenza di x in this //MODIFIES: this if (x==null) throw NullPointerException(" "); if (els.size()==0) type=x.getClass(); else { if (!type.isinstance(x)) throw ClassCastException(" "); } ………………………… poi inserisce Prima effettua la verifica del tipo, se e’ vuoto inizializza il tipo con quello di x, tramite getclass Preserva l’invariante (per quanto riguarda l’omogeneita’) Solleva l’eccezione in accordo alla specifica

Insert 2 Preserva l’invariante e soddisfa la specifica ………. if (isin(x)==0) { Pair p=new Pair(x,1); els.add(p); } else { for (int i=0; i<els.size(); i++) { Pair q=(Pair) els.get(i); if (x.equals(q.left)) { q.right++;} } Preserva l’invariante e soddisfa la specifica Inserisce l’elemento rispettando i vincoli dell’invariante Se non c’era crea una nuova coppia Altrimenti aggiorna la molteplicita’ nella coppia che manteneva le occorrenze di x

Remove public void remove(Object x) { //EFFECTS: rimuove un'occorrenza di x da this //MODIFIES: this if (isin(x)==0) return; for (int i=0; i<els.size(); i++) { Pair p=(Pair) els.get(i); if (x.equals(p.left)) { p.right--; if (p.right=0) {els.remove(i); }} }

Commenti a remove Preserva l’invariante e soddisfa la specifica Elimina l’elemento rispettando i vincoli dell’invariante Se c’era decrementa il numero di occorrenze Se sono zero rimuove proprio la coppia L’invariante non ammette (a,0) (piu’ efficiente)

Classe Multiset, Iterator elements public Iterator elements() { //EFFECTS: restituisce un generatore che produce gli elementi // del multiinsieme this nella forma di coppie //(elemento,molteplicita') return new MultisetGen(this); } L’iteratore e’ facile da progettare perche’ la rappresentazione e’ adeguata

Classe MultisetGen private static class MultisetGen implements Iterator { //OVERVIEW: restituisce come Pair tutte le coppie (element0, // molteplicita’) del multiinsieme che le viene passato private Multiset set; \\ il multinsieme private int current; \\ prossimo elemento //metodi public MultisetGen(Multiset m) { //EFFECTS: inizializza set a m e current a 0 set=m; current=0; }

Classe MultisetGen public boolean hasnext() { //EFFECTS: se ci sono ancora elementi nel multiinsieme // da generare ritorna true, altrimenti false return (current<set.els.size()); } public Object next() throws NoSuchElementException { //EFFECTS: restituisce il prossimo elemento del // multiinsieme se ce ne sono, altrimenti solleva // un'eccezione if (current=set.els.size()) throw NoSuchElementException; int loc=current; current++; return set.els.get(loc); } }

Funzione di astrazione e invariante aMultisetGen(c) = [c.set.els.get(current), ……..,c.set.els.get(c.set.els.size()-1) ] IMultisetGen(c) = 0  c.current <= c.set.els.size()

Sottoclasse Estende col metodo maxmul, ritorna la molteplicita’ massima presente nell’insieme Si puo’ implementare col generatore (ad ogni chiamata scorre gli elementi e trova il massimo) Si puo’ mettere una variabile d’istanza e mantenerla aggiornata (tramite l’overriding di insert e remove)

In ogni caso La rappresentazione della superclasse e’ mascherata Vantaggio: il codice delle sottoclassi e’ indipendente da quello della superclasse Facciamo vedere la seconda soluzione: sfrutta la gerarchia

Classe MaxMultiset, metodo maxmul public class MaxMultiset extends Multiset{ //OVERVIEW: un MaxMultiset e' un Multiset che mantiene traccia della massima molteplicita' dei suoi elementi private int max; //metodi public MaxMultiset () { //EFFECTS: inizializza this al MaxMultiSet vuoto {super(); max=0; } public int maxmul() { //EFFECTS: restituisce il valore della molteplicita' massima return max; }

Aggiorna il massimo (l’elemento inserito Overriding di Insert public void insert (object x) throws NullPointerException, ClassCastException { //EFFECTS: aggiunge una occorrenza di x in this //MODIFIES: this super.insert(x); int numero=isIn(x); if (numero>max) {max=numero;} } Aggiorna il massimo (l’elemento inserito potrebbe avere ora la molteplicita’ max) Le post condizioni sono uguali

Le post condizioni sono uguali Se x aveva il numero max di occorrenze, Overriding di Remove public void remove (object x) { //EFFECTS: rimuove una occorrenza di x da this //MODIFIES: this int numero=isIn(x); super.remove(x); if (numero < max) {return;} else {aggiornamax();} } Le post condizioni sono uguali Se x aveva il numero max di occorrenze, lo devo ricalcolare

Classe MaxMultiset, metodo aggiornamax private void aggiornamax() { //EFFECTS: aggiorna la molteplicita' massima //MODIFIES: this max=0; Iterator g = elements(); while (g.hasnext()) { Pair p = (Pair)g.next(); if (p.right()>max) max =p.right; }

Funzione di astrazione e invariante aMaxMultiset(c) = aMultiset(c) IMaxMultiset(c) = c.max  0 & c.max>0 xaMultiset(c)|x occorre c.max volte & xaMultiset(c) la molteplicita' di x e'  c.max E l’invariante della superclasse?

Commenti Nel progetto della superclasse deve essere previsto come si puo’ estendere (accesso diretto o metodi) Abbiamo fornito il generatore alle possibili sottoclassi per mantenere la rappresentazione privata Alternativa rappresentazione della superclasse protected (accesso diretto) Piu’ efficiente, ma la sottoclasse diventerebbe dipendente dall’implementazione della superclasse Inoltre la correttezza sarebbe piu’ complessa: la sottoclasse potrebbe invalidare la correttezza della superclasse (potrebbe violarne l’invariante)

Consiglio Le soluzioni migliori (piu’ efficienti e\o ben strutturate) sono piu’ complicate: piu’ condizioni nell’invariante, nei metodi bisogna fare attenzione a piu’ proprieta’ (per esempio a non inserire (a,8),(a,1)) Cercate di non scegliere la via piu’ facile *solo* per fare prima

Altro Esercizio Problema: vogliamo progettare un tipo di dato Lista Ordinata Generica In grado di memorizzare interi, stringhe etc…, ognuno con il relativo ordinamento Bisogna essere parametrici rispetto al tipo degli elementi e anche rispetto alla relativa nozione di ordinamento Due approcci basati sull’uso delle interfacce

Primo Approccio: element subtype definiamo l’interfaccia I che definisce le proprietà richieste (in questo caso l’ordinamento), Comparable definiamo il tipo di dato (in questo caso la lista) con elementi di tipo I (Comparable) definiamo gli oggetti come sottotipi dell’interfaccia I

La classe OrderedList Generalizza OrderedIntList Permette di definire liste piu’ generali, che hanno come elementi, sottotipi dell’interfaccia Comparable specifica e implementazione simili a quelle di OrderedIntList solo che argomenti e risultati delle operazioni sono Comparable invece che int l’ordinamento è fatto usando compareTo

La classe OrderedList Possiamo usarlo solo per memorizzare liste ordinate di elementi sottotipi di Comparable, ovvero che implementano l’interfaccia fornendo il metodi compareTo String, Integer Nuovi tipi predefiniti

Esempio Supponiamo di volere mantenere ordinate delle coppie di interi Ordinamento richiesto: in modo crescente in base al primo elemento, se il primo elemento e’ uguale in base al secondo in ordine crescente Ex: [(1,2),(1,3),(2,1,),(2,4),(4,1)]

Per usare OrderedList E’ pero’ necessario definire a priori le coppie di interi come sottotipo di Comparable public class IPair implements Comparable{ //OVERVIEW: sono coppie di interi su cui e’ definito un ordine // totale public int left; \\ il primo elemento public int right;\\ il secondo elemento public IPair(int x,int y){right=x,left=y;} public int compareTo (Object x) throws ClassCastException, NullPointerException { …….verifica se this e’ minore o uguale o maggiore di x secondo l’ordinamento descritto in precedenza tra coppie

Per usare OrderedList public int compareTo (Object x) throws ClassCastException, NullPointerException { IPair y=(IPair) x; if (left < x.left) {return -1}; if (x.left < left) {return 1}; else {if (right < x.right) {return -1}; if (x.right < rigth) {return 1};} return 0;}

Esempio di uso IPair p= new IPair (1,3); IPair q=new IPair (2,4); OrderedList l=new OrderedList(); l.add(p); l.add(q); l.toString(); Ritorna la lista ordinata (come String): [(1,3),(2,4)] I metodi di OrderedList usano compareTo per ordinare gli oggetti, in questo caso quello fornito dal tipo di dato IPair

Svantaggi Definendo il tipo IPair come sottotipo di Comparable le coppie hanno direttamente la relativa operazione di ordinamento (implementata da compareTo) E se avessi gia’ definito un tipo Pair che rappresenta le coppie di interi ma non implementa Comparable? Si puo’ definire un tipo di dato “polimorfo” OrderedList che funziona anche per tipi pre-esistenti?

Alternativa OrderedList Ha come elementi Object Il confronto e’ fatto usando il metodo compare, fornito da una interfaccia Comparator (anche questa pre-definita in Java) L’implementazione dell’interfaccia viene passata come parametro al costruttore e memorizzata per usare la relativa nozione di ordinamento Per usare la lista per un certo tipo di dato T basta definire (anche a posteriori) l’implementazione di Comparator relativa a T

L’interfaccia Comparator public interface Comparator { // OVERVIEW: tutti i sottotipi di Comparator forniscono //metodi per confontare gli elementi di un “tipo // collegato” public int compare (Object x, Object y) throws NullPointerException, ClassCastException; // EFFECTS: se uno tra x o y è null, solleva // NullPointerException; se x e y non sono // confrontabili solleva ClassCastException; altrimenti, // se x è minore di y ritorna -1; se y = x ritorna 0; //se x è maggiore di y, ritorna 1 }

Come usare OrderedList? Vogliamo fare una lista ordinata di Pair (pre-definito) Pair non implementa direttamente l’interfaccia Comparator non hanno incluso l’ordinamento Dobbiamo invece definire un ’implementazione di Comparator, collegata a Pair, che realizza il confronto tra coppie (quello richiesto) Dobbiamo passare ad OrderedList l’ implementazione di Comparator, collegata a Pair

Esercizio Definire il sottotipo di Comparator, PairComparator che realizza il confronto tra le coppie Se i parametri passati a compare non sono coppie deve sollevare ClassCastException, non sono confrontabili (basta usare il cast)

public class PairCompator implements Comparator { // OVERVIEW: definisce un sottotipo di Comparator relativo //al tipo Pair public int compare (Object x, Object y) throws NullPointerException, ClassCastException{ // EFFECTS: se uno tra x o y è null, solleva // NullPointerException; se x e y non sono // confrontabili solleva ClassCastException; altrimenti, // se x è minore di y ritorna -1; se y = x ritorna 0; //se x è maggiore di y, ritorna 1 if (x==null || y==null) throw new NullPointerException(); Pair p1= (Pair) x; Pair p2=(Pair) y; if (p1.left < p2.left) {return -1}; if (p1.left < p2.left) {return 1}; else {if (p1.right < p2.right) {return -1}; if (p1.right < p2.rigth) {return 1};} return 0;} }

Specifica di OrderedList public class OrderedList { // OVERVIEW: `e una lista modificabile ordinata // e omogenea di Object. // Oggetto tipico [x1, . . . , xn] con xi < xj se // i < j. Il confronto fra gli elementi è // effettuato con il metodo compare di una // interfaccia Comparator relativa // costruttore public OrderedList (Comparator c ) // EFFECTS: inizializza this alla lista // ordinata vuota che ha elementi del tipo //collegato c

Specifica di OrderedList 2 // metodi public void addEl (Object el) throws NullPointerException, DuplicateException, ClassCastException { // MODIFIES: this // EFFECTS: se el è in this, solleva //DuplicateException; se el è null solleva //NuIlPointerException; se el non è confrontabile //con gli altri elementi in this solleva //ClassCastException; altrimenti, aggiunge el a this} public void remove (Object el) { // EFFECTS: se el è in this, lo rimuove altrimenti, //non fa nulla}

Specifica di OrderedList 2 // metodi public Object first() throws EmptyException { // EFFECTS: se el è vuota solleva EmptyException, altrimenti restituisce il primo elemento} public OrederedList next() throws EmptyException { // EFFECTS: se el è vuota solleva EmptyException, altrimenti restituisce resto della lista} public boolean IsIn (Object el) { // EFFECTS: se el è in this restituisce true, //altrimenti false }

Implementazione public class OrderedList { private Object val; private boolean vuota; private OrderedList next; private Comparator conf; public OrderedList (Comparator c ) { vuota=true; conf=c;}

Invariante e funzione di astrazione Funzione di astrazione: la solita Invariante: I(c)= c.conf!=null e !c.vuota =====> (c.next e c.val!=null e c.conf.compare(c.val,c.val) non solleva ecc. e c.conf=c.next.conf e I(c.next) e c.conf.compare( c.val,c.next.val ) <0 )

Implementazione public void addEl (Object el) throws NullPointerException,DuplicateException, ClassCastException { if (el==null) throw new NullPointerException(“”); if (vuota){int n=conf.compare(el,el); val=el; vuota=false; next=new OrderedList(conf);} else {int n=conf.compare(val,el); if (n==0) throw new DuplicateException(“”); if (n <0) {next.addEl(el);} {OrderedList l=new OrderedList(conf); l.val=val;l.vuota=vuota; l.next=next; l.conf=conf; val=el;next=l;} }}

Implementazione public void remove (Object el) { if (vuota) return; int n=conf.compare(val,el); if (n==0) { if (next.vuota) {vuota=true;} else {val=next.val; vuota=next.vuota; next=next.next;} } else {next.remove(el);

Implementazione di OrderedList public Object first() throws EmptyException { if (vuota) throw new Emptyexception(“first”); return val; } public OrederedList next() throws EmptyException { return next; public boolean IsIn (Object el) { if (vuota) return false; in n= conf.compare(val,el); if (n==0) return true; else return next.IsIn(el);}

Differenza rispetto all’altro metodo Per confrontare el con l’elemento del vettore chiama il metodo compare del Comparator int n=conf.compare(o,el); Per confrontare el con l’elemento del vettore chiama il metodo compareto sull’elemento (sono Comparable) int n=o.compareto(el); Nel primo approccio gli elementi non hanno direttamente il metodo di confronto (glielo passo col Comparator relativo) Nel secondo approccio gli elementi hanno direttamente il metodo di confronto (implementano Comparable)

Differenza nell’uso IPair p= new IPair (1,3); //sottotipo di Comparable IPair q=new IPair (2,4); OrderedList l=new OrderedList(); l.add(p); l.add(q); //ordina con compareTo l.toString(); Pair p= new Pair (1,3); Pair q=new Pair (2,4); OrderedList l=new OrderedList(new PairComparator()); l.add(p); l.add(q); //ordina con compare Ritorna la lista ordinata (come String): [(1,3),(2,4)]