PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP och DSV1:P2

Relevanta dokument
PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP, DSV1:P2 och ITK:P2

PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP, DSV1:P2 och ITK:P2

PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP, DSV1:P2 och ITK:P2

PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP och DSV1:P2

PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP, DSV1:P2 och ITK:P2

SP:PROG3 HT12 Tenta

OOP Tenta

OOP Omtenta

OOP Tentamen

Subklasser och arv Inledning till grafik (JFrame och JPanel). Något om interface. Objektorienterad programvaruutveckling GU (DIT011) Subklasser

Tentamen för kursen Objektorienterad programvaruutveckling GU (DIT010)

ITK:P1 Lektion 4. Lektion 4. Lektion 4. Att implementera en spelidé i Java. DSV Peter Mozelius

TENTAMEN OOP

DAT043 Objektorienterad Programmering

OOP Omtenta

Tentamen Objekt-orienterad programmering med Java, 1DL100 Sommarkurs och distanskurs

OOP Tentamen

Föreläsnings 11 - GUI, Händelsestyrda program, MVC

Kungliga Tekniska Högskolan Ämneskod 2D4134 Nada Tentamensdag maj - 19 Tentamen i Objektorientering och Java Skrivtid 5 h

PROGRAMMERINGSTEKNIK TIN212

OOP Tentamen

Två designmönster, MVC och Observer/Observable. Objektorienterad programvaruutveckling GU (DIT011)

PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP och DSV1:P2

lgammal2.txt // Lösningar till gammal tentamen // Uppgift 1 a

Föreläsning 14: Grafik & mera händelsehantering

Tentamen i Objektorienterad programmering

Programmering för språkteknologer II, HT2014. Rum

OOP Tenta

OOP Exempel Tentamen 2007

DAT043 Objektorienterad programmering för D, DIT011 Objektorienterad programvaruutveckling för GU

Lösningsförslag till tentamen

Lösningsförslag till tentamen

OBJEKTORIENTERAD PROGRAMVARUUTVECKLING. Övningstentamen 1

Tentamen, EDA501/EDAA20 Programmering M MD W BK L

Tentamen OOP

Lösningsförslag till tentamen

Detta dokument är ett exempel, cirka andra hälften av en tentamen för TDA545 Objektorienterad programvaruutveckling

Lösningar för tenta 3 DAT043,

TENTAMEN I PROGRAMMERING. På tentamen ges graderade betyg:. 3:a 24 poäng, 4:a 36 poäng och 5:a 48 poäng

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

TENTAMEN OOP

Lösningsförslag tentamen FYTA11 Java

Laboration 24 Databasen MySQL och java

Frivillig Java-swing-Graphics-lab Programmeringsteknik MN1 vt02

Tentamen i Programmering

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Exempel på listor (klassen ArrayList). Ett exempel med fält. Avbildning är en speciell typ av lista HashMap.

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

Tentamen FYTA11 Javaprogrammering

Denna vecka. Idag. Grafiskt användarsnitt. Vi kommer att se

DI-institutionen Sid 1 av 6 Hans-Edy Mårtensson Sten Sundin

Tentamen i Objektorienterad programmering

OOP Omtenta

Tentamen för kursen Objektorienterad programvaruutveckling GU (DIT010)

Lösningar till Fiktiv Tentamen på kursen. 2D4135 Objektorienterad programmering, design och analys med Java vt2004. Teoridel

Dagens program. Programmeringsteknik och Matlab. Vad är arv? Vi ärver från GregorianCalendar. Kan vi bygga vidare på existerande klasser?

Föreläsning 12. Föreläsning 12. Rörliga figurer Klassen Timer Undantag Något om applets. Rörliga appletsfigurer Klassen Timer Undantag

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

MVC-mönstret. model-view-control i Swing

Lösningsförslag till tentamen FYTA11 Javaprogrammering

TENTAMEN OOP

Tentamen FYTA11 Javaprogrammering

Lösningsförslag till tentamen

Exempel på användning av arv: Geometriska figurer

Omtentamen för TDA540 Objektorienterad Programmering. Institutionen för Datavetenskap CTH HT-17, TDA540. Dag: , Tid:

Tentamen i EDAF25. 1 juni Skrivtid: Skriv inte med färgpenna enda tillåtna färg är svart/blyerts.

Lösningsförslag till tentamen i EDA011/EDA017 Programmeringsteknik för F, E, I, π och N 25 maj 2009

OOP Omtenta

Tentamen, EDAA10 Programmering i Java

Programmeringsteknik II - HT18. Föreläsning 6: Grafik och händelsestyrda program med användargränssnitt (och Java-interface) Johan Öfverstedt

Kungliga Tekniska Högskolan Ämneskod 2D4134 Nada Tentamensdag aug - 23 Tentamen i Objektorientering och Java Skrivtid 5 h

Tentamen. Lösningsförslag

kl

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Interfacen Set och Map, hashtabeller

ITK:P1 Föreläsning 4. Grafiska gränssnitt i Java. AWT-komponenter

Tentamen i Grundläggande programmering STS, åk 1 fredag

Malmö högskola 2008/2009 CTS

Föreläsning 14 Innehåll

Repetitionsföreläsning 2: Quiz & problemlösning med swing Inget nytt material.

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Tentamen i Programmeringsteknik I, ES,

Tentamen i Grundläggande programmering STS, åk 1 fredag

Vad handlar kursen om? Algoritmer och datastrukturer. Vad handlar kursen om? Vad handlar kursen om?

2 b) Följande finns definierat: public class Käk String titel = "Chili con carne"; Krydda[] kryddor = new Krydda[10]; kryddor[0] = new Krydda("Svartpe

Tentamen Objekt-orienterad programmering i Java, 5p distanskurs

Parsing med Recursive Descent, Avbildningsklasser. Syntaxdiagram. Syntaxdiagram och kodning expression. Betrakta följande uttryck

Laboration 13, Arrayer och objekt

Tentamen Datastrukturer (DAT037)

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Föreläsning 7. Träd och binära sökträd

Föreläsning 5-6 Innehåll

Malmö högskola 2007/2008 Teknik och samhälle

OBJEKTORIENTERAD PROGRAMVARUUTVECKLING

TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 2

Lösningsförslag till tentamen

Föreläsning 3: Abstrakta datastrukturer, kö, stack, lista

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Transkript:

DSV SU/KTH sid 1 (6) PROG2 HT12 PROG2 Tenta 2013-03-09 Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP och DSV1:P2 Tentan består av tre uppgifter. Max poäng är 38. För betyget E (godkänd) krävs minst 23 poäng och minst en poäng på varje uppgift. Betygen A-D ges enligt betygskriteria i Daisy och på omstående sida. Hjälpmedel: Tillåtna hjälpmedel är medhavda böcker om Java. Anvisningar: Skriv endast på ena sidan av bladen. Påbörja varje ny uppgift på nytt blad. Skriv tydligt - oläsbara svar beaktas inte. Även icke fullständiga lösningar beaktas. Kommentera gärna era lösningar. Lösningsförslag kommer att presenteras i delkursens FC-konferens. Lycka till!

DSV SU/KTH sid 2 PROG2 Tentan betygsätts i A/B/C/D/E/Fx/F-skalan enligt följande kriteria: A - Samtliga lösningar är felfria (förutom uppenbara små misstag), fullständiga, genomförda med användning av de på kursen presenterade Java-teknikerna och lämpliga klasser/metoder ur Javas standardbibliotek och med kod som är klar, effektiv och inte onödigt omständlig. Lösningarna tar hänsyn till alla i uppgiftstexten angivna situationer och innehåller alla i uppgiftstexten begärda felkontroller. Däremot behöver de inte innehålla andra felkontroller eller ta hänsyn till andra situationer än de som angetts i uppgiftstexten. B - Som för betyget A utom att någon eller ett par lösningar kan innehålla något grövre misstag eller underlåta att ta hänsyn till någon enstaka angiven situation eller någon enstaka begärd felkontroll. Lösningarna kan vara något mer omständliga än nödvändigt. C - Lösningarna är i princip korrekta men kan vara behäftade med fel och/eller underlåta att ta hänsyn till någon enstaka angiven situation eller begärd felkontroll. Lösningarna kan vara mer omständliga än nödvändigt (t.ex. skrivna med egen kod där standardklasser/-metoder kunde ha använts). D - Som för betyget C utom att någon eller ett par lösningar kan innehålla grövre fel av principiell karaktär. Lösningarna kan även innehålla grövre syntaktiska misstag (t.ex. sammanblandning med andra språk med liknande syntax). E - Som för betyget D utom att de flesta eller alla lösningar är behäftade med grövre fel av principiell karaktär. Icke desto mindre måste lösningarna visa grundläggande förståelse för problemet och åtminstone en ansats till korrekt lösning. Fx - En lösning är helt felaktig eller saknas medan de övriga lösningar är i princip korrekta, men kan vara behäftade med fel och/eller underlåta att ta hänsyn till någon enstaka angiven situation eller begärd felkontroll. F - Flera lösningar är helt felaktiga eller saknas. Betyget Fx innebär att studenten kan komplettera examinationen med en extra inlämningsuppgift för att få godkänt på aktuell tentamen (E men ej högre betyg). Kompletteringsuppgiften måste lämnas in enligt angiven deadline och kan endast användas för att få betyget E på den aktuella tentan.

DSV SU/KTH sid 3 PROG2 Uppgift 1 (13 poäng) Denna uppgift går ut på att komplettera ett program som visar en karta över ett kontor och kan visa var personer som valts i en lista sitter. Programmet skapar ett fönster som kan se ut så här: Kartan är en bild som har lästs in från en fil - hårdkodad i programmet (se koden nästa sida). Till vänster finns en JList som innehåller namn på personer som har sina arbetsrum på kontoret även dessa är hårdkodade i programmet. Knappen Ange är tänkt att användas av en administratör som kan välja ett namn i listan, klicka på knappen Ange och sedan klicka på kartan, varvid programmet kommer ihåg positionen där den valda personen sitter. Programmet ritar också en röd cirkel kring denna position (syns som en svart cirkel ovan, uppe till vänster, just under texten Game lab ). Klickar man på kartan utan att just ha klickat på knappen Ange så ska ingenting hända. Knappen Visa används av besökare: de kan välja ett namn i listan och klicka på Visa, och då visas cirkeln på kartan på den plats som sparats tidigare vid Ange. Tänk inte på några behörighetskontroller för knappen Ange, vi låtsas som att ingen obehörig någonsin skulle komma på tanken att använda denna knapp. Om ingen är vald i listan när man klickar på en knapp ska en meddelanderuta med ett felmeddelande visas. Om man klickar på knappen Visa och den valda personen inte har fått någon plats ska meddelandet Ingen plats angiven! visas i en meddelanderuta. Om man klickar på knappen Ange och anger en ny plats för en person som redan har fått en plats så är det den nya platsen som gäller i fortsättningen (en person kan ha högst en plats). På nästa sidan finns koden för klassen Karta som du ska komplettera. Det är kodat i Java 6 men du kan koda i Java 7 om du föredrar det. I Java 7 skulle rad 34 se ut så här: JList<String> folklist = new JList<String>(namn);

DSV SU/KTH sid 4 PROG2 Nedan finns koden till klassen Karta som du ska modifiera/komplettera (radnumreringen ingår inte i koden, den är till för att du enkelt skall kunna förklara var du gör tillägg/ändringar). 1 import javax.swing.*; 2 import java.awt.*; 3 import java.util.*; 4 5 class KartPanel extends JPanel{ 6 private ImageIcon bild = new ImageIcon("plan6.png"); 7 private int x, y; 8 private boolean visas = false; 9 protected void paintcomponent(graphics g){ 10 super.paintcomponent(g); 11 g.drawimage(bild.getimage(), 0,0, this); 12 if (visas){ 13 g.setcolor(color.red); 14 g.filloval(x-10,y-10,15,15); 15 16 17 public void setxy(int x, int y){ 18 this.x = x; 19 this.y = y; 20 21 public void setvisas(boolean b){ 22 visas = b; 23 repaint(); 24 25 26 class Karta extends JFrame{ 27 String[] namn = {"Andrea", "Bea", "Birger", "Björn", "Dan", "David", 28 "Elin", "Gustaf", "Henrik", "Ilja", "Jozef", "Lena", 29 "Leon", "Louise", "Maria", "Martin", "Matts", "Patrik", 30 "Paul", "Stefan", "Stewart", "Tessi"; 31 Karta(){ 32 JPanel höger = new JPanel(); 33 add(höger, BorderLayout.WEST); 34 JList folklist = new JList(namn); 35 folklist.setvisiblerowcount(20); 36 höger.add(new JScrollPane(folkList)); 37 KartPanel kp = new KartPanel(); 38 add(kp, BorderLayout.CENTER); 39 JPanel knapppanel = new JPanel(); 40 add(knapppanel, BorderLayout.SOUTH); 41 knapppanel.add(new JButton("Visa")); 42 knapppanel.add(new JButton("Ange")); 43 setdefaultcloseoperation(exit_on_close); 44 setsize(630, 450); 45 setvisible(true); 46 47 public static void main(string[] args){ 48 new Karta(); 49 50

DSV SU/KTH sid 5 PROG2 Uppgift 2 (12 poäng) I ett Java-program som ska hålla reda på passagerarlistor på flygplan har man följande klass för att representera en plats i flygplanet: public class Plats{ private int rad; private String stol; public Plats(int rad, String stol){ if (rad < 1 rad > 30!(stol.equals("A") stol.equals("b") stol.equals("c") stol.equals("d") stol.equals("e"))) throw new IllegalArgumentException(); this.rad = rad; this.stol = stol; public int getrad(){ return rad; public String getstol(){ return stol; public String tostring(){ return "" + rad + stol; En plats identifieras alltså av radnummer och inom raden av en bokstavsbeteckning A till E. a) Man vill kunna representera en passagerarlista med hjälp av en TreeMap med Platsobjekt som nycklar och passagerarnas namn (String) som värden. Förbered klassen Plats för att dessa objekt ska kunna användas som nycklar i en TreeMap. b) Skriv en metod som tar en sådan TreeMap som argument och skriver ut passagerarlistan (med plats och namn för varje passagerare) på System.out sorterad i platsnummerordning c) Skriv en metod som tar en sådan TreeMap som argument och skriver ut passagerarlistan (med plats och namn för varje passagerare) på System.out sorterad i alfabetisk ordning efter passagerarnas namn

DSV SU/KTH sid 6 PROG2 Uppgift 3 (13 poäng) I många tillämpningar händer det att man har objekt som alternativt kan identifieras med två nycklar och där sökning efter båda nycklarna är lika viktig (t.ex. personer i ett kundregister som ska kunna sökas med hjälp av personnummer eller kundnummer). Denna uppgift går ut på att skriva ett gränssnitt (interface) DoubleKeyMap<K1,K2,V> och en implementerande klass DoubleKeyHashMap<K1, K2, V> för sådana ändamål. En DoubleKeyMap tänks ha följande metoder - put som tar tre argument: första nyckeln, andra nyckeln och värdet. Metoden ska stoppa in nycklarna och värdet i datastrukturen. Om det redan finns ett värde för någon av nycklarna så ersätts det gamla värdet med det nya. Metoden returnerar ingenting. - getbyfirstkey - tar första nyckeln och returnerar värdet för denna nyckel eller null om det inte finns. - getbysecondkey - tar andra nyckeln och returnerar värdet för denna nyckel eller null om det inte finns - firstkeyset - returnerar mängden av alla första-nycklar - secondkeyset - returnerar mängden av alla andra-nycklar - values - returnerar samlingen av all värden Den implementerande klassen DoubleKeyHashMap implementeras enklast genom att man internt har två HashMap:ar som håller reda på värdena identifierade med var sin nyckeln. Man kan tänka sig att en tillämpning skulle kunna använda detta på följande sätt (tänk att man här har kundernas namn som första nyckel, kundnummer som andra nyckel och att värdena utgörs av kundernas saldo): class KundReg{ public static void main(string[] args){ DoubleKeyMap<String, Integer, Integer> kunder = new DoubleKeyHashMap<String, Integer, Integer>(); kunder.put("jozef", 1234, 300); kunder.put("stefan", 2345, 500); kunder.put("jonathan", 3456, 100); int saldo1 = kunder.getbyfirstkey("jozef"); int saldo2 = kunder.getbysecondkey(2345); int summa = 0; for(integer ig : kunder.values()) summa += ig; System.out.println("Totalt: " + summa);

Lösningsförslag PROG2 HT12 tenta 2013-03-09 Uppgift 1 Kommentar: för att spara positionen på kartan för var personer sitter behöver man en Map där namnet är nyckeln och positionen värdet. Men positionen består av två värden koordinaterna x och y. Dessa behöver förpackas på något sätt för att kunna läggas som värden i Map:en. I lösningen nedan använder jag klassen Point från java.awt - man kan även konstruera en egen klass för detta eller använda någon lämplig datastruktur, eller "packa" koordinaterna i ett heltal genom någon aritmetisk operation m.fl. möjliga lösningar. import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; class KartPanel extends JPanel{ private ImageIcon bild = new ImageIcon("plan6.png"); private int x, y; private boolean visas = false; protected void paintcomponent(graphics g){ super.paintcomponent(g); g.drawimage(bild.getimage(), 0,0, this); if (visas){ g.setcolor(color.red); g.filloval(x-10,y-10,15,15); public void setxy(int x, int y){ this.x = x; this.y = y; public void setvisas(boolean b){ visas = b; repaint(); class Karta extends JFrame{ String[] namn = {"Andrea","Bea","Birger","Björn","Dan","David","Elin", "Gustaf","Henrik","Ilja","Jozef","Lena","Leon","Louise", "Maria","Martin","Matts","Patrik","Paul","Stefan", "Stewart","Tessi"; KartPanel kp = new KartPanel(); JList folklist = new JList(namn); Map<String, Point> where = new HashMap<String,Point>(); Karta(){ JPanel höger = new JPanel(); add(höger, BorderLayout.WEST); folklist.setvisiblerowcount(20); höger.add(new JScrollPane(folkList)); add(kp, BorderLayout.CENTER); JPanel knapppanel = new JPanel(); add(knapppanel, BorderLayout.SOUTH); JButton visaknapp = new JButton("Visa"); knapppanel.add(visaknapp); visaknapp.addactionlistener(new VisaLyss()); JButton angeknapp = new JButton("Ange"); knapppanel.add(angeknapp); angeknapp.addactionlistener(new AngeLyss()); setdefaultcloseoperation(exit_on_close); setsize(630, 450); setvisible(true);

Lösningsförslag PROG2 HT12 Tenta 2013-03-09 class AngeLyss implements ActionListener{ public void actionperformed(actionevent ave){ kp.setvisas(false); kp.addmouselistener(new MusLyss()); class MusLyss extends MouseAdapter{ public void mouseclicked(mouseevent mev){ if (folklist.isselectionempty()){ JOptionPane.showMessageDialog(Karta.this, "Ingen vald!"); return; String vem = (String)folkList.getSelectedValue(); int x = mev.getx(); int y = mev.gety(); where.put(vem, new Point(x,y)); kp.setxy(x, y); kp.setvisas(true); kp.removemouselistener(this); class VisaLyss implements ActionListener{ public void actionperformed(actionevent ave){ if (folklist.isselectionempty()){ JOptionPane.showMessageDialog(Karta.this, "Ingen vald!"); return; String vem = (String)folkList.getSelectedValue(); Point p = where.get(vem); if (p == null){ JOptionPane.showMessageDialog(Karta.this, "Ingen plats!"); return; kp.setxy(p.x, p.y); kp.setvisas(true); public static void main(string[] args){ new Karta();

Lösningsförslag PROG2 HT12 Tenta 2013-03-09 Uppgift 2 a) public class Plats implements Comparable<Plats>{ private int rad; private String stol; public Plats(int rad, String stol){ if (rad < 1 rad > 30!(stol.equals("A") stol.equals("b") stol.equals("c") stol.equals("d") stol.equals("e"))) throw new IllegalArgumentException(); this.rad = rad; this.stol = stol; public int getrad(){ return rad; public String getstol(){ return stol; public String tostring(){ return "" + rad + stol; public int compareto(plats other){ if (rad < other.rad) return -1; else if (rad > other.rad) return 1; else return stol.compareto(other.stol); b) static void passagerarlistaperplats(treemap<plats, String> plista){ for(map.entry<plats, String> me : plista.entryset()) System.out.println(me.getKey() + "\t" + me.getvalue());

Lösningsförslag PROG2 HT12 Tenta 2013-03-09 c) Kommentar: en generell lösning (som ger ett mönster som skulle kunna användas till annat än utskrifter) går ut på att man tar ut platsbeteckningar och namnen ur Map:en och lägger dem i en lista, sorterar om listan och sedan går igenom den sorterade listan. Då måste platsen och namnet packas ihop i objekt av någon klass, t.ex. klassen PlatsOchNamn nedan. Om en lista med sådana objekt ska kunna sorteras så måste PlatsOchNamn göras Comparable eller så får man skapa en fristående Comparator för den. Jag väljer en fristående Comparator för det skulle kännas konstigt att göra en comparetometod som ignorerar ett av attributen i klassen. Se längre ner för en enklare lösning. class PlatsOchNamn{ private Plats plats; private String namn; public PlatsOchNamn(Plats plats, String namn){ this.plats = plats; this.namn = namn; public String getnamn(){ return namn; public String tostring(){ return plats + ": " + namn; class NamnCMP implements Comparator<PlatsOchNamn>{ public int compare(platsochnamn pon1, PlatsOchNamn pon2){ return pon1.getnamn().compareto(pon2.getnamn()); static void passagerarlistapernamn(treemap<plats,string> plista){ ArrayList<PlatsOchNamn> lista = new ArrayList<PlatsOchNamn>(); for(map.entry<plats, String> me : plista.entryset()) lista.add(new PlatsOchNamn(me.getKey(), me.getvalue())); Collections.sort(lista, new NamnCMP()); for(platsochnamn pon : lista) System.out.println(pon); I tentauppgiften är det explicit angivet att metoden skulle användas för utskrift, så då kan man göra en mycket enklare lösning genom att vid genomgången av Map:en skapa strängar innehållande strängrepresentationen av platsbeteckning och namnet (helt enkelt de rader som ska skrivas ut) och sortera dessa strängar ser man till att namnet står först så blir de sorterade i namnordning: static void passagerarlistapernamn(treemap<plats,string> plista){ ArrayList<String> lista = new ArrayList<String>(); for(map.entry<plats, String> me : plista.entryset()) lista.add("" + me.getvalue() + "\t" + me.getkey()); Collections.sort(lista); for(string rad : lista) System.out.println(rad);

Lösningsförslag PROG2 HT12 Tenta 2013-03-09 Uppgift 3 import java.util.*; public interface DoubleKeyMap<K1, K2, V>{ void put(k1 firstkey, K2 secondkey, V value); V getbyfirstkey(k1 key); V getbysecondkey(k2 key); Set<K1> firstkeyset(); Set<K2> secondkeyset(); Collection<V> values(); I implementeringen av metoden put nedan borde man egentligen kolla att firstkey och secondkey stämmer: de får antingen båda vara null (då skapas en ny post) eller så får ingen av dem vara null och deras värden måste vara samma som angavs tidigare (t.ex. kan man inte ha samma personnr med ett annat kundnr och vice versa). En sådan kontroll skulle kunna göras med två till interna Map:as, en Map<K1, K2> och en Map<K2, K1>. Det begärdes ingen sådan kontroll på tentan så jag gör den inte i lösningsförslaget. import java.util.*; public class DoubleKeyHashMap<K1, K2, V> implements DoubleKeyMap<K1,K2,V>{ private Map<K1, V> firstmap = new HashMap<K1, V>(); private Map<K2, V> secondmap = new HashMap<K2, V>(); public void put(k1 firstkey, K2 secondkey, V value){ firstmap.put(firstkey, value); secondmap.put(secondkey, value); public V getbyfirstkey(k1 key){ return firstmap.get(key); public V getbysecondkey(k2 key){ return secondmap.get(key); public Set<K1> firstkeyset(){ return firstmap.keyset(); public Set<K2> secondkeyset(){ return secondmap.keyset(); public Collection<V> values(){ return firstmap.values();