INF1010, 23. februar 2012 Parametriserte klasser Om å gå gjennom egne beholdere (subklasser og grensesnitt 3) Stein Gjessing Inst for Informatikk Universitetet i Oslo
Repetisjon fra gamle dager: Metoder med parametre En metode uten parameter: int kvadratav5 () { return 25; En metode med parameter: int kvadrat (int tall) { return tall * tall; tall er formell parameter Definerende forekomst av den formelle parameteren tall Bruks-forekomst av den formelle parameteren tall int svar = kvadrat(7); 49 7 er aktuell parameter 2
Klasser med parametre n Nytt for noen år siden (Java 1.5) n Metoder med parametre har eksistert alltid n Klasser med parametre kalles også n n Generiske klasser Generiske typer n Ikke 100% vellykket i Java n Pga. at at det ikke var lett å få Java Virtual Machine til å kjøre dette. n Derfor: Bare enkel bruk av generiske klasser er pensum i INF1010, dvs. det du ser her i dag. 3
Motivasjon: En liten beholder Hva slags objekter får jeg lov til å lagre? void legginn (Object en) Object hent ( ) Type: Object Navn: denne Hva er ulempen(e) med dette? Objekt av klassen Object eller en subklasse av Object
Hva kan skje a? public class BeholderTilEn { private Object denne; public void legginn(object en) { denne = en; public Object hent() { return denne; void legginn (Object en) Type: Object class Bil { class Person { Type: BholderTilEn Navn: bilbeholder public class EnkelDemo { public static void main(string[] args) { BeholderTilEn bilbeholder = new BeholderTilEn(); Bil bilen = new Bil(); bilbeholder.legginn(bilen) Object noe; Bil bilto; noe = bilbeholder.hent(); bilto = (Bil) noe; Object hent( ) Bil-objekt Navn: denne Person personen = new Person(); bilbeholder.legginn(personen); Bil bilfire = (Bil) bilbeholder.hent(); Person-objekt
Dette ønsker vi oss: void legginn (Bil en) Bil hent( ) Type: Bil Navn: denne Objekt av klassen Bil eller en subklasse av Bil void legginn (Person en) Person hent( ) Type: Person Navn: denne Objekt av klassen Person eller en subklasse av Person
Dette ønsker vi oss: Objekt av klassen GenBeholderTilEn <Bil> void legginn ( Bil T en) Type: T Bil Bil T hent( ) Navn: denne Objekt av klassen Bil T eller en subklasse av T Bil Hvor vi kan velge hvilken klasse vi skal kunne lagre objekter av, i det vi lager objektet (beholderen). class GenBeholderTilEn <T> {... new GenBeholderTilEn <Bil> (... ) klassedefinisjon med formel parameter lag objekt med aktuell parameter Her velger vi at denne beholderen bare skal kunne lagre Bil-objekter 7
Generisk versjon av den enkle beholderen (T er et navn vi velger selv (T for Type )) T er formell parameter Definerende forekomst av den formelle parameteren T Bruks-forekomster av den formelle parameteren T public class GenBeholderTilEn <T> { private T denne; public void legginn (T en) { denne = en; public T hent ( ) { return denne; NB! slike objekter finnes ikke!! void legginn (T en) T hent( ) Type: T Navn: denne Objekt av klassen T eller en subklasse av T
Bruk av class GenBeholderTilEn <T> GenBeholderTilEn <Bil> bilbeholder = new GenBeholderTilEn <Bil> ( ); Type: GenBeholderTilEn <Bil> Navn: bilbeholder Bil bilen = new Bil(); bilbeholder.legginn(bilen); bilen = bilbeholder.hent( ); Slike objekter finnes! void legginn (Bil en) Type: Bil Bil hent( ) Navn: denne Objekt av klassen GenBeholderTilEn<Bil> Objekt av klassen Bil eller en subklasse av Bil
Formell parameter public class GenBeholderTilEn <T> { private T denne; public void legginn (T en) { denne= en; public T hent () { return denne; class Bil { Aktuell parameter public class EnkelGenDemo { public static void main(string[] args) { GenBeholderTilEn <Bil> bilbeholder = new GenBeholderTilEn <Bil> (); Bil bilen = new Bil(); bilbeholder.legginn(bilen); Bil bilto = bilbeholder.hent(); Type: GenBeholderTilEn<Bil> Navn: bilbeholder I dette objektet kan vi bare legge inn biler! void legginn (Bil en) Bil hent( ) Type: Bil Navn: denne Bil-objekt og vi slipper å typekonvertere ( caste ) når vi tar dem ut 10
public class BeholderTilEnPerson { private Person denne; public void legginn (Person) { denne = en; public Person hent() { return denne; public class BeholderTilEn { private Object denne; public void legginn (Object en) { denne = en; public Object hent() { return denne; public class GenBeholderTilEn <T> { private T denne; public void legginn (T en) { denne = en; public T hent ( ) { return denne; At sammen er super Java-kode 11
Navn: antall T [ ] alle public void legginn (T en) Type: int Her mangler det mye! alle [antall] = peker; antall ++; public T hent( ) NB! slike objekter finnes ikke!! antall --; return alle [antall]; class Beholder<T> { private int antall = 0; private T[] alle = (T[]) new Object[100]; void legginn(t peker) {alle [antall] = peker; antall ++; public T hent() { antall --; return alle [antall]; 12
Navn: antall Fisk [ ] alle public void legginn (Fisk en) Type: int alle [antall] = peker; antall ++; public Fisk hent( ) Navn: akvarium Type: Beholder<Fisk> antall --; return alle [antall]; Objekt av klassen Beholder<Fisk> String [ ] allenavn = { "Langen", "Slanken", "Lynet", "Latsabb", "Dorsken", "Storhodet"; Beholder<Fisk> akvarium = new Beholder<Fisk>(); for (int i = 0; i < 6; i++) { Fisk f = new Fisk(alleNavn[i]); akvarium.legginn(f); class Fisk { String navn; Fisk(String nvn) { navn = nvn; 13
unchecked cast Typekonvertering nedover medfører kjøretidskontroll: Student stud2 = (Student) pers; (Repetisjon neste side) Her får vi en advarsel om at dette ikke vil skje ( unchecked ). Hvorfor (ikke pensum i INF1010): Fordi under kjøring er alle arrayer inne i objekter av generiske typer av klassen Object. Den typekonverteringen vi ser er bare til ære for oversetteren. 14
Konvertering av referanser (pekere) class Student extends Person { Student stud = new Student(); Person pers; pers = stud; Student stud2 = (Student) pers; Dette kalles casting (class-cast) på engelsk, typekonvertering på norsk. Medfører kjøretidstest. 15
class HashMap<K,V> class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { // Hemmelig datastruktur public void put(k key, V value) {... public V remove(object key) {... public V get(object key) {... Java har etter hvert mange klasser som kan brukes til å ta vare på objekter (Containers): Vector, ArrayList, Collection, HashMap HashSet, LinkedList, Stack, TreeSet, TreeMap,...) public boolean containskey(object key) {... public boolean containsvalue(object value) {... public int size( ) {... public Collection<V> values( ) {... // slutt class HashMap 16
Eksempel: HashMap uten klasse-parameter En HashMap (uten typespesifikasjon) kan brukes til å lagre objekter av en hvilken som helst klasse alle lagres som om de var av klassen Object. HashMap tabell = new HashMap(); Student stud = new Student(); stud.lesfraterminal(); tabell.put("kari", stud); stud = (Student) tabell.get("kari"); Disse blir implisitt konvertert oppover til Object, siden metoden put i HashMap har formalparametre put(object key, Object value). Dette gir en referanse til et objekt av klassen Object, og vi må eksplisitt konvertere nedover til Student for å snakke om objektets Student-egenskaper. 17
HashMap med klasse-parameter class Bil { String regnr; class Personbil extends Bil { int antpass; class Lastebil extends Bil { double lastevekt; class Drosje extends Personbil { int LøyveNr; DE25132 HashMap <String, Bil> h; h = new HashMap <String,Bil> ( ); Bil bl; Personbil minbil; Personbil persb = new Personbil(); h.put ( DE25132, persb); bl = h.get( DE25132 ); minbil= (Personbil) bl; //tryggere med: if (bl instanceof Personbil) minbil = (Personbil) bl; Denne blir implisitt konvertert oppover til Bil, siden metoden put i denne HashMapen har formalparametre put(string key, Bil value). Dette gir en referanse til et objekt av klassen Bil, og vi må eksplisitt konvertere nedover til Personbil for å snakke om objektets Personbilegenskaper. 18
Interface med parametre interface Utkledd <T> { // T er klassen jeg er utkledd som T utkleddsom(); class KarnevalsHund<U> extends VanligHund implements Utkledd <U> { U likner; // peker til en jeg er utkledd som KarnevaldsHund(U forbilde){likner = forbilde; public U utkleddsom(){return likner; class Reinsdyr { ; class Hoved{ public static void main (String[] args) { Reinsdyr dyr = new Reinsdyr(); KarnevalsHund<Reinsdyr> passopp= new KarnevalsHund<Reinsdyr>(dyr); Reinsdyr reinpeker = passopp.utkleddsom(); likner 19
interface Utkledd <T> { T utkleddsom(); Formoe Krav til klasse-parametre Formoe class VanligHund { class Person { String navn = Formoe ; class Sjorover extends Person{ navn class KarnevalsHund<U extends Person> extends VanligHund implements Utkledd<U> { U likner; // peker til en jeg er utkledd som KarnevalsHund(U forbilde) {likner = forbilde; public U utkleddsom() {return likner; String navntilutkleddsom () { return likner.navn; class Hoved{ public static void main (String[] args) { Sjorover rover = new Sjorover(); KarnevalsHund<Sjorover> passopp= new KarnevalsHund<Sjorover>(rover); Sjorover sjopeker = passopp.utkleddsom(); System.out.println(passopp.navnTilUtkleddSom()); likner 20
Comparable i Java-biblioteket interface Comparable <T> { int compareto (T obj) ; compareto returns a negative, zero or a positive integer as this object is less than, equal to, or greater than the specified object class Bil implements Comparable <Bil> {... class Person implements Comparable <Person> {... class Fly implements Comparable <Bil> {... Men hvem ønsker å sammenligne Fly med Biler? Objekt av klassen Bil Comparable<T> Object compareto(bil b) Bil 21
Finn beste hund class StedTilTaVarePaaBeste < U > { U beste= null; void settinn(u ny) { if( beste== null) beste= ny; else if (beste er dårligere enn ny) beste= ny; U hentbeste() {return beste; Navn: hundehuset Ins$tu' for informa$kk Type: StedTilTaVarePaaBeste<Hund> void settinn(hund ny) Person hentbest() return beste; class Katt { class Hund { class Person { Navn: beste Type: Hund StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast Type: Hund 29 poeng public int sammenlign (Hund hnd) return...; Navn: passopp Type: Hund 42 poeng public int sammenlign (Hund hnd) return...; Navn: kea Type: Hund 31 poeng public int sammenlign (Hund hnd) return...; 22
Finn beste hund Navn: hundehuset class StedTilTaVarePaaBeste < U > { U beste= null; void settinn(u ny) { if( beste== null) beste= ny; else if (beste.sammenlig(ny) < 0) beste= ny; U hentbeste() {return beste; class Katt { class Hund { class Person { Type: StedTilTaVarePaaBeste<Hund> void settinn(hund ny) Person hentbest() return beste; Navn: beste Type: Hund StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast Type: Hund Navn: passopp Type: Hund Navn: kea Type: Hund 29 poeng public int sammenlign (Hund hnd) 42 poeng public int sammenlign (Hund hnd) 31 poeng public int sammenlign (Hund hnd) return...; return...; return...; 23
Finn beste hund Navn: hundehuset class StedTilTaVarePaaBeste < U > { U beste= null; void settinn(u ny) { if( beste== null) beste= ny; else if (beste.compareto(ny) < 0) beste= ny; U hentbeste() {return beste; class Katt { class Hund { class Person { Type: StedTilTaVarePaaBeste<Hund> void settinn(hund ny) Person hentbest() return beste; Navn: beste Type: Hund StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast Type: Hund Navn: passopp Type: Hund Navn: kea Type: Hund 29 poeng public int compareto (Hund hnd) 42 poeng public int compareto (Hund hnd) 31 poeng public int compareto (Hund hnd) return...; return...; return...; 24
Finn beste hund Navn: hundehuset class StedTilTaVarePaaBeste < U > { U beste= null; void settinn(u ny) { if( beste== null) beste= ny; else if (beste.compareto(ny) < 0) beste= ny; U hentbeste() {return beste; class Katt { class Hund implements Comparable <Hund>{ class Person { Type: StedTilTaVarePaaBeste<Hund> void settinn(hund ny) Person hentbest() return beste; Navn: beste Type: Hund StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast Type: Hund Navn: passopp Type: Hund Navn: kea Type: Hund 29 poeng public int compareto (Hund hnd) 42 poeng public int compareto (Hund hnd) 31 poeng public int compareto (Hund hnd) return...; return...; return...; 25
Finn beste hund extends Navn: hundehuset class StedTilTaVarePaaBeste < U implements Comparable <U>> Type: { StedTilTaVarePaaBeste<Hund> U beste= null; void settinn(u ny) { if( beste== null) beste= ny; void settinn(hund ny) else if (beste.compareto(ny) < 0) beste= ny; U hentbeste() {return beste; Person hentbest() return beste; class Katt { class Hund implements Comparable <Hund>{... se neste side... class Person { Navn: beste Type: Hund StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast Type: Hund Navn: passopp Type: Hund Navn: kea Type: Hund 29 poeng public int compareto (Hund hnd) return...; 42 poeng public int compareto (Hund hnd) return...; 31 poeng public int compareto (Hund hnd) return...; 26
class Hund implements Comparable <Hund>{ int poeng; Hund(int png) {poeng= png; public int compareto (Hund hnd) { return poeng hnd.poeng; trofast = new Hund(29); passopp = new Hund(42); if (trofast.compareto(passopp) < 0) {... Navn: trofast Type: Hund Navn: passopp Type: Hund 29 poeng public int compareto (Hund hnd) 42 poeng public int compareto (Hund hnd) Navn: hnd Type: Hund return hnd.poeng - poeng return hnd.poeng - poeng 27
Evas hus Navn: hjem Ins$tu' for informa$kk interface Comparable <T> { int compareto (T obj) ; Type: StedTilTaVarePaaBeste<Person> class StedTilTaVarePaaBeste < U extends Comparable <U> > { U beste= null; Navn: ole void settinn(u ny) { if( beste== null) beste= ny; Type: Person else if (beste.compareto(ny) < 0) beste= ny; poeng 17 U hentbeste() {return beste; public int compareto(person prs) class Person implements Comparable <Person> { int poeng; Person (int png) {poeng= png; public int compareto (Person prs) { return poeng - prs.poeng; class BrukSted { public static void main (String [ ] args) { StedTilTaVarePaaBeste<Person> hjem= new StedTilTaVarePaaBeste<Person>( ); Person ole = new Person(17); hjem.settinn(ole); Person per = new Person(25); hjem.settinn(per); Person paal= new Person(21); hjem.settinn(paal); Person bestitest = hjem.hentbeste (); System.out.println(bestITest.poeng); void settinn(person ny) if( beste== null) beste= ny; else if (beste.compareto(ny) > 0 beste= ny; Person hentbest() return beste; return...; Navn: beste Navn: per Type: Person Type: Person Navn: paal poeng 25 public int compareto(person prs) return...; Type: Person 21 poeng public int compareto(person prs) Navn: bestitest Type: Person return...; 28
For de spesielt interesserte class Bil {... // Hvis du absolutt må sammenligne fly og biler: class Fly implements Comparable <Bil> {... public int compareto(bil b) {... ; return... ; // Hvis vi skal ta vare på to ting, der vi ikke krever noe om den første (T), men krever at den andre tingen (U) kan sammenlignes med den første: class Beholder <T, U extends Comparable <T>> {... // For eksempel; Beholder <Bil,Fly> minb = new Beholder <Bil, Fly> ( ) ; 29
Indre klasser n n n n Klasser i Java kan defineres inni hverandre. Objekter i den indre klassen kan referere til metoder og variable i sitt omsluttende objekt! * + Lettvint + Skjuler implementasjon Flere feilmuligheter class Register { HashMap<String,Person> liste;... class Person { String navn;... void registrer() {... liste.put(navn,this);... // Slutt class Person... // Slutt class Register Du må altså opprette et objekt av den ytre klassen før du får lov til å lage objekter av den indre klassen (*hvis ikke den indre klassen er static ) 30
From Java language specification: 14.14.2 The enhanced for statement The enhanced for statement has the form: EnhancedForStatement: for ( VariableModifiers opt Type Identifier: Expression) Statement The Expression must either have type Iterable or else it must be of an array type ( 10.1), or a compile-time error occurs. 31
class Hoved { public static void main (String [ ] args) { String [ ] alle= { "Langen", "Slanken", "Lynet", "Latsabb", "Dorsken", "Storhodet" for (String s: alle) System.out.println(s); Fisk [ ] alle Akvarium med array class Hoved { public static void main (String [ ] args) { Fisk[ ] alle = {new Fisk(), new Fisk(), new Fisk(), new Fisk(), new Fisk(), new Fisk(); for (Fisk f: alle) System.out.println(f.navn); class Fisk { static int allenummer = 0; static String [ ] allenavn = { "Langen", "Slanken", "Lynet", "Latsabb", "Dorsken", "Storhodet"; String navn = allenavn[allenummer ++]; 32
Akvarium med HashMap import java.util.*; class Hoved18 { public static void main (String [ ] args) { HashMap<String,Fisk> akvarium = new HashMap<String,Fisk>(); for (int i = 0; i < 10; i++) { Fisk f = new Fisk(); akvarium.put(f.navn, f); for (Fisk f: akvarium.values()) System.out.println(f.navn); Navn: f Type: Fisk class Fisk { static int allenummer = 0; static String [ ] allenavn = { Rar", Slanken", Lynet", Pigg", Dorsken, Stor ; String navn = allenavn[allenummer ++]; 33
Hvordan skal vi klare å gå gjennom alle objektene i vår egendefinerte beholder? public void legginn (T en) public T hent( ) alle [antall] = peker; antall ++; antall --; return alle [antall]; Navn: antall Type: int T [ ] alle public T gimegalleenetteren hentenogen( )???????????????????? NB! slike objekter finnes ikke!! 34
35
36
Iterasjon over innholdet i en generisk beholder n La oss starte med å gå gjennom alle elementene i en beholder som bare kan inneholde en ting void legginn (T en) T hent( ) Type: T Navn: denne Objekt av klassen T eller en subklasse av T NB! slike objekter finnes ikke!! 37
public class GenBeholderTilEn <T> { private T denne; public void legginn (T en) { denne= en; public T hent () { return denne; Gammel del public Iterable<T> iterergjennomalle() {return new Ukjent1(); private class Ukjent1 implements Iterable<T> { public Iterator<T> iterator () {return new Ukjent2(); Ny del private class Ukjent2 implements Iterator<T> { boolean fortsett = true; public boolean hasnext(){return fortsett; public T next() {fortsett = false; return denne; public void remove ( ) { class Hoved { public static void main (String [ ] ards) { GenBeholderTilEn<Fisk> ensligakvarium = new GenBeholderTilEn<Fisk> (); ensligakvarium.legginn(new Fisk("Piraja")); for (Fisk f: ensligakvarium.iterergjennomalle()) System.out.println("Fisk med navn: " + f.navn); class Fisk { String navn; Fisk(String nvn) {navn= nvn; 38
public void legginn (Fisk en) public Fisk hent( ) public Iterable<Fisk> iterergjennomalle() {return new Ukjent1(); Type: Fisk Navn: denne Iterator iterator( ) return new Ukent2(); objekt av class Ukjent1 implements Iterable<Fisk> boolean hasnext( ) Fisk next( ) void remove( ) fortsett objekt av class Ukjent2 implements Iterator<Fisk> Navn: ensligakvarium Type: GenBeholderTilEn<Fisk> Når java kjører er objektene i virkeligheten ikke inne i hverandre (men det blir letter for oss hvis vi tenker oss at de er inne i hverandre) 39
Iterasjon over innholdet i en større generisk beholder (et objekt av en parameterisert klasse) n Hvis vi ungår pirajaen, kan vi lage bruke et akvarium som kan inneholde mange fisk n Vi lager først en generisk beholder med plass til mange objekter 40
tenkt objekt av klassen Beholder<T> public void legginn (T en) public T hent( ) alle [antall] = peker; antall ++; antall --; return alle [antall]; public Iterable<T> iterergjennomalle() {return new Ukjent1(); Navn: antall Type: int T [ ] alle Iterator<T> iterator( ) return new Ukjent2(); objekt av class Ukjent1 implements Iterable<T> boolean hasnext( ) return teller < antall; T next( ) teller teller ++; return alle[teller-1]; void remove( ) objekt av class Ukjent2 implements Iterator<T> NB! slike objekter finnes ikke!! 41
objekt av klassen Beholder<Fisk> public void legginn (Fisk en) public Fisk hent( ) alle [antall] = peker; antall ++; antall --; return alle [antall]; public Iterable<Fisk> iterergjennomalle() {return new Ukjent1(); Navn: antall Type: int Fisk [ ] alle Iterator<Fisk> iterator( ) return new Ukjent2(); objekt av class Ukjent1 implements Iterable<Fisk> boolean hasnext( ) return teller < antall; Fisk next( ) teller teller ++; return alle[teller-1]; void remove( ) objekt av class Ukjent2 implements Iterator<Fisk> NB! slike objekter finnes!! 42
class Hoved{ public static void main (String [ ] ards) { new Hoved ( ); Hoved() { String [ ] allenavn = { "Langen", "Slanken", "Lynet", "Latsabb, "Dorsken", "Storhodet"; Beholder<Fisk> akvarium = new Beholder<Fisk>(); for (int i = 0; i < 6; i++) { Fisk f = new Fisk(alleNavn[i]); akvarium.legginn(f); for (Fisk fsk: akvarium.iterergjennomalle()) System.out.println("Fisk med navn: " + fsk.navn); class Beholder<T> { int antall = 0; T[] alle = (T[]) new Object[100]; void legginn(t peker) {alle [antall] = peker; antall ++; T hent () {antall --; return alle [antall]; Iterable<T> iterergjennomalle() {return new Ukjent1(); class Ukjent1 implements Iterable<T> { public Iterator<T> iterator () {return new Ukjent2(); class Ukjent2 implements Iterator<T> { int teller = 0; public boolean hasnext(){return teller < antall; public T next() {teller ++; return alle[teller-1]; public void remove ( ) { class Fisk { String navn; Fisk(String nvn) {navn = nvn; 43
class Hoved { public static void main (String [ ] ards) { String [ ] navn = { Ole", "Per", "Paal", "Eva", "Else"; for (String s: navn) System.out.println(s); import java.util.iterator; class Hoved2 { public static void main (String [ ] ards) { new Hooved2 ( ); Hoved2() { for (String s: new Ukjent1()) { System.out.println(s); String [ ] navn = { "Ole", "Per", "Paal", "Eva", "Else"; class Ukjent1 implements Iterable<String> { public Iterator iterator () {return new Ukjent2(); Enda to eksempler class Ukjent2 implements Iterator<String> { int teller = 0; public boolean hasnext(){return teller!= navn.length; public String next() {teller ++ ; return navn[teller-1]; public void remove ( ) { Legg merke til at det ikke er noen beholder her (ikke så bra) Slike indre klasser (som ikke er static ) finnes bare inne i objekter (ikke inne i klassedatastrukturer) 44
HashMap og grensesnittet Collection public interface Collection<E> extends Iterable<E> { public int size(); Iterator<E> iterator( );... class HashMap<K,V>... { <Hemmelig datastruktur> class Ukjent1 implements Collection<V> {... class Ukent2 implements Iterator <V>{... public void put(k nokkel, V verdi ){...... public Collection<V> values( ) { Ukjent1<V> u = new Ukjent1<V> ( ) ;... return u;... HashMap har altså sine egen implementasjon av Collection som er hemmelig for oss utenfor 45
Implementasjon av HashMap HashMap<String, Dokument> alledokumenter void visalledokumenter() for (Dokument d: alledokumenter.values()) { d.vispaaskjerm(); d objekt av class Ukjent1 implements Collection<Dokument> Iterator<Dokument> iterator( ) Collection<Dokument> values() boolean hasnext( ) Dokument next( )? objekt av class Ukjent2 implements Iterator<Dokument> Dokument-objekt 46