Uke 8 - Opprmstyper, HshMp og Innstikksortering, litt jvdoc 17. oktober 2013, Arne Mus Inst. for informtikk, UiO Slik enum kn h metoder, og hver verdi hr et tll ssosiert ved seg. En enum virker omtrent som en klsse-deklrsjon. Enummerering å lge egne opprmstyper Brukes til å lge typer som hr et lite ntll verdier, ofte tekst. Holde orden på objekter - HshMp Ofte hr vi flere, mnge objekter v en bestemt klsse - eks. : elever på en skole biler som hr pssert bomringen i Oslo telefonsmtler fr en bestemt person,. Vi hr hittil lært rryer (Elev [] elevene = new Elev[400], Bil [] bomringbiler = new Bil[10000];...) og må d psse på t vi hr nok plss for å finne et bestemt objekt må vi ofte lete gjennom hele rryen Vi skl nå lære en bedre måte å lgre objekter hvor det er viktig å rskt og enkelt finne igjen ett v objektene (som d hr ett bestemt kjennetegn som: Nvnet til eleven, registreringsnummeret til en bil,...) Et slikt kjennetegn som skiller ett objekt fr lle ndre objekter, kller vi en nøkkel (key) HshMp er svret 2 4
HshMp = lgre objekter med en søkenøkkel Brukes til å holde orden på en smling objekter Alterntiv til rryer Med rryer kn mn: I en rry legger vi inn objekter i en bestemt posisjon, og vi må gå tilbke til denne posisjonen/indeksen når vi senere skl se på objektet. Indeksen er et heltll mellom 0 og length-1. To viktige forskjeller mellom rryer og HshMp: I en HshMp oppgir vi en bestemt nøkkel (vnligvis en tekststreng) når vi legger vi inn et nytt objekt (klt verdien), og vi oppgir denne nøkkelen når vi senere skl se på objektet. Dvs. indeksen er en tekststreng. En HshMp hr ingen gitt lengde når vi lger den. Den vokser når legger inn nye elementer (inntil hele lgerplssen er oppbrukt) En Hshmp er mer fleksibel (men lngsommere) måte å lgre flere/mnge elementer i et progrm Ulike versjoner i Jv 1.4 (gmmel) og Jv 1.5/1.6/1.7 v HshMp Vi nbefler klrt t 1.5-1.7 måten nyttes, d den hjelper deg mot visse feil (som ellers er lett å gjøre). 1.4 måten gjennomgås bre en gng (bre) fordi mnge gmle progrmmer inneholder slik kode. 7 Hvordn vi skl tenke oss en HshMp en HshMp er som en slgs dobbelt-rry (f.eks bomringbilene) HshMp <String,Bil> bomringbilene = new HshMp <String,Bil>(); bomringbilene regnum Bil 1 regnum Bil 2 regnum Bil 3 nøkler verdier (keys) (vlues) 6 import jv.util.*; clss BrukAvHshMp { public sttic void min (String[] rgs) { HshMp<String,Person> h = new HshMp <String,Person>(); String fnr1 = 30128812344"; Person per1 = new Person(fnr1, "Hrld Olsen"); h.put(fnr1, per1); String fnr2 = 14109522547"; Person per2 = new Person(fnr2, Len Torsen"); h.put(fnr2, per2); Legg inn Person-objekt i HshMp en Person p = h.get( 30128812344 ); clss Person { String fnr; String nvn; Eksempel på bruk v HshMp (1.5-1.7) Importer pkken jv.util Opprett en HshMp og forteller hvilke klsser nøkkelen og verdier hr. Person(String fnr, String nvn) { this.fnr = fnr; this.nvn = nvn; String fånvn() { return nvn; Legg inn Person-objekt i HshMp en Hent Person-objekt fr HshMp en 8 5
Opprette en HshMp, Jv1.4 (gmmel) og Jv 1.5-1.6 I strten v progrmmet: import jv.util.*; Dette importerer pkken jv.util hvor bl.. klssen HshMp ligger. I klssen eller metoden som skl bruke HshMp'en Jv 1.4: HshMp h = new HshMp(); I klssen eller metoden som skl bruke HshMp'en Jv 1.5 og nyere (best): HshMp <String,Person> h = new HshMp <String,Person>(); I Jv 1.5 forteller vi hvilke klsser nøkkel- og verdi-objektene kommer fr. Vi sier t vi d låser objektene til både nøkkelen og verdi-objektene til å være v disse typene. NB: Hvis tbellen skl brukes v flere metoder i en klsse, deklreres vribelen ovenfor i strten v klssen (som en objektvribel). Hvis tbellen kun skl brukes v en enkelt metode, er det nturlig å deklrere HshMp vribelen ovenfor inni den ktuelle metoden. Dersom vi legger inn flere objekter med smme nøkkel, er det bre det sist innlgte objektet som blir liggende i tbellen (de ndre overskrives): Person p1 = new Person(...); Person p2 = new Person(...); Person p3 = new Person(...); String nvn = "Jens"; h.put(nvn, p1); // p1 legges inn h.put(nvn, p2); // p2 legges inn og p1 overskrives h.put(nvn, p3); // p3 legges inn og p2 overskrives Noen gnger må vi konstruere en nøkkel ut fr flere vrible for å få entydighet: String lengdegrd = "67.3"; String breddegrd = "53.3"; String posisjon = lengdegrd + ";" + breddegrd; Fjelltopp fjell = new Fjelltopp(posisjon, Bjørnefjell ); h.put(posisjon, fjell); Legge inn objekt i HshMp Et hvilket som helst objekt i Jv kn legges inn i en HshMp, men det må det være v den klssen vi hr lovet systemet Når vi legger et objekt inn i HshMp'en, må vi smtidig oppgi en nøkkel, dvs en tekststreng som entydig identifiserer objektet. Vi trenger denne nøkkelen dersom vi senere skl finne eller fjerne objektet i HshMp'en. Eksempel: String fnr = 30126512345 ; Person p = new Person(fnr, Kri Olsen ); h.put(fnr, p); Her lger vi først et Person-objekt (med pssende rgumenter) og legger det deretter inn i tbellen med fødselsnummeret som nøkkel. 10 Hente objekt fr HshMp Jv 1.4: For å hente et objekt med utgngspunkt i nøkkelen: // 1.4: Vi vil finne en person ut fr fødselsnummeret: Person p = (Person) h.get(fnr); Legg merke til t vi i 1.4 i strten må skrive i prentes nvnet på klssen som objektet tilhører - i dette tilfellet klssen Person. Årsken er t i 1.4 HshMp'en ikke holder rede på hvilken klsse objektene som legges inn hr - bre t det er objekter. Når objektene hentes ut må vi derfor "minne Jv på" hvilken klsse objektet vr v (dette er egentlig et møte med en vnsert og svært nyttig meknisme i objektorienterte språk som klles rv og som blir ttt opp i vårens INF1010). Jv 1.5: For å hente et objekt med utgngspunkt i nøkkelen, nå trenger vi ikke si hvilken klsse objektet hr (det hr vi jo sgt i deklrsjonen v HshMpen h): // 1.5: Vi vil finne en person ut fr fødselsnummeret: Person p = h.get(fnr) Merk: å hente et objekt fr en HshMp slik som over medfører ikke t objektet fjernes fr HshMp'en (vi får bre en kopi v en peker til objektet). 12 9
Fjerne objekt fr HshMp For å fjerne et objekt med gitt fødselsnummer som nøkkel: h.remove(fnr); Dersom det ligger et objekt i HshMp'en med den gitte nøkkelen, blir objektet fjernet og setningen ovenfor returnerer med en peker til objektet som fjernes. Dersom det ikke ligger et objekt i HshMp'en med den gitte nøkkelen, returnerer setningen ovenfor verdien null. Kn også løpe gjennom nøklene til en HshMp Løpe gjennom nøklene med en for-løkke (best): for (String s: h.keyset()) { System.out.println( Fødselsnummer: + p.fnr()); Løpe gjennom nøklene med itertor: Itertor <String> it = h.keyset().itertor(); while (it.hsnext()) { String nøkkel = it.next(); <gjør noe med Stringen nøkkel> 13 15 Løp gjennom lle objekter i HshMp For å løpe gjennom lle objektene i en HshMp, lger vi en opprmsing og låser smtidig det vi skl hente til en bestemt klsse: Itertor <Person> it = h.vlues().itertor(); Deretter kn vi se på hvert enkelt objekt i HshMp'en ved å gå i løkke: while (it.hsnext()) { Person p = it.next(); System.out.println( Nvn: + p.fånvn()); Bedre: Vi kn også i 1.5 nytte den nye for-løkk som utomtisk lger en itertor. Person-pekeren p får d kopi v peker til objektene, en etter en, som er verdiene i HshMp en h. for (Person p: h.vlues()) { System.out.println( Nvn: + p.fånvn()); 14 Metoder i HshMp Metode Eksempel Beskrivelse put h.put(nøkkel, objekt); Legg inn objekt med gitt nøkkel get -1.4 get -1.5 Person p = (Person) h.get(nøkkel); Person p = h.get(nøkkel); Finn objekt remove h.remove(nøkkel); Fjern objekt continskey if (h.continskey(nøkkel)) { // gjør et eller nnet Sjekk om nøkkel finnes i tbell vlues Itertor it = h.vlues().itertor(); Lg opprmsing v objektene keyset Itertor it = h.keyset().itertor(); Lg opprmsing v nøklene 16
Itertor (opprmsing) Eksempel Itertor it1 = h.vlues().itertor(); Itertor it2 = h.keyset().itertor(); Beskrivelse deklrrsjon hsnext() while (it.hsnext()) { < les neste og gjør noe>; next() 1.5 next() 1.4 Person p = it.next(); Person p = (Person) it.next(); returnerer true hvis flere objekter igjen i opprmsingen Finn neste objekt remove() Person p = it.next(); if (p.nvn.equls( Arne )) it.remove(); while (it1.hsnext()) { Person p1 = it1.next(); for (Person p2 : h.vlues()){... Fjern siste objekt som ble returnert med next() To måter å gå gjennom lle verdiene (objektene) i h Sortering Lære å løse et vnskelig problem Sortering mnge metoder, her Innstikksortering Sortere hv: Heltll Tekster Lære bstrksjon Når vi hr løst ett problem, kn lignende problemer løses tilsvrende Lære å lge proff progrmvre ved å lge en generell klsse (en vektøyboks) for sortering Hvordn deklrere en slik klsse Jvdoc lge dokumentsjon Testing Hvordn utvikle progrmmet 17 19 import jv.util.*; import esyio.*; clss Hsheksempel { public sttic void min(string[] rgv) { In tsttur = new In(); HshMp <String,Person> personregister = new HshMp <String,Person>(); System.out.print("Antll personer som registreres : "); int nt = tsttur.inint(); for (int i = 0; i < nt; i++) { System.out.println( Gi neste person ); Person p = new Person(tsttur); personregister.put(p.telefonnr, p); // Skriv ut lle personobjektene System.out.println("Viser lle personer" + "(ukjent rekkefølge):"); for (Person p: personregister.vlues()){ p.skrivdt(); Eksempel fr bok s.189 clss Person { String nvn, dresse, telefonnr; Person (In tsttur) { System.out.print("Oppgi nvn : "); nvn = tsttur.inline(); System.out.print("Oppgi dresse : "); dresse = tsttur.inline(); System.out.print("Oppgi telefonnummer : "); telefonnr = tsttur.inline(); void skrivdt() { System.out.println("Nvn : " + nvn); System.out.println("Adresse : " + dresse); System.out.println("Telefonnummer : +telefonnr); String fånvn() { return nvn; Sortering Mnge dttyper kn sorteres Tll Tekster (leksikogrfisk =i smme rekkefølge de ville stått i et leksikon) Tbeller v tekster eller tll Vi må h en lgoritme (fremgngsmåte) for sortering Det finns mnge titlls (hundretlls) metoder for sortering Dere skl lær den som er rskest når vi skl sortere få elementer, si < 50 elementer 20
Hvorfor sorterer vi For å få noen tll i sortert rekkefølge eks: lotto-tllene Sortere tekster (nvnelister) Sortere noen opplysninger som hører smmen. Sorterer d på en v opplysningene. Eks. IKEAktlogen: nvn, produkttype, pris sortert på nvn eller produkttype Eks. Oslo Mrton eller Birken sortert etter :nvn, plssering Sortering brukes hele tiden i dtbsesystemer for å smstille dt fr flere tbeller. Vi ønsker en klsse med to vrinter v sortering: Heltll og tekster public clss ISort { public sttic void sorter(int [] ) { public sttic void sorter(string [] ) { // end clss ISort 21 23 Vi skl først lære å sortere heltll Dette skl vi så med minimle endringer bruke til å sortere: String-rryer (tekster) clss TestInnstikkSortering { Test-progrm for sortering public sttic void min ( String[] rgs) { int [] = {3,1,7,14,2,156,77; String [] nvn = {"Ol", "Kri", "Arne", "Jo"; // sorter heltll - skriv ut ISort.sorter(); for (int i = 0; i <.length; i++) System.out.println( [" + i +"]= " + [i]); System.out.println("\n Test tekst-sortering:"); // sorter Stringer - skriv ut ISort.sorter(nvn); for (int i = 0; i < nvn.length; i++) System.out.println("nvn[" + i +"]= " + nvn[i]); 22
heltlls-rry 3 1 7 14 2 156 77 >jv InnstikkSortering Test v test-progrmmet med tomme sortering-metoder [0]= 3 [1]= 1 [2]= 7 [3]= 14 [4]= 2 [5]= 156 [6]= 77 en-dimensjonl String-rry "Ol "Kri "Arne "Jo" Test tekst-sortering: nvn[0]= Ol nvn[1]= Kri nvn[2]= Arne nvn[3]= Jo nvn En lgoritme for å sortere heltll innstikkmetoden steg 1 Sorter 1 på plss i forhold til 3 3 1 7 14 2 156 77 3 1 7 14 2 156 77 t 1 Se på rryen ett for ett element fr venstre mot høyre Sorterer det vi hittil hr sett på, ved : Hvis det nye elementet vi ser på ikke er sortert i forhold til de vi llerede hr sett på: T ut dette elementet (gjem verdien i en vribel t) Skyv på de ndre elementene vi her sett på en-etter-en, ett hkk høyreover til elemetet i t kn settes ned på sortert plss. D er den delen vi hr sortert ett element lenger (fr venstre) Når vi hr sett på lle elementene, er hele rryen sortert Observsjon : Det første elementet, er det sortert i forhold til seg selv 27 steg 2 3 3 7 14 2 156 77 t 1 steg 3 1 3 7 14 2 156 77 t 1 26
7 og 14 står riktig, Sorter 2 på plss i forhold til : 1,3,7,14 steg 4 1 3 7 14 2 156 77 steg 5 1 3 7 14 2 156 77 steg 6 1 3 7 14 2 156 77 flytt: 14, 7 og så 3 ett hkk til høyre steg 7 1 3 3 7 14 156 77 steg 8 1 2 3 7 14 156 77 public clss ISort { public sttic void sorter(int [] ) { for (int k = 0 ; k <.length-1; k++) { if ([k] > [k+1]) { // [k +1 ] står på feil plss, t den ut int t = [k + 1], i = k; // skyv [i] mot høyre ett hkk til // vi finner riktig plss til t while (i >= 0 && [i] > t) { [i + 1] = [i]; i--; // sett t inn på riktig plss [i + 1] = t; // end heltll-sortering i k+1 Kode for å flytte ett element på plss : 1 7 14 2 156 77 3 // [k +1] står på // feil plss, t den ut int t = [k + 1], i = k; 1 3 3 7 14 156 77 k+1 // skyv [i] mot høyre ett hkk til // vi finner riktig plss til t while (i >= 0 && [i] > t) { [i + 1] = [i]; i--; 1 3 7 14 156 77 2 // sett t inn på riktig plss [i + 1] = t; >jv InnstikkSortering [0]= 1 Resultt v sortering med heltlls-metoden kodet, den ndre uten kode [1]= 2 [2]= 3 [3]= 7 [4]= 14 [5]= 77 [6]= 156 Test tekst-sortering: nvn[0]= Ol nvn[1]= Kri nvn[2]= Arne nvn[3]= Jo i
Sortering v tekster (String) "Ol "Kri "Arne "Jo" Vi skl sortere denne ved å bytte om på pekerne ( slik t [0] peker på Arne,..osv) med innstikkmetoden 33 public sttic void sorter(int [] ) { // Sorterer heltllsrryen ''. for (int k = 0 ; k <.length-1; k++) { if ([k] > [k+1]) { int t = [k + 1]; int i = k; while (i >= 0 && [i] > t) { [i + 1] = [i]; i--; [i + 1] = t; // end heltll-sortering public sttic void sorter(string [] ) { // Sorterer String-rryen ''. for (int k = 0 ; k <.length-1; k++) { if( [k].compreto([k+1]) > 0 ){ String t = [k + 1]; int i = k; while (i >= 0 && ( [i].compreto(t) > 0) ){ [i + 1] = [i]; i--; [i + 1] = t; // end String-sortering Sortere de to første elementene ved å bytte om pekere "Ol "Kri "Arne "Jo" t t = [1]; "Ol "Kri "Arne "Jo" t [1]= [0]; "Ol "Kri "Arne "Jo" t [0]= t; >jv InnstikkSortering [0]= 1 [1]= 2 Test med heltll og enkel String-sortering kodet [2]= 3 [3]= 7 [4]= 14 [5]= 77 [6]= 156 Test tekst-sortering: nvn[0]= Arne nvn[1]= Jo nvn[2]= Kri nvn[3]= Ol Vi hr greid å sortere både heltll og Stringer med smme lgoritme og nesten smme kode
Jvdoc proff dokumentsjon v klssene Legg inn spesielle kommentrer i progrmmet ditt (over hver metode og klsse) I disse kommentrene kn mn legge HTMLkommndoer (som <br> for å få linjeskift) Kjør progrmmet jvdoc, og utomtisk hr du en fin dokumentsjon Største fordel: Kode og dukumentsjon vedlikeholdes på smme fil. Dokumentsjon v klssen og metodene - jvdoc M:\INF1000\ISort>jvdoc -pckge Isort.jv Loding source file Isort.jv... Constructing Jvdoc informtion... Stndrd Doclet version 1.7.0-e Building tree for ll the pckges nd clsses... Generting \ISort.html... Generting \pckge-frme.html... Generting \pckge-summry.html... Generting \pckge-tree.html... Generting \constnt-vlues.html... Building index for ll the pckges nd clsses.. Generting \overview-tree.html... Generting \index-ll.html... Generting \deprected-list.html... Building index for ll clsses... Generting \llclsses-frme.html... Generting \llclsses-nofrme.html... Generting \index.html... Generting \help-doc.html... M:\INF1000\ISort> 37 39 /** * Klsse for sortering etter 'innstikk-metoden', se * Rett på Jv - kp.5.6.<br> * Sortering v heltllsrry, tekster.<br> * * N.B. Bre velegnet for mindre enn 100 elementer. * * Copyright : A.Mus, Univ. i Oslo, 2008 **********************************************************/ public clss ISort { /** * Sorterer heltll i stigende rekkefølge. * @prm heltllsrryen som sorteres. <br> * Endrer prmeter-rryen. ********************************************/ public sttic void sorter(int [] ) { /** * Sorterer String-rryer i stigende leksikogrfisk orden. * @prm rryen som sorteres.<br> * Endrer prmeter-rryen ********************************************/ public sttic void sorter(string [] ) { // end clss ISort