INF1010, 26. februar 2014 1. Krav til klasseparametre 2. Om å gå gjennom egne beholdere (iteratorer) Stein Gjessing Inst. for Informatikk Universitetet i Oslo
Vi tar utgangspunkt i dette programmet for å vise krav til klasseparametre og egendefinerte iteratorer class Person { public String navn; Person(String navn) { this.navn = navn; public void skrivut() { System.out.println("Navnet er: " + navn); class PersonBeholder{ Person ene = null; public void settinn(person p) { ene= p; public void skrivut() { ene.skrivut(); class Hoved { public static void main(string[] args) { PersonBeholder minpbeholder = new PersonBeholder ( ); Person petter = new Person("Petter"); minpbeholder.settinn(petter); minpbeholder.skrivut(); Person anne = new Person("Anne"); minpbeholder.settinn(anne); minpbeholder.skrivut(); 2
interface Utkledd <U> { U utkleddsom(); Krav til klasse-parametre Formoe class VanligHund { class Person { String navn = Formoe ; class Sjorover extends Person{ navn class KarnevalsHund <U > 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()); VanligHund Utkledd<U> likner KarnevalsHund<U extends Person> 3
interface Utkledd <U> { U utkleddsom(); 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()); VanligHund Utkledd<U> likner KarnevalsHund<U extends Person> 4
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 implements Comparable <Bil> 5
Finn beste hund class StedTilTaVarePaaBeste < U > { private U beste= null; public void settinn(u ny) { if( beste== null) beste= ny; else if (beste er dårligere enn ny) beste= ny; public U hentbeste() {return beste; Navn: hundehuset Ins$tu' for informa$kk Type: StedTilTaVarePaaBeste<Hund> void settinn(hund ny) Hund hentbeste() return beste; class Katt { class Hund { class Person { Navn: beste StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast 29 poeng public int sammenlign (Hund hnd) return...; Navn: passopp 42 poeng public int sammenlign (Hund hnd) return...; Navn: kea 31 poeng public int sammenlign (Hund hnd) return...; 6
Finn beste hund class StedTilTaVarePaaBeste < U > { private U beste= null; public void settinn(u ny) { if( beste== null) beste= ny; else if (beste.compareto(ny) < 0) beste= ny; public U hentbeste() {return beste; Navn: hundehuset Ins$tu' for informa$kk Type: StedTilTaVarePaaBeste<Hund> void settinn(hund ny) Hund hentbeste() return beste; class Katt { class Hund { class Person { Navn: beste StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast 29 poeng public int compareto (Hund hnd) return...; Navn: passopp 42 poeng public int compareto (Hund hnd) return...; Navn: kea 31 poeng public int compareto (Hund hnd) return...; 7
Finn beste hund class StedTilTaVarePaaBeste < U > { private U beste= null; public void settinn(u ny) { if( beste== null) beste= ny; else if (beste.compareto(ny) < 0) beste= ny; public U hentbeste() {return beste; Navn: hundehuset Ins$tu' for informa$kk Type: StedTilTaVarePaaBeste<Hund> void settinn(hund ny) Hund hentbeste() return beste; class Katt { class Hund implements Comparable <Hund>{ class Person { Navn: beste StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast 29 poeng public int compareto (Hund hnd) return...; Navn: passopp 42 poeng public int compareto (Hund hnd) return...; Navn: kea 31 poeng public int compareto (Hund hnd) return...; 8
Finn beste hund extends class StedTilTaVarePaaBeste < U implements Comparable <U>> { private U beste= null; public void settinn(u ny) { if( beste== null) beste= ny; else if (beste.compareto(ny) < 0) beste= ny; public U hentbeste() {return beste; Navn: hundehuset Ins$tu' for informa$kk Type: StedTilTaVarePaaBeste<Hund> void settinn(hund ny) Hund hentbeste() return beste; Navn: beste class Hund implements Comparable <Hund>{ StedTilTaVarePaaBeste <Hund> hundehuset = new StedTilTaVarePaaBeste <Hund> ( ); // nytt hundehus; Navn: trofast 29 poeng public int compareto (Hund hnd) return...; Navn: passopp 42 poeng public int compareto (Hund hnd) return...; Navn: kea 31 poeng public int compareto (Hund hnd) return...; 9
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 Navn: passopp Objekt av class Hund implements Comparable <Hund> Objekt av class Hund implements Comparable <Hund> 29 poeng 42 poeng public int compareto (Hund hnd) public int compareto (Hund hnd) Navn: hnd return hnd.poeng - poeng Navn: hnd return hnd.poeng - poeng 10
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> > { private U beste= null; Navn: ole public void settinn(u ny) { if( beste== null) beste= ny; Type: Person else if (beste.compareto(ny) < 0) beste= ny; poeng 17 public 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 hentbeste() 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...; 11
Flere krav til klasse-parametre: & interface Skriv{ void skrivut(); class Person implements Comparable <Person>, Skriv { public String navn; Person(String navn) { this.navn = navn; public void skrivut() {System.out.println("Navnet er: " + navn); public int compareto (Person p) {return navn.compareto(p.navn); class BestBeholder <T extends Comparable<T> & Skriv> { T ene = null; public void settinn(t p) { if (ene == null) ene = p; else if( p.compareto(ene) < 0) ene= p; public void skrivut(){ene.skrivut(); class HovedComp { public static void main(string[] args) { BestBeholder<Person> minpbeholder = new BestBeholder<Person> ( ); Person petter = new Person("Petter"); minpbeholder.settinn(petter); minpbeholder.skrivut(); Person anne = new Person("Anne"); minpbeholder.settinn(anne); minpbeholder.skrivut(); Person bjarne = new Person("Bjarne"); minpbeholder.settinn(bjarne); minpbeholder.skrivut(); 12
For de spesielt interesserte class Bil {... // Hvis du absolutt må sammenligne fly med 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> ( ) ; 13
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 ) 14
Ikke noe nytt her From the Java language specification (version 6): (nesten det samme i versjon 7) 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. Kalles også "for-each 15
String-array Ikke noe nytt her class Hoved { public static void main (String [ ] args) { String [ ] alles = { Ole", Eva", Lise", Per", Turid", Anne"; for (String s: alles) System.out.println(s); String [ ] alles Ole Eva Anne Akvarium med array class Hoved { public static void main (String [ ] args) { Fisk[ ] allef = {new Fisk("Langen"), new Fisk("Slanken"), new Fisk("Lynet"), new Fisk("Latsabb"), new Fisk("Dorsken"), new Fisk("Storhodet"); Fisk [ ] allef for (Fisk f: allef) System.out.println(f.navn); class Fisk { String navn; Fisk (String nv) {navn = nv; 16
Ikke noe nytt her Akvarium med HashMap import java.util.*; class Hoved { static String [ ] allenavn = { Rar", Slanken", Lynet", Pigg", Dorsken, Stor ; public static void main (String [ ] args) { HashMap<String,Fisk> akvarium = new HashMap<String,Fisk>(); Navn: f Type: Fisk for (int i = 0; i < 6; i++) { Fisk f = new Fisk(alleNavn(i)); akvarium.put(f.navn, f); for (Fisk f: akvarium.values() ) System.out.println(f.navn); class Fisk { String navn; Fisk (String nv) {navn = nv; 17
Hvordan skal vi klare å gå gjennom alle objektene i vår egendefinerte beholder? public void legginn (T en) public T hentut( ) alle [antall] = peker; antall ++; antall --; return alle [antall]; Navn: antall Type: int T [ ] alle Iterable<T> iterergjennomalle()????? NB! slike objekter finnes ikke!! (T må få en verdi først) 18
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. Type: Iterable<T> Navn: alle Iterator<T> iterator( ) Da kan vi si: for (T en: alle) { <gjør noe med objektet som "en" peker på> Men T må byttes ut med et ordentlig klassenavn 19
20
Type: Iterable<T> Iterator<T> iterator( ) Navn: alle Type: Iterator<T> Navn: anonym boolean hasnext ( ) T next ( ) void remove ( ) Vi kan da si: for (T en: alle) { <gjør noe med objektet som en peker på> Men T må byttes ut med et ordentlig klassenavn 21
22
Type: Iterable<T> Navn: alle Iterator<T> iterator( ) Nytt objekt eller beholderen selv Type: Iterator<T> Navn: anonym Vi kan da si: boolean hasnext ( ) T next ( ) void remove ( ) Peker "neste" på et gyldig element? Øk "neste" og returne forrige Fjern forrige neste Invariant: "neste" peker på neste element. Forandres av "next" for (T en: alle) { <gjør noe med objektet som en peker på> Men T må byttes ut med et ordentlig klassenavn 23
Iterasjon over innholdet i en generisk beholder vi lager selv 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 Iterable<T> iterergjennomalle() Objekt av klassen T eller en subklasse av T NB! slike objekter finnes ikke!! 24
class Hoved { public static void main (String [ ] args) { EgenDefBeholder<Fisk> akvarium = new EgenDefBeholder<Fisk> (); akvarium.put(new Fisk("Dorsken")); akvarium for (Fisk f: akvarium.iterergjennomalle() ) System.out.println(f.navn); class Fisk { String navn; Fisk (String nv) {navn = nv; class EgenDefBeholder<T> { private... public void legginn(t en) {... T hent ( ) {... Iterable<T> iterergjennomalle ( ) {... void legginn (Fisk en) Fisk hent( ) Type: Fisk Navn: denne Iterable<Fisk> iterergjennomalle() 25
class Hoved { Enda klarere (?): public static void main (String [ ] args) { GenBeholderTilEn<Fisk> akvarium = new GenBeholderTilEn<Fisk> (); akvarium.put(new Fisk("Dorsken")); akvarium Itarable<Fisk> alle = akvarium.iterergjennomalle(); for (Fisk f: alle) System.out.println(f.navn); class Fisk { String navn; Fisk (String nv) {navn = nv; class GenBeholderTilEn<T> { private... public void legginn(t en) {... T hent ( ) {... Iterable<T> iterergjennomalle ( ) {... void legginn (Fisk en) Fisk hent( ) Type: Fisk Navn: denne Iterable<Fisk> iterergjennomalle() alle Iterable<Fisk> Objekt som implementerer grensesnittet Iterable<Fisk> Iterator<Fisk> iterator( ) 26
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; 27
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) 28
29 Iterasjon over innholdet i en større generisk beholder n Hvis vi ungår pirajaen, kan vi bruke et akvarium som kan inneholde mange fisk n Vi lager først en generisk beholder med plass til mange objekter
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!! 30
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!! 31
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; 32
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; Repetisjon Ikke nytt Enkel måte å gå gjennom en String-tabell Komplisert måte å gå gjennom en String-tabell class Hoved2 { public static void main (String [ ] ards) { new Hoved2 ( ); 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(); 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 ( ) { Nytt i dag Slike indre klasser (som ikke er static ) finnes bare inne i objekter (ikke inne i klassedatastrukturer) 33
HashMap og grensesnittet Collection public interface Collection<E> extends Iterable<E> {..... class HashMap<K,V>... { <Hemmelig datastruktur> private class Ukjent1 implements Collection<V> {... private 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 34
Eks. 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 35