Programmazione Parametrica ( a.k.a. Generics )

Slides:



Advertisements
Presentazioni simili
Dipartimento di Ingegneria Idraulica e Ambientale - Universita di Pavia 1 Caduta non guidata di un corpo rettangolare in un serbatoio Velocità e rotazione.
Advertisements

TAV.1 Foto n.1 Foto n.2 SCALINATA DI ACCESSO ALL’EREMO DI SANTA CATERINA DEL SASSO DALLA CORTE DELLE CASCINE DEL QUIQUIO Foto n.3 Foto n.4.
II° Circolo Orta Nova (FG)
1 Le s-espressioni. 2 Un nuovo esempio completo: le s-espressioni Sexpr 4 alberi binari (possibilmente vuoti) che hanno sulle foglie atomi (stringhe)
1 Progettazione gerarchica delle s- espressioni, utilizzando lereditarietà
1 Pregnana Milanese Assessorato alle Risorse Economiche Bilancio Preventivo P R O P O S T A.
Interfacce Java.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
1 Semantica Operazionale di un frammento di Java: lo stato.
11 TAVOLO TERRITORIALE DINTESA CRISI OCCUPAZIONALE TERRITORIO MANTOVANO 28 febbraio 2011 Sala del Consiglio.
Frontespizio Economia Monetaria Anno Accademico

1 Tavolo del Patto per la crescita intelligente, sostenibile e inclusiva Il ricorso agli ammortizzatori sociali nei territori colpiti dagli eventi sismici.
Numerazione in base tre Prof. Lariccia Giovanni Gruppo: Roberta Spicciariello, Roberta Accaria e Maria Elisa Graziano.
Heap binomiali.
Programmazione Parametrica ( a.k.a. Generics ). Introduzione ai meccanismi e concetti della programmazione parametrica Generics e relationi di sottotipo.
XXIV Congresso ACOI 2005 Montecatini Terme Maggio 2005
Virtual CPU - Eniac Dr.ssa Veronica Marchetti
Esempio: Tombola! Parte seconda.
Unified Modeling Language class C {…} class B extends C {…} Esiste una notazione grafica per mostrare le relazioni di ereditarietà. Object StringC B Tutte.
Sezione: Costruttori Costruttori. Definizione dei costruttori Se per una classe A non scrivo nessun costruttore, il sistema automaticamente crea il costruttore.
prompt> java SumAverage
1 struct Pila { private: int size; int defaultGrowthSize; int marker; int * contenuto; void cresci(int increment); public: Pila(int initialSize) ; Pila();
HDM Information Design notation v.4. HDM Information Design.
Ufficio Studi UNIONCAMERE TOSCANA 1 Presentazione di Riccardo Perugi Ufficio Studi UNIONCAMERE TOSCANA Firenze, 19 dicembre 2000.
1 Ultima Lezione del Corso di Fondamenti di Informatica 1 a.a – 06 Ma 29-Nov-2005.
1. Conoscere luso delle collezioni in Java Comprendere le principali caratteristiche nelle varie classi di Collection disponibili Saper individuare quali.
II ESONERO Modelli di Sistemi Biologici II 19/06/2007h12 A.9TEMA 1 1. Si illustri il metodo di stima dei parametri di popolazione a due stadi (TS) (8 pt)
6.6Ordinamento di Vettori Ordinamento di dati –Applicazione computazionale importante –Virtualmente ogni organizzazione deve ordinare dei dati Enormi quantità
Dipartimento di Ingegneria Idraulica e Ambientale - Universita di Pavia 1 Scritte scritte scritte scritte scritte scritte scritte Scritte scritte Titolo.
MP/RU 1 Dicembre 2011 ALLEGATO TECNICO Evoluzioni organizzative: organico a tendere - ricollocazioni - Orari TSC.
Capitolo OD.
2000 Prentice Hall, Inc. All rights reserved. 1 Capitolo 6: Classi e astrazione dati 1.Introduzione 2.Definizione delle strutture 3.Accedere ai membri.
Sottoprogrammi e Unità di Compilazione Nicola Fanizzi Laboratorio - Corso di Programmazione (B) C.d.L. in Informatica DIB - Università degli Studi di Bari.
1 laboratorio di calcolo II AA 2003/04 ottava settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza tel. ( )
Progetto di applicazioni grafiche. Disegno di forme complesse Prassi : un classe per ciascuna forma Progetta la forma individuando le componenti base.
Programmazione Parametrica ( a.k.a. Generics ). Introduzione ai meccanismi e concetti della programmazione parametrica Generics e relationi di sottotipo.
CALCIO SKY 2007 – 2008 PROFILO DI ASCOLTO. 2 INDICE DEGLI ARGOMENTI Profilo di ascolto CALCIO SERIE A 2007 – 2008 Totale campionato (tutte le partite)……………………………………………….
Analisi di Immagini e Dati Biologici
Compito desame del Svolgimento della Sezione 5: CONTROLLORI Esempio preparato da Michele MICCIO.
Java Collections.
QUESTIONARIO ALUNNI A.S.2008/09. MOTIVAZIONE SI A VOLTE NO I miei insegnanti mi spiegano bene 13957% % 1 0 % I miei insegnanti spiegano all'inizio.
2 3 4 RISERVATEZZA INTEGRITA DISPONIBILITA 5 6.
Melfi, 1 aprile 2011 – MediaShow 1 Social Network: possibilità di uso consapevole nella didattica Uso, consapevolezza, opportunità, proposte Caterina Policaro.
Pregare con i Salmi.
La Cooperativa Sociale Le Sagome nasce nel dicembre 2005, grazie ad un progetto finanziato in parte dal fondo sociale europeo, coordinato e guidato da.
1 Negozi Nuove idee realizzate per. 2 Negozi 3 4.
ORDINE DI CHIAMATA a 1minuto e 2 minuti PRINCIPALI TEMPI DELLA COMPETIZIONE ORDINE DI CHIAMATA a 1minuto e 2 minuti PRINCIPALI TEMPI DELLA COMPETIZIONE.
Scheda Ente Ente Privato Ente Pubblico. 2ROL - Richieste On Line.
1 Guida per linsegnamento nei corsi per il conseguimento del CERTIFICATO DI IDONEITÀ ALLA GUIDA DEL CICLOMOTORE.
Bando Arti Sceniche. Per poter procedere è indispensabile aprire il testo del Bando 2ROL - Richieste On Line.
24 aprile 2002 Avvisi: Risultati 1 o Esonero: (entro) lunedi 27 disponibili nella pag. WEB, ma anche esposti nella bacheca fuori dal corridoio 2 o dente,
Multiset. Progettare (specifica con identificazione delle eventuali astrazioni necessarie, incluse eccezioni, e implementazione) del tipo di dato Multiset,
1 Simulated multiple inheritance Sandro Pedrazzini Approfondimento Simulated multiple inheritance in Java.
1Piero Scotto - C14. Finalità del corso Programma Materiale Requisiti Spendibilità 2Piero Scotto - C14.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
Generazione Italia Osservatorio Roma, 26 Ottobre 2010.
1 Sky 2 Sky 3 Sky L’Universo Aperto La teoria del Big Bang prevede che, se la densità globale dell’universo non raggiunge un valore di Ωo (Omega Zero)
cursus Renaissance les 3.11 Vroege Renaissance de beeldende kunst Schilderkunst Schilderkunst Beeldhouwkunst Beeldhouwkunst Architectuur Architectuur.
Collection & Generics in Java
Fondamenti di informatica T-A Esercitazione 7 : Collezioni AA 2012/2013 Tutor : Domenico Di Carlo.
MA COME POSSO PARLARTI, MIO DIO ? Incontri biblici sui SALMI A cura di Antonella Jori Parrocchia di s. Ugo – Roma
Moles and Formula Mass.
1 Acceleratori e Reattori Nucleari Saverio Altieri Dipartimento di Fisica Università degli Studi - Pavia
Customer satisfaction anno 2013 Ospedale di Circolo Fondazione Macchi Varese Presentazione risultati (Febbraio 2014)
DIRETTIVI UNITARI SPI-CGI – FNP-CISL - UILP-UIL TERRITORIO LODIGIANO Lunedì 23 marzo 2015 dalle ore 9,00 alle ore 13,00 Presso la sala Conferenze Confartigianato.
ANNI POLIZZA 1 IMPORTO PREMIO UNICO INTERESSE NETTO ANNUO (%) TOTALE INTERESSI (€) POLIZZA 2 IMPORTO PREMIO ANNUO (INDICIZZATO) POLIZZA 3 IMPORTO PREMIO.
Fondamenti di informatica Oggetti e Java Luca Cabibbo Luca Cabibbo – Fondamenti di informatica: Oggetti e Java Copyright © 2004 – The McGraw-Hill Companies.
IL GIOCO DEL PORTIERE CASISTICA. Caso n. 1 Il portiere nella seguente azione NON commette infrazioni.
Collection & Generics in Java
Transcript della presentazione:

Programmazione Parametrica ( a.k.a. Generics )

Introduzione ai meccanismi e concetti della programmazione parametrica Generics e relationi di sottotipo wildcards generics e vincoli Implementazione di classi e metodi parametrici Supporto per i generics nella JVM

Programmazione polimorfa Polimorfo ~ multiforme, di molti tipi Programmazione polimorfa: creazione di costrutti (classi e metodi) che possono essere utilizzati in modo uniforme su dati di tipo diverso In Java, tradizionalmente ottenuta mediante i meccanismi di sottotipo ed ereditarietà Da Java 1.5. anche mediante i meccanismi di parametrizzazione di tipo (a.k.a. generics)

Variabili di Tipo Le variabili (o parametri) di tipo pemettono di creare astrazioni di tipo Classico caso di utilzzo nelle classi “Container” E = variabile di tipo astrae (e rappresenta) il tipo delle componenti public class ArrayList<E> { public ArrayList() { . . . } public void add(E element) { . . . } . . . } Continua

Variabili di Tipo Possono essere istanziate con tipi classe o interfaccia Vincolo: tipi che istanziano variabili di tipo non possono essere primitivi (devono essere tipi riferimento) Classi wrapper utili allo scopo ArrayList<BankAccount> ArrayList<Measurable> ArrayList<double> // No! ArrayList<Double>

Variabili di tipo e controlli di tipo Utilizzare variabili di tipo nella programmazione permette maggiori controlli sulla correttezza dei tipi in fase di compilazione Aumenta quindi la solidità e robustezza del codice Continua

Variabili di tipo e controlli di tipo Un classico caso di utilizzo di containers Il cast è problematico, per vari motivi verboso, fonte di errori a run time Ma necessario per la compilazione e per localizzare l’eventuale errore a run time List intList = new LinkedList(); intList.add(new Integer(0)); Integer x = (Integer) intList.get(0); Continua

Variabili di tipo e controlli di tipo Container generici: più sintetici ed eleganti Compilatore può stabilire un invariante sugli elementi della lista garantire l’assenza di errori a run-time in forza di quell’invariante. List<Integer> intList = new LinkedList<Integer>(); intList.add(new Integer(0)); Integer x = intList.get(0); Continua

Variabili di tipo e controlli di tipo Ora non è possibile aggiungere una stringa ad intlist:List<Integer> Le variabili di tipo rendono il codice parametrico più robusto e semplice da leggere e manutenere List<Integer> intList = new LinkedList<Integer>(); intList.add(new Integer(0)); Integer x = intList.get(0);

Classi parametriche: definizione Un frammento delle interfacce List e Iterator nel package java.util.* // nulla di particolare, a parte i parametri // tra parentesi angolate public interface List<E> { void add(E x); Iterator<E> iterator(); } public interface Iterator<F> F next(); boolean hasNext(); Nulla di speciale, a parte la presenza dei parametri di tipo

Classi parametriche: uso Quando utilizziamo un tipo parametrico, tutte le occorrenze dei parametri formali sono rimpiazzate dall’argomento (parametro attuale) Meccanismo simile a quello del passaggio dei parametri in un metodo Diversi usi generano tipi diversi Ma . . . classi parametriche compilate una sola volta danno luogo ad un unico file .class Nulla di speciale, a parte la presenza dei parametri di tipo

Sintassi: uso GenericClassName<Type1, Type2, . . .> Esempio:   ArrayList<BankAccount> HashMap<String, Integer> Scopo: Fornire tipo specifici per ciascuna delle variabili di tipo introdotte nella dichiarazione

Esempio: Pair<T,S> Una semplice classe parametrica per rappresentare coppie di oggetti public class Pair<T, S> { public Pair(T firstElement, S secondElement) { first = firstElement; second = secondElement; } public T getFirst() { return first; } public S getSecond() { return second; } private T first; private S second; } Continua

Esempio: Pair<T,S> Una semplice classe parametrica per rappresentare coppie di oggetti: I metodi getFirst e getSecond restituiscono il primo e secondo elemento, con i tipi corrispondenti Pair<String, BankAccount> result = new Pair<String, BankAccount> ("Harry Hacker", harrysChecking); String name = result.getFirst(); BankAccount account = result.getSecond();

Variabili di tipo: convenzioni Variabile Significato Inteso E Tipo degli elementi in una collezione K Tipo delle chiavi in una mappa V Tipo dei valori in una mappa T,S,U Tipi generici

Esempio: LinkedList<E> public class LinkedList<E> { . . . public E removeFirst() { if (first == null) throw new NoSuchElementException(); E element = first.data; first = first.next; return element; } . . . private Node first; private class Node { E data; Node next; } } Continua

Esempio: LinkedList<E> Notiamo la struttura della classe ausiliaria che specifica la struttura dei nodi Se la classe è interna, come in questo caso, non serve alcun accorgimento all’interno di Node possiamo utilizzare il tipo E, il cui scope è tutta la classe Se invece la classe è esterna, dobbiamo renderla generica

Esempio: LinkedList<E> class Node<F> { F data; Node next; } public class LinkedList<E> { . . . public E removeFirst() { if (first == null) throw new NoSuchElementException(); E element = first.data; first = first.next; return element; } . . . private Node<E> first; } Continua

Generics e sottotipi I meccanismi di subtyping si estendono alle classi generiche C<T> <: I<T> per qualunque T Analogamente: C<T> <: I per qualunque T Sembra tutto facile, MA . . . class C<T> implements I<T> { . . . } class C<T> implements I { . . . }

Generics e sottotipi Consideriamo La prima istruzione è legale, la seconda è più delicata … Number è una classe che ha Integer , Double e altre classi wrapper come sottotipi Per capire se la seconda istruzione sia da accettare come legale continuiamo con l’esempio … List<Integer> li = new ArrayList<Integer>(); List<Number> ln = li; Continua

Generics e sottotipi Come si vede abbiamo un problema List<Integer> li = new ArrayList<Integer>(); List<Number> ln = li; // type error ln.add(3.14); Integer i = li.get(0); // uh oh ... Come si vede abbiamo un problema nella terza istruzione inseriamo un Double nella quarta estraiamo un Integer ! Il vero problema è nella seconda istruzione soluzione: errore di compilazione per l’assegnamento Continua

Generics e sottotipi In generale, dati due tipi A e B , ed tipo generico C<T> abbiamo che: Quindi, per le stesse ragioni di prima Come abbiamo visto questo è necessario per garantire la correttezza A ≤ B NON implica C<A> ≤ C<B> Set<Integer> NON è sottotipo di Set<Object> Continua

A ≤ B NON implica C<A> ≤ C<B> Generics e sottotipi In generale, dati due tipi A e B , ed tipo generico C<T> abbiamo che: MA … A ≤ B NON implica C<A> ≤ C<B> A ≤ B implica A[] ≤ B[] Continua

Generics e sottotipi Integer[] ai = new Integer[10] Number[] an = ai; // type OK an[0] = 3.14; // ArrayStoreException Integer i = ai[0]; // uh oh ... Continua

Generics e sottotipi Le limitazione sulle relazioni di sottotipo sono contro-intuitive uno degli aspetti più complessi dei generics Non solo … sono spesso anche troppo restrittive illustriamo con un esempio Continua

Generics e sottotipi Stampa degli elementi di una collezione Primo tentativo Inutile per stampare gli elementi di una generica Collection<T> Collection<Object> non è il supertipo di tutte le collezioni static void printCollection(Collection<Object> c) { for (Object e:c) System.out.println(e); } Continua

Wildcards Stampa degli elementi di una collezione Secondo tentativo Collection<?> è il supertipo di tutte le Collections la wildcard ? indica un qualche tipo, non specificato static void printCollection(Collection<?> c) { for (Object e:c) System.out.println(e); } Continua

Wildcards Possiamo estrarre gli elementi di c al tipo Object Corretto perché, qualunque sia il loro vero tipo, sicuramente è sottotipo di Object void printCollection(Collection<?> c) { for (Object e:c) System.out.println(e); } Continua

Wildcards D’altra parte … Poichè non sappiamo esattamente quale tipo indica ?, non possiamo inserire elementi nella collezione In generale, non possiamo modificare valori che hanno tipo ? Collection<?> c = new ArrayList<String>(); c.add(new String()); // errore di compilazione! Continua

Domanda Date un esempio di codice che causerebbe errore in esecuzione se permettessimo di aggiungere elementi a Collection<?>

Risposta Collection<Integer> ci = new ArrayList<Integer>; Colletion<?> c = ci; c.add(“a string”); // non compila ci.get(0).intValue(); L’ultima istruzione invocherebbe intValue() sul primo elemento di ci ma quell’elemento ha tipo String … Il compilatore previene l’errore, rigettando la add()

Wilcards con vincoli (bounded) Shapes: (again!) interface Shape { public void draw(Graphics g); } class Circle extends Shape private int x, y, radius; public void draw(Graphics g) { ... } class Rectangle extends Shape private int x, y, width, height; Continua

Wilcards con vincoli (bounded) Graphics e il metodo draw() Solito problema: drawAll() non può essere invocato su una List<Circle> public class Graphics { // disegna una shape public void draw(Shape s) { s.draw(this); } // disegna tutte le shapes di una lista public void drawAll(List<Shape> shapes) { for (Shape s:shapes) s.draw(this) } . . . Continua

Bounded Wilcards Quello che ci serve è un metodo che accetti liste di qualunque (sotto) tipo di Shape List<? extends Shape> bounded wildcard indica un tipo sconosciuto, sottotipo di Shape il bound può essere qualunque tipo riferimento (classe o interfaccia) Ora il metodo ha la flessibilità necessaria e desiderata void drawAll(List<? extends Shape> shapes) { ... } Continua

Bounded Wilcards Graphics e il metodo draw() public class Graphics { // disegna una shape public void draw(Shape s) { s.draw(this); } // disegna tutte le shapes di una lista public void drawAll(List<? extends Shape> shapes) for (Shape s:shapes) s.draw(this) } . . . Continua

Bounded Wilcards Attenzione: c’è sempre un prezzo da pagare Non possiamo modificare strutture con questi tipi [ perché? ] void addRectangle(List<? extends Shape> shapes) { // errore di compilazione shapes.add(new Rectangle()); }

Metodi Generici Metodi che dipendono da una variabile di tipo Possono essere definiti all’interno di qualunque classe, generica o meno N.B. Evitiamo List<Object> perché renderebbe il metodo non utilizzabie su liste arbitrarie /* trasforma un array in una lista, copiando * tutti gli elementi di a in l */ static void array2List(Object[] a, List<?> l){ . . . } Continua

Metodi Generici Al solito però . . . . . . non possiamo aggiungere elementi ad una struttura (o modificare) con elementi di tipo wildcard /* trasforma un array in una lista, copiando * tutti gli elementi di a in l */ static void array2List(Object[] a, List<?> l) { for (Object o : a) l.add(o) // compiler error } Continua

Metodi Generici Soluzione: rendiamo il metodo parametrico possiamo invocare questo metodo con una qualunque lista il cui tipo sia supertipo del tipo base dell’array purché sia un tipo riferimento /* trasforma un array in una lista, copiando * tutti gli elementi di a in l */ static <T> void array2List(T[] a, List<T> l) { for (T o : a) l.add(o) }

Invocazione di metodi generici Nell’invocazione di un metodo generico non è necessario passare l’argomento di tipo il compilatore inferisce il tipo, se esiste, dai tipi degli argomenti del metodo

Invocazione di metodi generici Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); fromArrayToCollection(oa, co); // T = Object (inferito) String[] sa = new String[100]; Collection<String> cs = new ArrayList<String>(); fromArrayToCollection(sa, cs); // T = String (inferito) fromArrayToCollection(sa, co); // T = Object (inferito) Integer[] ia = new Integer[100]; Float[] fa = new Float[100]; Number[] na = new Number[100]; Collection<Number> cn = new ArrayList<Number>(); fromArrayToCollection(ia, cn); // T = Number (inferito) fromArrayToCollection(fa, cn); // T = Number (inferito) fromArrayToCollection(na, cn); // T = Number (inferito) fromArrayToCollection(na, co); // T = Object (inferito) fromArrayToCollection(na, cs); // compiler error Continua

Wildarcds vs variabili di tipo Ci sono situazioni in cui è possibili usare equivalentemente wildcards e variabili di tipo. Nella libreria Collection troviamo interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); public boolean addAll(Collection<E> c); . . . } Continua

Wildarcds vs variabili di tipo Queste specifiche possono essere espresse equivalentemente con metodi parametrici Il secondo metodo è parametrico in qualunque sottotipo di E i bounds si possono utilizzare anche con variabili, non solo con wildcards interface Collection<E> { public <T> boolean containsAll(Collection<T> c); public <T extends E> boolean addAll(Collection<T> c); . . . } Continua

Wildarcds vs variabili di tipo Wildcards e variabili di tipo possono coesistere Notiamo la dipendenza tra i tipi dei due parametri: il tipo della sorgente deve essere un sottotipo del tipo della destinazione interface Collection<E> { public static <T> void copy(List<T> dest, List<? extends T> src) . . . } Continua

Wildarcds vs variabili di tipo Potremmo analogamente riformulare in modo da evitare le wildcards Come scegliere tra le due soluzioni? interface Collection<E> { public static <T, S extends T> void copy(<List<T> dest, List<S> src) . . . } Continua

Wildarcds vs variabili di tipo In generale, preferiamo le wildcards quando entrambe le soluzioni sono possibili Possiamo darci la seguente “rule of thumb” se una variabile di tipo ha una unica occorrenza nella specifica di un metodo e il tipo non è il target di un operazione di modifica utilizziamo una wildcard al posto della variabile

Generics e “erasure” I tipi generici sono significativi a compile-time La JVM opera invece con tipi “raw” Il tipo raw è ottenuto da un tipo generico mediante un processo detto erasure che rimuove le variabili di tipo il bycode generato da un tipo generico è lo stesso che viene generato dal corrispondente tipo raw.

Generics e “erasure” Generano lo stesso bytecode List<String> words = new ArrayList<String>(); words.add(“hi”); words.add(“there”); String welcome = words.get(0) + words.get(1); List words = new ArrayList(); words.add(“hi”); words.add(“there”); String welcome = (String)words.get(0) + (String)words.get(1);

Generics e “erasure” Cast-iron guarantee i cast impliciti che vengono aggiunti dalla compilazione di codice generico non falliscono mai.

Generics e Array Non è possibile creare array generici Ecco perché: class MyClass<T> { T[] contents = new T[100]; // Non compila public void showTheProblem() { Object[] objs = contents; objs[0] = new String(); // no ArrayStoreException T bump = contents[0]; // ClassSclassException }

Variabili di Tipo e Bounds Abbiamo visto che possiamo definire bounds anche per variabili di tipo (non solo wildcards) Un caso paradigmatico public static <T extends Comparable<T>> T max(Collection<T> coll) { T candidate = coll.iterator().next(); for (T e : coll) if candidate.compareTo(e) < 0) candidate = e; return candidate; }

Variabili di Tipo e Bounds Il bound su una variabile impone vincoli sulla variabile, determinando quali metodi possono essere utilizzati su valori del tipo variabile Qui il bound è ricorsivo: informa che i valori con cui operiamo forniscono un metodo compareTo() che gli argomenti del metodo devono essere dello stesso tipo dei valori public static <T extends Comparable<T>> T max(T max(List <T> coll)

File LinkedList.java 019: /** 019: /** 020: Returns the first element in the linked list. 021: @return the first element in the linked list 022: */ 023: public E getFirst() 024: { 025: if (first == null) 026: throw new NoSuchElementException(); 027: return first.data; 028: } 029: 030: /** 031: Removes the first element in the linked list. 032: @return the removed element 033: */ 034: public E removeFirst() 035: { Continua

File LinkedList.java 036: if (first == null) 037: throw new NoSuchElementException(); 038: E element = first.data; 039: first = first.next; 040: return element; 041: } 042: 043: /** 044: Adds an element to the front of the linked list. 045: @param element the element to add 046: */ 047: public void addFirst(E element) 048: { 049: Node newNode = new Node(element,first); 052: first = newNode; 053: } Continua

File LinkedList.java 054: 055: /** 055: /** 056: Returns an iterator for iterating through this list. 057: 058: */ 059: public ListIterator<E> listIterator() 060: { 061: return new LinkedListIterator(); 062: } 063: 064: private Node first; 065: 066: private class Node 067: { 068: E data; 069: Node next; 070: } 071: Continua

LinkedListIterator La definiamo come classe interna di LinkedList<E> Implemental’interfaccia ListIterator<E> Ha accesso al campo first e alla classe interna Node

Classe LinkedListIterator 072: private class LinkedListIterator implements ListIterator<E> 073: { 074: /** 075: Costruisce un iteratore posizionato sul primo 076: elemento della lista 077: */ 078: public LinkedListIterator() 079: { 080: last = null; // ultimo nodo visitato 081: previous = null; // precedente a position 082: } 083: Continua

LinkedListIterator – next() 084: /** 085: Posizione l’iteratore sul prossimo. 086: @return il prossimo elemento 087: */ 088: public E next() 089: { 090: if (!hasNext()) 091: throw new NoSuchElementException(); 092: previous = last; // Remember for remove 093: 094: if (last == null) 095: last = first; 096: else 097: last = last.next; 098: 099: return last.data; 100: } 101: 102: Continua

LinkedListIterator – hasNext() 102: /** 103: Testa se c’è un elemento dopo l’ultimo 104: visitato. 105: @return true se esiste un elemento dopo 106: l’ultimo visitato 107: */ 108: public boolean hasNext() 109: { 110: if (last == null) 111: return first != null; 112: else 113: return last.next != null; 114: } 115: 116: Continua

LinkedListIterator – add() 117: /** Aggiunge un elemento dopo last e sposta 118: l’iteratore sul prossimo elemento. 119: */ 121: public void add(E element) 122: { 123: if (last == null) 124: { 125: addFirst(element); last = first; 127: } 128: else 129: { 130: Node newNode = new Node(); 131: newNode.data = element; 132: newNode.next = last.next;// (1) 133: last.next = newNode; // (2) 134: last = newNode; // (3) 135: } 136: previous = last; // (4) 137: } Continua

LinkedListIterator – add() last

LinkedListIterator – remove() 140: /** Rimuove l’elemento puntato da last. Può essere 141: invocato solo dopo una chiamata a next() 142: */ 143: public void remove() 144: { 145: if (previous == last) 146: throw new IllegalStateException(); 147: 148: if (last == first) 149: { 150: removeFirst(); 151: } 152: else 153: { 154: previous.next = last.next; // (1) 155: } 156: last = previous; // (2) 157: } Continua

LinkedListIterator –remove() last

Classe LinkedListIterator 159: /** 160: Sets the last traversed element to a different 161: value. 162: @param element the element to set 163: */ 164: public void set(E element) 165: { 166: if (position == null) 167: throw new NoSuchElementException(); 168: position.data = element; 169: } 170: 171: private Node position; 172: private Node previous; 173: } // end LinkedListIterator 174: } // end LinkedList

File ListIterator.java 01: /** 02: A list iterator allows access of a position in a linked 03: list. This interface contains a subset of the methods 04: of the standard java.util.ListIterator interface. The 05: methods for backward traversal are not included. 06: */ 07: public interface ListIterator<E> 08: { 09: /** 10: Moves the iterator past the next element. 11: @return the traversed element 12: */ 13: E next(); 14: 15: /** 16: Tests if there is an element after the iterator 17: position. Continua

File ListIterator.java 18: @return true if there is an element after the iterator 19: position 20: */ 21: boolean hasNext(); 22: 23: /** 24: Adds an element before the iterator position 25: and moves the iterator past the inserted element. 26: @param element the element to add 27: */ 28: void add(E element); 29: 30: /** 31: Removes the last traversed element. This method may 32: only be called after a call to the next() method. 33: */ Continua

File ListIterator.java 34: void remove(); 35: 36: /** 37: Sets the last traversed element to a different 38: value. 39: @param element the element to set 40: */ 41: void set(E element); 42: }