Oppdatert 30. september 2016
Det skal leveres en fil (navn: DobbeltLenketListe.java
) som inneholder klassen
public class DobbeltLenketListe<T> implements Liste<T>
.
Grensesnittet Liste
er det som er satt opp
Avsnitt 3.2.1
i kompendiet (og skal ikke følge med i løsningen).
Pass på at alle metodene dine er testet og at de behandler alle spesialtilfellene
korrekt (se testprogrammet).
Det er ok at det under arbeidet med å lage metodene legges
inn utskriftssetninger for testing i metodene. Men de SKAL FJERNES når obligen
leveres inn. Klassen DobbeltLenketListe
skal heller ikke ha noen main-metode når den leveres inn.
En gruppe på opp til og med 5 studenter kan levere en felles løsning. Filen
DobbeltLenketListe.java
sendes som vedlegg til en e-post til Ulf.Uttersrud@hioa.no
. Den skal
ikke «pakkes ned» som en zip-fil eller lignende. Den skal være som en
vanlig java-fil (dvs. i tekstformat).
Skriv navn og studentnummer øverst på filen. Hvis det er en gruppe
som leverer, må det stå navn og studentnummer på alle i gruppen.
Skriv også navn og studentnummer
i e-posten. Tilbakemelding om det ble godkjent eller ikke blir sendt til e-postens
avsender. En oversikt over hvem som har fått godkjent oblig 2 vil til slutt komme på
siden godkjente obliger.
Huskeliste før du sender inn løsningen:
DobbeltLenketListe.java
?class DobbeltLenketListe
fjernet?OBS: Hvis det som leveres inn som 2. oblig ikke blir godkjent, vil en få det i retur med krav om at det må forbedres. Med andre ord får en flere sjanser.
Oppgaven:
En toveis liste (dobbelt lenket) har et hode og en hale. Hode peker til den første noden og hale til den siste slik som denne figuren viser:
![]() |
En node har både en forrige-peker og en neste-peker. Neste-peker i den siste noden og forrige-peker i den første noden er begge null.
Nedenfor står et skjelett av klassen
DobbeltLenketListe
og dens metoder. Et par av dem er kodet.
I de øvrige kastes det en UnsupportedOperationException
som signal om at de ikke er kodet.
Det gjør at kompilatoren ikke gir noen feilmeldinger. Alle disse skal kodes.
Klassen inneholder instansvariablene antall
og endringer
.
Variabelen antall
skal økes med 1 for hver innlegging og reduseres med 1 for hver fjerning.
Variabelen endringer
skal økes med 1 for hver endring i listen
(innlegging, oppdatering, fjerning, nullstill). Dvs. for alle mutatorer. Hensikten med
endringer
tas opp i forbindelse med kodingen av iteratoren.
Arbeidet, kodingen og testingen bør skje i flg. rekkefølge:
Oppgave 0
Flytt grensesnittene
Beholder
,
Liste
og skjelettet til klassen DobbeltLenketListe
over til deg selv og legg dem i samme mappe (package) (Beholder
og Liste
skal ikke følge med når
du sender inn løsningen din). Lag deretter et main-program med flg. kode og sjekk at det ikke gir noen syntaks- eller
kjørefeil (runtime error). Hvis du legger main-programmet i en annen klasse, slipper du å fjerne det når filen
DobbeltLenketListe.java
skal sendes inn:
Liste<String> liste = new DobbeltLenketListe<>();
Klassen DobbeltLenketListe
er generisk. I koden kan det derfor hende at det må gjøres
typekonverteringer (eng: casting). Slike konverteringer kan i verste fall føre til
kjørefeil (runtime error). De som bruker Eclipse får advarsler (warnings) der det kan være mistenklige
konverteringer. De som bruker NetBeans skal gå inn på Tools|Options|Editor|Hints|Standard Javac Warnings og
hake av Raw Types og Unchecked. Så Apply og Ok. I IntelliJ er det sikkert noe lignende. Hvis en får en advarsel,
må en rette opp det som er mistenkelig eller bruke en annotasjon hvis en er sikker på
at det en gjør er korrekt (legg til @SuppressWarnings("unchecked")).
Hvis en f.eks. bruker kode som: Node<T> p = new Node(verdi);
så skal en normalt få en advarsel om
«raw type». Korrekt kode er: Node<T> p = new Node<>(verdi);
Det samme hvis
en har: Node p = new Node<>(verdi);
Også der skal det være:
Node<T> p = new Node<>(verdi);
Oppgave 1
Lag metodene int antall()
og
boolean tom()
.
Den første skal returnere antallet verdier i listen og
den andre skal returnere true/false avhengig av om listen er tom eller ikke. Sjekk så at flg. programbit gir rett utskrift:
Liste<String> liste = new DobbeltLenketListe<>(); System.out.println(liste.antall() + " " + liste.tom()); // Utskrift: 0 true
Lag så konstruktøren public DobbeltLenketListe(T[] a)
. Den skal lage
en dobbeltlenket liste med verdiene fra tabellen a. Verdiene skal ligge i samme rekkefølge i listen som i tabellen.
Hvis a
er null, skal det kastes en
NullPointerException
med teksten "Tabellen a er null!" (bruk f.eks. en requireNonNull
-metode fra klassen Objects
).
Hvis a
inneholder en eller flere
null-verdier, skal de ikke tas med. Dvs. at listen skal inneholde de verdiene fra a
som ikke er null.
Hvis alle verdiene i a
er null, får vi en tom liste.
Her må du passe på at hode
peker til den første i listen og hale
til den siste. Pass også på at neste
og forrige
er satt riktig i alle noder. Spesielt skal både hode.forrige
og hale.neste
være null. Pass også på at hvis tabellen a har kun én verdi som ikke er null (listen får da én node),
så vil hode
og hale
peke til samme node. Hvis a er tom (lengden er 0), skal
det ikke opprettes noen noder og dermed at
hode
og hale
fortsatt er null (dvs. en tom liste).
Variabelen endringer
skal være 0.
Her kan det være fristende å bygge opp listen ved gjentatte kall på metoden leggInn()
(den skal kodes i
Oppgave 2). Men konstruktøren skal kodes direkte (uten bruk av leggInn()
).
F.eks. vil NetBeans gi advarselen «Overridable method call in constructor» hvis
leggInn()
brukes i en konstruktør. Det kommer sikkert noe tilsvarende i Eclipse og IntelliJ. Årsaken er
at hvis en senere skal lage en subklasse av DobbeltLenketListe
og overskriver (overrides) leggInn()
, så
kan det føre til at konstruktøren ikke lenger virker som den skal.
Sjekkliste for konstruktøren DobbeltLenketListe(T[])
:
NullPointerException
?
Det er så langt ikke enkelt å få testet om konstruktøren lager en korrekt toveisliste. Det kan først gjøres når
metodene toString()
og omvendtString()
er ferdiglaget i
Oppgave 2. Men flg. programbit skal i hvert fall gi rett utskrift:
String[] s = {"Ole", null, "Per", "Kari", null}; Liste<String> liste = new DobbeltLenketListe<>(s); System.out.println(liste.antall() + " " + liste.tom()); // Utskrift: 3 false
Oppgave 2
a) Lag først metoden String toString()
. Den
skal returnere en tegnstreng med listens verdier. Hvis listen f.eks. inneholder
tallene 1, 2 og 3, skal metoden returnere strengen "[1, 2, 3]" og kun "[]" hvis listen er tom.
Du skal bruke en StringBuilder
(eller en StringJoiner
) til å bygge opp tegnstrengen og verdiene
i listen finner du ved å traversere fra hode til hale ved hjelp av neste-pekere.
Lag så metoden String omvendtString()
. Den skal returnere en tegnstreng på samme form
som den toString()
gir, men verdiene skal komme i omvendt rekkefølge. Her skal du finne verdiene i omvendt rekkefølge
ved å traversere fra hale til hode ved hjelp av forrige-pekere. Hensikten med omvendtString()
er
å kunne sjekke at forrige-pekerne er satt riktig.
Sjekk at flg. programbit gir rett utskrift (forutsetter at Oppgave 1 er ferdig):
String[] s1 = {}, s2 = {"A"}, s3 = {null,"A",null,"B",null}; DobbeltLenketListe<String> l1 = new DobbeltLenketListe<>(s1); DobbeltLenketListe<String> l2 = new DobbeltLenketListe<>(s2); DobbeltLenketListe<String> l3 = new DobbeltLenketListe<>(s3); System.out.println(l1.toString() + " " + l2.toString() + " " + l3.toString() + " " + l1.omvendtString() + " " + l2.omvendtString() + " " + l3.omvendtString()); // Utskrift: [] [A] [A, B] [] [A] [B, A]
b) Lag metoden boolean leggInn(T verdi)
.
Null-verdier er ikke tillatt. Start derfor med en sjekk
(bruk en requireNonNull
-metode fra klassen Objects
).
Innleggingsmetoden skal legge en ny node med oppgitt verdi
bakerst i
listen og returnere true. Her må du skille mellom to tilfeller: 1) at listen på forhånd er tom og 2) at den ikke
er tom. I en tom liste skal både hode og hale være null (og antall lik 0). I tilfelle 1)
skal både hode og hale etter innleggingen
peke på den nye noden (både forrige-peker og neste-peker i noden skal da være null). I tilfelle 2)
er det kun hale-pekeren som skal endres etter innleggingen. Pass da på at forrige-peker og neste-peker
i den nye noden og i den noden som oppprinnelig lå bakerst, får korrekte verdier.
Husk at antallet må økes etter en innlegging. Det samme
med variablen endringer
. Metoden skal returnere true
.
Sjekkliste for metoden leggInn(T verdi)
:
NullPointerException
?Sjekk så at flg. programbit gir rett utskrift:
DobbeltLenketListe<Integer> liste = new DobbeltLenketListe<>(); System.out.println(liste.toString() + " " + liste.omvendtString()); for (int i = 1; i <= 3; i++) { liste.leggInn(i); System.out.println(liste.toString() + " " + liste.omvendtString()); } // Utskrift: // [] [] // [1] [1] // [1, 2] [2, 1] // [1, 2, 3] [3, 2, 1]
Oppgave 3
a) Lag den private hjelpemetoden
Node<T> finnNode(int indeks)
.
Den skal returnere noden med den gitte indeksen/posisjonen.
Hvis indeks er mindre enn antall
/2, så skal letingen etter
noden starte fra hode og gå mot høyre ved hjelp av neste-pekere. Hvis ikke, skal
letingen starte fra halen og gå mot venstre ved hjelp av forrige-pekere. Lag deretter metoden
public T hent(int indeks)
ved å bruke finnNode()
. Pass på at
indeks
sjekkes. Bruk metoden indeksKontroll()
som arves fra
Liste
(bruk false
som parameter).
Lag også metoden T oppdater(int indeks, T nyverdi)
.
Den skal erstatte verdien på plass indeks
med nyverdi
og returnere det som
lå der fra før. Husk at indeks må sjekkes, at null-verdier ikke skal kunne legges inn
og at variabelen endringer
skal økes.
b) Lag metoden Liste<T> subliste(int fra, int til)
. Den
skal returnere en liste (en instans av klassen DobbeltLenketListe
) som inneholder verdiene fra
intervallet [fra:til> i «vår» liste. Her må det først sjekkes om indeksene
fra
og til
er lovlige. Hvis ikke, skal det kastes unntak
slik som i metoden
fratilKontroll()
.
Legg defor den inn som en privat metode i klassen
DobbeltLenketListe
og bytt ut ArrayIndexOutOfBoundsException
med IndexOutOfBoundsException
siden vi ikke har noen tabell (array) her. Bytt også ut
ordet tablengde
med ordet antall
. Denne kontrollmetoden kan da kalles
med antall
,
fra
og til
som argumenter. Husk at et tomt intervall er lovlig. Det
betyr at vi får en tom liste.
Pass på at variablen antall
i den listen som metoden subliste()
returnerer,
får korrekt verdi. Variablen endringer
skal være 0. Her kan alle metoder brukes - også
leggInn()
.
Sjekk så at flg. programbit gir rett utskrift:
Character[] c = {'A','B','C','D','E','F','G','H','I','J',}; DobbeltLenketListe<Character> liste = new DobbeltLenketListe<>(c); System.out.println(liste.subliste(3,8)); // [D, E, F, G, H] System.out.println(liste.subliste(5,5)); // [] System.out.println(liste.subliste(8,liste.antall())); // [I, J] // System.out.println(liste.subliste(0,11)); // skal kaste unntak
Oppgave 4
Lag metoden int indeksTil(T verdi)
.
Den skal returnere indeksen/posisjonen til verdi
hvis den finnes i listen
og returnere -1 hvis den ikke finnes. Her skal det ikke kastes unntak hvis verdi
er null
. Metoden skal isteden returnere -1. Det er logisk siden null
ikke finnes i listen.
Hvis verdi
forekommer flere ganger,
skal indeksen til den første av dem (fra venstre) returneres.
Lag så metoden boolean inneholder(T verdi)
.
Den skal returnere true hvis listen inneholder verdi
og returnere false ellers.
Her lønner det seg å bruke et kall på metoden indeksTil
som en del av koden.
Oppgave 5
Lag metoden void leggInn(int indeks, T verdi)
.
Den skal legge verdi
inn i listen slik at den får indeks/posisjon indeks.
Husk at negative indekser og indekser større enn antall er ulovlige (indekser fra og med 0 til og med antall er lovlige).
Her må du
passe på de fire tilfellene 1) listen er tom, 2) verdien skal legges først, 3) verdien skal legges bakerst
og 4) verdien skal legges mellom to andre verdier. Sørg for at neste- og forrige-pekere
får korekte verdier i alle noder. Spesielt skal forrige-peker i den første noden være
null og neste-peker i den siste noden være null.
Sjekkliste for leggInn(int indeks, T verdi)
:
NullPointerException
?antall
økt?endringer
økt?Oppgave 6
Lag de to fjern-metodene, dvs.
T fjern(int indeks)
og
boolean fjern(T verdi)
. Den første
skal fjerne (og returnere) verdien på posisjon indeks
(som først må sjekkes). Den andre skal fjerne
verdi
fra listen og så returnere true. Hvis det er flere forekomster av verdi
er det den første av dem (fra venstre) som skal fjernes. Hvis verdi
ikke er i listen, skal metoden returnere false. Her skal det ikke kastes unntak hvis verdi
er null
. Metoden skal isteden returnere false. Det er logisk siden null
ikke finnes i listen. Begge metodene skal være så effektive som mulig. Her kan det være fristende å kode
fjern(T verdi)
ved hjelp av indeksTil(T verdi)
og fjern(int indeks)
.
Men det fører til to gjennomganger av listen og er dermed ineffektivt. Derfor skal fjern(T verdi)
kodes direkte.
I begge metodene må du passe på tilfellene 1) den første
fjernes, 2) den siste fjernes og 3) en verdi mellom to andre fjernes. Alle neste- og forrige-pekere
må være korrekte etter fjerningen. Variabelen antall
skal også reduseres og
variabelen endringer
økes.
Sjekk også tilfellet at listen blir tom etter fjerningen,
blir korrekt behandlet. Bruk metodene toString()
og omvendtString()
til å sjekke at alle pekerne er satt riktig.
Sjekkliste for fjern
-metodene:
antall
redusert?endringer
økt?Oppgave 7
Lag metoden void nullstill()
. Den skal «tømme»
listen og nulle alt slik at «søppeltømmeren» kan hente alt som ikke lenger brukes.
Kod den på to måter og velg den som er mest effektiv (gjør tidsmålinger):
1 måte: Start i hode
og gå mot hale
ved hjelpe pekeren neste
.
For hver node «nulles» nodeverdien og alle nodens pekere. Til slutt settes både hode
og
hale
til null, antall
til 0 og endringer
økes. Hvis du er i tvil
om hva som det bes om her, kan du slå opp i kildekoden for metoden clear()
i klassen LinkedList
i Java.
2. måte: Lag en løkke som inneholder metodekallet fjern(0)
(den første noden fjernes) og som går inntil listen er tom
Oppgave 8
Metoden boolean hasNext()
og konstruktøren public DobbeltLenketListeIterator()
i klassen DobbeltLenketListeIterator
er ferdigkodet og skal ikke endres.
a) Lag metoden T next()
.
Den skal først sjekke om iteratorendringer
er lik
endringer
. Hvis ikke,
kastes en ConcurrentModificationException
. Så en NoSuchElementException
hvis det ikke er flere igjen i listen (dvs. hvis hasNext()
ikke er sann/true). Deretter settes fjernOK
til sann/true, verdien
til denne
returneres og denne
flyttes til den neste node.
b) Lag metoden
Iterator<T> iterator()
.
Den skal returnere en instans av iteratorklassen.
c) Lag konstruktøren private DobbeltLenketListeIterator(int indeks)
.
Den skal sette pekeren denne
til den noden som hører til den oppgitte indeksen. Resten skal
være som i den konstruktøren som er ferdigkodet.
d) Lag til slutt metoden
Iterator<T> iterator(int indeks)
.
Det må først sjekkes at indeksen er lovlig. Bruk metoden indeksKontroll()
.
Deretter skal den ved hjelp av konstruktøren i punkt c) returnere en instans av iteratorklassen.
Nå vil default
-metoden
void forEach(Consumer<? super T> handling)
i grensesnittet Iterable
virke. En vanlig forAlle-løkke bruker implisitt en iterator.
Sjekk at flg. kode virker for deg:
String[] navn = {"Lars","Anders","Bodil","Kari","Per","Berit"}; Liste<String> liste = new DobbeltLenketListe<>(navn); liste.forEach(s -> System.out.print(s + " ")); System.out.println(); for (String s : liste) System.out.print(s + " "); // Utskrift: // Lars Anders Bodil Kari Per Berit // Lars Anders Bodil Kari Per Berit
Oppgave 9
a) Lag metoden void remove()
i iteratorklassen.
Her kan du ikke bruke noen av de ordinære
fjern-metodene. For det første vet vi ikke hvilken indeks det er snakk om her og for det andre
kan verdien som skal fjernes, forkomme flere steder og dermed kan gal verdi bli fjernet. Her
må remove()
kodes direkte.
Hvis det ikke er tillatt å kalle denne metoden, skal det kastes en IllegalStateException.
Hvis endringer
og
iteratorendringer
er forskjellige,
kastes en Concurrent-ModificationException.
Hvis disse hindrene passeres, settes
fjernOK
til usann/false. Så skal noden rett til venstre for p fjernes.
Den finner vi lett siden det går en peker dit. Her må en passe på alle tilfellene.
antall == 1
), så nulles
hode og hale.denne == null
), så må hale
oppdateres.denne.forrige == hode
), så må hode
oppdateres.denne.forrige
),
så må pekerne i nodene på hver side oppdateres.
Til slutt
reduseres antall
og både endringer
og
iteratorendringer
økes.
Metoden boolean fjernHvis(Predicate<? super T> sjekk)
er en default
-metode i grensesnittet Beholder
. Den vil virke så sant metoden
remove()
i iteratorklassen er kodet på en korrekt måte. Her er et eksempel på hvordan den kan brukes.
Sjekk at det virker. Lag
så for din egen del et predikat som gjør at de navnene som inneholder e fjernes. Og så et der kun de navnene som
innholder 5 bokstaver blir igjen.
DobbeltLenketListe<String> liste = new DobbeltLenketListe<>(new String[] {"Birger","Lars","Anders","Bodil","Kari","Per","Berit"}); liste.fjernHvis(navn -> navn.charAt(0) == 'B'); // fjerner navn som starter med B System.out.println(liste + " " + liste.omvendtString()); // Utskrift: [Lars, Anders, Kari, Per] [Per, Kari, Anders, Lars]
Oppgave 10
Lag public static <T> void sorter(Liste<T> liste, Comparator<? super T> c)
.
Den skal sortere liste
ved hjelp av komparatoren c
. Siden parametertypen
for liste
er Liste<T>
, vil det kun være de metodene som står grensesnittet
Liste
som
kan brukes. Her vil det selvfølgelig være fristende å kopiere alle verdiene over i en tabell, sortere tabellen og så
kopiere dem tilbake i listen. Men oppgaven skal løses uten bruk av hjelpestrukturer. Dvs. det skal være en såkalt
«på plass»-sortering (eng: in place).
Målet er å få metoden til å virke (at den sorterer korrekt). Det er det eneste som testprogrammet undersøker. Men selv om det er umulig å lage en effektiv «på plass»-sortering i en lenket liste, er det jo likevel et poeng å ikke lage koden unødvendig ineffektiv. Det vil være mulig å finne ut hvilken orden metoden din har ved en analyse. Men du kan få en indikasjon ved hjelp av tidsmålinger. Lag en liste med med så mange tilfeldige verdier at metoden f.eks. bruker ca. 1 sekund. Lag så en som har dobbelt så mange verdier. Hvis tidsforbruket da blir ca. 4 sekunder, kan metoden din være av kvadratisk orden. Bruken den ca. 8 sekunder, er den kanskje av kubisk orden.
Argumentet liste
i metoden sorter()
vil være en instans av en klasse som
implementerer grensesnittet Liste
.
Det betyr at også instanser av TabellListe
og EnkeltLenketListe
vil bli sortert av denne metoden. Hvis du har en eller
begge av disse klassene tilgjengelig, vil flg. kodebit vise hvordan metoden skal virke:
String[] navn = {"Lars","Anders","Bodil","Kari","Per","Berit"}; Liste<String> liste1 = new DobbeltLenketListe<>(navn); Liste<String> liste2 = new TabellListe<>(navn); Liste<String> liste3 = new EnkeltLenketListe<>(navn); DobbeltLenketListe.sorter(liste1, Comparator.naturalOrder()); DobbeltLenketListe.sorter(liste2, Comparator.naturalOrder()); DobbeltLenketListe.sorter(liste3, Comparator.naturalOrder()); System.out.println(liste1); // [Anders, Berit, Bodil, Kari, Lars, Per] System.out.println(liste2); // [Anders, Berit, Bodil, Kari, Lars, Per] System.out.println(liste3); // [Anders, Berit, Bodil, Kari, Lars, Per] // Tabellen navn er upåvirket: System.out.println(Arrays.toString(navn)); // [Lars, Anders, Bodil, Kari, Per, Berit]
/////////// DobbeltLenketListe ////////////////////////////////////
import java.util.Comparator; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Objects; public class DobbeltLenketListe<T> implements Liste<T> { private static final class Node<T> // en indre nodeklasse { // instansvariabler private T verdi; private Node<T> forrige, neste; private Node(T verdi, Node<T> forrige, Node<T> neste) // konstruktør { this.verdi = verdi; this.forrige = forrige; this.neste = neste; } protected Node(T verdi) // konstruktør { this(verdi, null, null); } } // Node // instansvariabler private Node<T> hode; // peker til den første i listen private Node<T> hale; // peker til den siste i listen private int antall; // antall noder i listen private int endringer; // antall endringer i listen // hjelpemetode private Node<T> finnNode(int indeks) { throw new UnsupportedOperationException("Ikke laget ennå!"); } // konstruktør public DobbeltLenketListe() { hode = hale = null; antall = 0; endringer = 0; } // konstruktør public DobbeltLenketListe(T[] a) { throw new UnsupportedOperationException("Ikke laget ennå!"); } // subliste public Liste<T> subliste(int fra, int til) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public int antall() { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public boolean tom() { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public boolean leggInn(T verdi) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public void leggInn(int indeks, T verdi) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public boolean inneholder(T verdi) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public T hent(int indeks) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public int indeksTil(T verdi) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public T oppdater(int indeks, T nyverdi) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public boolean fjern(T verdi) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public T fjern(int indeks) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public void nullstill() { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public String toString() { throw new UnsupportedOperationException("Ikke laget ennå!"); } public String omvendtString() { throw new UnsupportedOperationException("Ikke laget ennå!"); } public static <T> void sorter(Liste<T> liste, Comparator<? super T> c) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public Iterator<T> iterator() { throw new UnsupportedOperationException("Ikke laget ennå!"); } public Iterator<T> iterator(int indeks) { throw new UnsupportedOperationException("Ikke laget ennå!"); } private class DobbeltLenketListeIterator implements Iterator<T> { private Node<T> denne; private boolean fjernOK; private int iteratorendringer; private DobbeltLenketListeIterator() { denne = hode; // denne starter på den første i listen fjernOK = false; // blir sann når next() kalles iteratorendringer = endringer; // teller endringer } private DobbeltLenketListeIterator(int indeks) { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public boolean hasNext() { return denne != null; // denne koden skal ikke endres! } @Override public T next() { throw new UnsupportedOperationException("Ikke laget ennå!"); } @Override public void remove() { throw new UnsupportedOperationException("Ikke laget ennå!"); } } // DobbeltLenketListeIterator } // DobbeltLenketListe