Methodiek van de informatica Dani¨el Slenders Faculteit Ingenieurswetenschappen Katholieke Universiteit Leuven Academiejaar 2009 - 2010
Inhoudsopgave Oefenzitting 1
3
Oefening 2.57 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
Oefening 2.58 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
Oefening 2.76 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Oefening 2.82 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Oefening 2.83 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Oefenzitting 2
17
Oefening 3.31 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Oefening 3.32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Oefening 4.17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Oefening 4.18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Oefening 4.19 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Oefening 4.34 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Oefenzitting 3
34
Oefening 4.35 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Oefening 4.28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Oefening 4.29 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Oefenzitting 4
54
Oefening 5.14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 Oefening 5.16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Oefening 5.17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 Oefening 5.25 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Oefening 5.28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Oefening 5.30 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
2
Oefenzitting 1 Oefening 2.57 Vraag Pas de methode printTicket aan zodat deze een lokale variabele, amountLeftToPay, declareert. Deze moet worden ge¨ınitialiseerd om het verschil tussen price en balance op te slaan. Pas de test in het conditionele statement aan om de waarde van amountLeftToPay te controleren. Als de waarde ervn kleiner of gelijk is aan nul moet de automat een kaartje afdrukken. Als dat niet het geval is, moet de automaat een foutmelding afdrukken met daarin het nog te betalen bedrag. Test je versie om er zeker van te zijn dat deze precies zo werkt als de oorspronkelijke versie.
Oplossing Om de nieuwe, lokale, variabele amountLeftToPay te defini¨ere kunnen we de volgende code gebruiken: int amountLeftToPay; De waarde hiervan moet gelijk zijn aan het verschil tussen price en balance. Dit geeft: amountLeftToPay = price - balance; We kunnen de twee vorige commando’s ook combineren tot het volgende: int amountLeftToPay = price - balance; Als deze waarde negatief is, wil dit zeggen dat er genoeg geld in de automaat gestopt is. Er mag dus een ticket afgeprint worden. Anders moet de automaat een foutmelding geven en het resterende bedrag vermelden. Dit geeft de volgende code: if(amountLeftToPay <= 0) { // Simulate the printing of a ticket. System.out.println("##################"); System.out.println("# The BlueJ Line");
3
System.out.println("# Ticket"); System.out.println("# " + price + " cents."); System.out.println("##################"); System.out.println(); // Update the total collected with the price. total = total + price; // Reduce the balance by the prince. balance = balance - price; } else { System.out.println("You must insert at least: " + amountLeftToPay + " more cents."); } De broncode van het hele programma wordt dan: /** * TicketMachine models a ticket machine that issues * flat-fare tickets. * The price of a ticket is specified via the constructor. * Instances will check to ensure that a user only enters * sensible amounts of money, and will only print a ticket * if enough money has been input. * * @author D. Slenders * @version 2010.02.11 */ public class TicketMachine { // The price of a ticket from this machine. private int price; // The amount of money entered by a customer so far. private int balance; // The total amount of money collected by this machine. private int total; /** * Create a machine that issues tickets of the given price. */ public TicketMachine(int ticketCost) { price = ticketCost; balance = 0; total = 0; }
4
/** * @Return The price of a ticket. */ public int getPrice() { return price; } /** * Return The amount of money already inserted for the * next ticket. */ public int getBalance() { return balance; } /** * Receive an amount of money in cents from a customer. * Check that the amount is sensible. */ public void insertMoney(int amount) { if(amount > 0) { balance = balance + amount; } else { System.out.println("Use a positive amount: " + amount); } } /** * Print a ticket if enough money has been inserted, and * reduce the current balance by the ticket price. Print * an error message if more money is required. */ public void printTicket() { int amountLeftToPay = price - balance; if(amountLeftToPay <= 0) { // Simulate the printing of a ticket. System.out.println("##################"); System.out.println("# The BlueJ Line"); System.out.println("# Ticket"); System.out.println("# " + price + " cents."); System.out.println("##################"); System.out.println();
5
// Update the total collected with the price. total = total + price; // Reduce the balance by the prince. balance = balance - price; } else { System.out.println("You must insert at least: " + amountLeftToPay + " more cents."); } } /** * Return the money in the balance. * The balance is cleared. */ public int refundBalance() { int amountToRefund; amountToRefund = balance; balance = 0; return amountToRefund; } }
Oefening 2.58 Vraag Veronderstel dat we ´e´en TicketMachine-object willen hebben dat kaartjes met verschillende prijzen kan produceren. Een gebruiker van de machine kan bijvoorbeeld door op een knop op de machine te drukken, aangeven welk kaartje hij/zij wil hebben. Welke methodes en/of velden moeten nog worden toegevoegd aan TicketMachine om dit mogelijk te maken? Denk je dat daarvoor ook veel van de bestaande methodes aangepast moeten worden? Sla het project better-ticket-machine op onder een nieuwe naam en implementeer je wijzingen in het nieuwe project.
Oplossing Stel het aantal kaartjes gelijk aan 3. Dan defini¨eren we de prijs van elk kaartje respectievelijk als volgt: price1, price2, price3. Welk kaartje men moet hebben, wordt gedefinieerd door ticket. Als we dit toevoegen aan de broncode van TicketMachine, wordt dat: // The price of a ticket from this machine. private int price1; private int price2;
6
private int price3; private int price; // The amount of money entered by a customer so far. private int balance; // The total amount of money collected by this machine. private int total; // Which ticket. private int ticket; Bij het maken van de machine, moeten de prijzen van de verschillende kaartjes gevraagd worden. Dit wordt dus: public TicketMachine(int ticket1Cost, int ticket2Cost, int ticket3Cost) { price1 = ticket1Cost; price2 = ticket2Cost; price3 = ticket3Cost; balance = 0; total = 0; ticket = 1; price = price1; } Hierbij wordt standaard het eerste kaartje gekozen. Om dit te veranderen moeten we de volgende methode toevoegen: public void chooseTicket(int whichTicket) { if((whichTicket > 0) && (whichTicket < 4)) { ticket = whichTicket; if(ticket==1) { price = price1; } if(ticket==2) { price = price2; } if(ticket==3) { price = price3; } } else {
7
System.out.println("You must choose a valid ticket."); } } De broncode van het hele programma wordt dan: /** * TicketMachine models a ticket machine that issues * flat-fare tickets. * The price of a ticket is specified via the constructor. * Instances will check to ensure that a user only enters * sensible amounts of money, and will only print a ticket * if enough money has been input. * This program is capable of using three different types of tickets. * * @author D. Slenders * @version 2010.02.11 */ public class TicketMachine { // The price of a ticket from this machine. private int price1; private int price2; private int price3; private int price; // The amount of money entered by a customer so far. private int balance; // The total amount of money collected by this machine. private int total; // Which ticket private int ticket; /** * Create a machine that issues tickets of the given price. */ public TicketMachine(int ticket1Cost, int ticket2Cost, int ticket3Cost) { price1 = ticket1Cost; price2 = ticket2Cost; price3 = ticket3Cost; balance = 0; total = 0; ticket = 1; price = price1; } /** * Choose ticket. */
8
public void chooseTicket(int whichTicket) { if((whichTicket > 0) && (whichTicket < 4)) { ticket = whichTicket; if(ticket==1) { price = price1; } if(ticket==2) { price = price2; } if(ticket==3) { price = price3; } } else { System.out.println("You must choose a valid ticket."); } } /** * @Return The price of a ticket. Prices are separated by a ";". */ public int getPrice() { return price; } /** * Return the type of ticket. */ public int getTicket() { return ticket; } /** * Return The amount of money already inserted for the * next ticket. */ public int getBalance() { return balance; }
9
/** * Receive an amount of money in cents from a customer. * Check that the amount is sensible. */ public void insertMoney(int amount) { if(amount > 0) { balance = balance + amount; } else { System.out.println("Use a positive amount: " + amount); } } /** * Print a ticket if enough money has been inserted, and * reduce the current balance by the ticket price. Print * an error message if more money is required. */ public void printTicket() { int amountLeftToPay = price - balance; if(amountLeftToPay <= 0) { // Simulate the printing of a ticket. System.out.println("##################"); System.out.println("# The BlueJ Line"); System.out.println("# Ticket" + ticket); System.out.println("# " + price + " cents."); System.out.println("##################"); System.out.println(); // Update the total collected with the price. total = total + price; // Reduce the balance by the prince. balance = balance - price; } else { System.out.println("You must insert at least: " + amountLeftToPay + " more cents."); } } /** * Return the money in the balance. * The balance is cleared. */ public int refundBalance()
10
{ int amountToRefund; amountToRefund = balance; balance = 0; return amountToRefund; } }
Oefening 2.76 Vraag Voeg twee methodes, printAuthor en printTitle, toe aan de beknopte weergave van de klasse Book. Deze methodes moeten de inhoud van de velden author en title afdrukken naar het terminalvenster.
Oplossing De gevraagde methodes moeten een string weergeven. Dit wordt dus: public String printAuthor() { return author; } public String printTitle() { return title; } De broncode van het hele programma wordt dan: /** * A class that maintains information on a book. * This might form part of a larger application such * as a library system, for instance. * * @author D. Slenders * @version 2010.02.12 */ class Book { // The fields. private String author; private String title;
11
/** * Set the author and title fields when this object * is constructed. */ public Book(String bookAuthor, String bookTitle) { author = bookAuthor; title = bookTitle; } /** * Returns the author. */ public String printAuthor() { return author; } /** * Returns the title. */ public String printTitle() { return title; } }
Oefening 2.82 Vraag Voeg nog een geheelgetalveld, borrowed, toe aan de klasse Book. Dit veld houdt bij hoe vaak een boek uitgeleend werd. Voeg een mutator, borrow, toe aan de klasse. Deze moet de waarde van het veld telkens wanneer de methode wordt aangeroepen, met 1 verhogen. Voeg een accessor, getBorrowed, toe, die de waarde van dit nieuwe veld als resultaat retourneert. Pas printDetails aan zodat deze ook de waarde van dit veld met een verklarende tekst afdrukt.
Oplossing Allereerst moet er het geheelgetalveld borrowed toegevoegd worden. Dit gebeurt met het volgende commande: private int borrowed; De waarde hiervan moet op nul gezet worden, dus voeg aan de constructor Book de volgende regel toe:
12
borrowed = 0; De mutator borrow moet de waarde van borrowed met ´e´en verhogen. Dit gebeurt met de volgende code: public void borrow() { borrowed++; } De accessor getBorrowed moet de waarde van borrowed tonen. Dit gebeurt op de volgende manier: public int getBorrowed() { return borrowed; } De details van het boek worden met de volgende code weergegeven: public void printDetails() { System.out.println("Author: "+author); System.out.println("Title: "+title); System.out.println("Number of times borrowed: "+borrowed); } De broncode van het hele programma wordt dan: /** * A class that maintains information on a book. * This might form part of a larger application such * as a library system, for instance. * * @author D. Slenders * @version 2010.02.12 */ class Book { // The fields. private String author; private String title; private int borrowed; /** * Set the author, the title and the borrowed fields when this * object is constructed. */
13
public Book(String bookAuthor, String bookTitle) { author = bookAuthor; title = bookTitle; borrowed = 0; } /** * Returns the author. */ public String printAuthor() { return author; } /** * Returns the title. */ public String printTitle() { return title; } /** * Increases the value of borrowed the 1. */ public void borrow() { borrowed++; } /** * Returns the number of times borrowed. */ public int getBorrowed() { return borrowed; } /** * Returns the details of the book. */ public void printDetails() { System.out.println("Author: "+author); System.out.println("Title: "+title); System.out.println("Number of times borrowed: "+borrowed); } }
14
Oefening 2.83 Vraag Maak een nieuw project binnen BlueJ aan, heaterexercise. Verander de informatie in de projectomschrijving - de tekst die je ziet in het schema. Maak een klasse, Heater, die ´e´en geheelgetalveld, temperature, bevat. Definieer een constructor die zonder parameters werkt. Het veld temperature moet in de constructor worden ingesteld op de waarde 15. Definieer de mutators warmer en cooler waarmee de waarde van temperature met 5◦ C wordt verhoogd respectievelijk verlaagd. Definieer een accessormethode die de waarde van temperature retourneert.
Oplossing In de klasse Heater moet het veld Temperature aangemaakt worden. Dit gebeurt met het volgende commando: private int temperature; In de constructor moet de waarde van temperature ingesteld worden. Als we Java de initi¨ele waarde laten vragen, gebeurt dat met de volgende code: public Heater(int initialTemperature) { temperature = initialTemperature; } Om de mutators warmer en cooler de waarde van temperature te laten veranderen met 5◦ C, hebben we de volgende code nodig: public void warmer() { temperature = temperature + 5; } public void cooler() { temperature = temperature - 5; } Om de waarde van temperature weer te geven hebben we de volgende accessor nodig: public int getTemperature() { return temperature; }
15
De broncode van het hele programma wordt dan: /** * A class that maintains information on the temperature. * * @author D. Slenders * @version 2010.02.12 */ public class Heater { private int temperature; /** * Set the temperature when the object is created. */ public Heater(int initialTemperature) { temperature = initialTemperature; } /** * Increases the temperature with 5 degrees. */ public void warmer() { temperature = temperature + 5; } /** * Decreases the temperature with 5 degrees. */ public void cooler() { temperature = temperature - 5; } /** * Returns the value of temperature; */ public int getTemperature() { return temperature; } }
16
Oefenzitting 2 Oefening 3.31 Vraag Verander de klok van een 24-uursklok in een 12-uursklok. Pas op, dit is minder gemakkelijk dan het op het eerste gezicht lijkt. Bij een 12-uursklok worden de uren na middernacht en na de middag niet weergegeven als 00 : 30 maar als 12 : 30. Het minutendisplay toont waarden van 0 tot en met 59, maar de urenaanduiding toont waarden van 1 tot en met 12!
Oplossing De waarde van de uren moet met ´e´en beginnen. Hiervoor passen we de constructor van de ClockDisplay als volgt aan: public ClockDisplay() { hours = new NumberDisplay(13); minutes = new NumberDisplay(60); hours.setValue(1); updateDisplay(); } De methode van het verhogen van de tijd moet ook aangepast worden zodat hour in een 1 veranderd zodra deze 0 wordt: public void timeTick() { minutes.increment(); if(minutes.getValue() == 0) { hours.increment(); } if(hours.getValue() == 0){ hours.increment(); } updateDisplay(); }
// it just rolled over!
17
De constructor waar men zelf de tijd kan ingeven, moet nog zodanig aangepast worden dat het uur nul verandert in 12. Dit geeft dus: public ClockDisplay(int hour, int minute) { hours = new NumberDisplay(13); minutes = new NumberDisplay(60); if(hour == 0) { hour = 12; } setTime(hour, minute); } De broncode van het hele programma wordt dan: /** * The ClockDisplay class implements a digital clock display for a * European-style 12 hour clock. The clock shows hours and minutes. The * range of the clock is 01:00 to 12:59. * * The clock display receives "ticks" (via the timeTick method) every minute * and reacts by incrementing the display. This is done in the usual clock * fashion: the hour increments when the minutes roll over to zero. * * @author D. Slenders * @version 2010.02.13 */ public class ClockDisplay { private NumberDisplay hours; private NumberDisplay minutes; private String displayString; // simulates the actual display /** * Constructor for ClockDisplay objects. This constructor * creates a new clock set at 01:00. */ public ClockDisplay() { hours = new NumberDisplay(13); minutes = new NumberDisplay(60); hours.setValue(1); updateDisplay(); } /** * Constructor for ClockDisplay objects. This constructor * creates a new clock set at the time specified by the * parameters.
18
*/ public ClockDisplay(int hour, int minute) { hours = new NumberDisplay(13); minutes = new NumberDisplay(60); if(hour == 0) { hour = 12; } setTime(hour, minute); } /** * This method should get called once every minute - it makes * the clock display go one minute forward. */ public void timeTick() { minutes.increment(); if(minutes.getValue() == 0) { // it just rolled over! hours.increment(); } if(hours.getValue() == 0){ hours.increment(); } updateDisplay(); } /** * Set the time of the display to the specified hour and * minute. */ public void setTime(int hour, int minute) { hours.setValue(hour); minutes.setValue(minute); updateDisplay(); } /** * Return the current time of this display in the format HH:MM. */ public String getTime() { return displayString; } /** * Update the internal string that represents the display. */
19
private void updateDisplay() { displayString = hours.getDisplayValue() + ":" + minutes.getDisplayValue(); } } met NumberDisplay: /** * The NumberDisplay class represents a digital number display that can hold * values from zero to a given limit. The limit can be specified when creating * the display. The values range from zero (inclusive) to limit-1. If used, * for example, for the seconds on a digital clock, the limit would be 60, * resulting in display values from 0 to 59. When incremented, the display * automatically rolls over to zero when reaching the limit. * * @author D. Slenders * @version 2010.02.13 */ public class NumberDisplay { private int limit; private int value; /** * Constructor for objects of class NumberDisplay. * Set the limit at which the display rolls over. */ public NumberDisplay(int rollOverLimit) { limit = rollOverLimit; value = 0; } /** * Return the current value. */ public int getValue() { return value; } /** * Return the display value (that is, the current value as a two-digit * String. If the value is less than ten, it will be padded with a leading * zero). */ public String getDisplayValue() {
20
if(value < 10) { return "0" + value; } else { return "" + value; } } /** * Set the value of the display to the new specified value. If the new * value is less than zero or over the limit, do nothing. */ public void setValue(int replacementValue) { if((replacementValue >= 0) && (replacementValue < limit)) { value = replacementValue; } } /** * Increment the display value by one, rolling over to zero if the * limit is reached. */ public void increment() { value = (value + 1) % limit; } }
Oefening 3.32 Vraag Er zijn (ten minste) twee manieren waarop je een 12-uursklok kunt maken. E´en mogelijkheid is om uurwaarden van 1 tot en met 12 op te slaan. Een andere mogelijkheid is dat jde de klok intern ook gewoon als een 24-uursklok laat werken, maar de displaystring van het klokdisplay aanpast zodat die 4:23 of 4:23 pm aangeeft wanneer de interne waarde 16:23 is. Programmeer beide varianten. Welke optie is het eenvoudigst? Welke is beter? Waarom?
Oplossing De eerste methode is volledig uitgewerkt in de vorige oefening (3.31). Als we de klok intern als een 24-uursklok laten werken, kunnen we de broncode van het originele programma gebruiken. De enige aanpassing zit in de methode updateDisplay om de inhoud van de displayString te veranderen in een 12-uursklok. Dit gebeurt door de voorwaarde te stellen dat als het uur gelijk is aan nul of groter dan 12 dit aan te passen. Dit geeft de volgende code:
21
private void updateDisplay() { if(hours.getValue() > 12) { hours.setValue(hours.getValue() - 12); } if(hours.getValue() == 0) { hours.setValue(12); } displayString = hours.getDisplayValue() + ":" + minutes.getDisplayValue(); } De broncode van het hele programma wordt dan: /** * The ClockDisplay class implements a digital clock display for a * European-style 12 hour clock. The clock shows hours and minutes. The * range of the clock is 01:00 (midnight) to 12:59 (one minute before * midnight). * * The clock display receives "ticks" (via the timeTick method) every minute * and reacts by incrementing the display. This is done in the usual clock * fashion: the hour increments when the minutes roll over to zero. * * @author D. Slenders * @version 2010.02.18 */ public class ClockDisplay { private NumberDisplay hours; private NumberDisplay minutes; private String displayString; // simulates the actual display /** * Constructor for ClockDisplay objects. This constructor * creates a new clock set at 12:00. */ public ClockDisplay() { hours = new NumberDisplay(24); minutes = new NumberDisplay(60); updateDisplay(); } /** * Constructor for ClockDisplay objects. This constructor * creates a new clock set at the time specified by the * parameters.
22
*/ public ClockDisplay(int hour, int minute) { hours = new NumberDisplay(24); minutes = new NumberDisplay(60); setTime(hour, minute); } /** * This method should get called once every minute - it makes * the clock display go one minute forward. */ public void timeTick() { minutes.increment(); if(minutes.getValue() == 0) { // it just rolled over! hours.increment(); } updateDisplay(); } /** * Set the time of the display to the specified hour and * minute. */ public void setTime(int hour, int minute) { hours.setValue(hour); minutes.setValue(minute); updateDisplay(); } /** * Return the current time of this display in the format HH:MM. */ public String getTime() { return displayString; } /** * Update the internal string that represents the display. */ private void updateDisplay() { if(hours.getValue() > 12) { hours.setValue(hours.getValue() - 12); } if(hours.getValue() == 0)
23
{ hours.setValue(12); } displayString = hours.getDisplayValue() + ":" + minutes.getDisplayValue(); } } met NumberDisplay: /** * The NumberDisplay class represents a digital number display that can hold * values from zero to a given limit. The limit can be specified when creating * the display. The values range from zero (inclusive) to limit-1. If used, * for example, for the seconds on a digital clock, the limit would be 60, * resulting in display values from 0 to 59. When incremented, the display * automatically rolls over to zero when reaching the limit. * * @author D. Slenders * @version 2010.02.13 */ public class NumberDisplay { private int limit; private int value; /** * Constructor for objects of class NumberDisplay. * Set the limit at which the display rolls over. */ public NumberDisplay(int rollOverLimit) { limit = rollOverLimit; value = 0; } /** * Return the current value. */ public int getValue() { return value; } /** * Return the display value (that is, the current value as a two-digit * String. If the value is less than ten, it will be padded with a leading * zero). */ public String getDisplayValue()
24
{ if(value < 10) { return "0" + value; } else { return "" + value; } } /** * Set the value of the display to the new specified value. If the new * value is less than zero or over the limit, do nothing. */ public void setValue(int replacementValue) { if((replacementValue >= 0) && (replacementValue < limit)) { value = replacementValue; } } /** * Increment the display value by one, rolling over to zero if the * limit is reached. */ public void increment() { value = (value + 1) % limit; } }
Oefening 4.17 Vraag Schrijf een while-lus (bijvoorbeeld in een methode met de naam multiplesOfFive) die alle veelvouden van 5 tussen 0 en 95 afdrukt.
Oplossing Alle veelvouden van vijf zijn de getallen die na deling door vijf als rest nul hebben. Dit kunnen we gemakkelijk met de modulo-operator (%) nagaan: int x = 0; while(x <= max) { if(x % 5 == 0) {
25
System.out.println(""+ x); } x++; } Hierbij moet er wel rekening gehouden worden dat de maximumwaare strikt positief moet zijn. De broncode van het hele programma wordt dan: /** * A program that prints the multiples of five. * * @author D. Slenders * @version 2010.02.19 */ public class MultiplesOfFive { /** * Print multiples of five */ public void multiplesOfFive(int max) { if(max > 0) { int x = 0; while(x <= max) { if(x % 5 == 0) { System.out.println(""+ x); } x++; } } else { System.out.println("Geef een strikt positieve maximumwaarde op."); } } }
Oefening 4.18 Vraag Schrijf een methode met de naam sum waarim je een while-lus gebruikt die alle getallen tussen twee getallen a en b optelt. De waarden van a en b kunnen als parameters aan de methode doorgegeven worden.
26
Oplossing Om de som van alle getallen tussen twee gegeven getallen te bepalen, moeten we itereren over alle getallen tussen a en b en deze steeds optellen bij de beginwaarde nul. Dit geeft de volgende code: public void sumOfElements(int a, int b) { int x = a + 1; int y = 0; while(x < b) { y = y + x; x++; } System.out.println("Som = " + y); } Hierbij moet wel rekening gehouden worden met de mogelijkheid dat a groter dan b zou kunnen zijn. De broncode van het hele programma wordt dan: /** * A program that summates all numbers between two given numbers. * * @author D. Slenders * @version 2010.02.19 */ public class Sum { /** * Print the sum of numbers between two given numbers. */ public void sumOfElements(int a, int b) { if(a <= b) { int x = a + 1; int y = 0; while(x < b) { y = y + x; x++; } System.out.println("Som = " + y); } else { int x = b + 1;
27
int y = 0; while(x < a) { y = y + x; x++; } System.out.println("Som = " + y); } } }
Oefening 4.19 Vraag Schrijf een methode isPrime(int n) die true retourneert als de parameter n een priemgetal is en false als dat niet het geval is. Om de methode te implementeren, kun je een while-lus schrijven die n deelt door alle getallen tussen 2 en (n − 1) en test of de deling een geheel getal oplevert. Je kunt deze test schrijven met behulp van de modulo-operator (%) om te controleren of de gehele deling een rest 0 oplevert.
Oplossing We moeten x dus laten vari¨eren tussen 2 en (n − 1) en voor elke waarde controleren of de rest gelijk is aan nul. Indien dit voor een waarde het geval is, laten we de boolean prime veranderen in false en dit retourneren. Als dit voor geen enkele waarde het geval is, moet de boolean true retourneren. De broncode van het hele programma is dan: /** * A program that determines if a given number is a prime number or not. * * @author D. Slenders * @version 2010.02.19 */ public class IsPrime { /** * Test if a given number is prime. */ public boolean isPrime(int n) { boolean prime = false; int x = 2; while(x < n) {
28
if(n % x == 0) { prime = false; return(prime); } prime = true; x++; } return(prime); } }
Oefening 4.34 Vraag Open het project club. Definieer een methode in de klasse Club met de volgende omschrijving: /** * Calculates the number of people joined in month x. * @param month The month we want information about. * @return The number of people joined. */ Druk, als de parameter month niet in het bereik 1 − 12 ligt, een foutmelding af en retourneer nul.
Oplossing Met een for-each-lus kunnen we alle elementen uit de ArrayList afgaan. Hiervan moeten we bepalen of ze in de desbetreffende maand lid zijn geworden, en, zoja, de waarde van het aantal leden in die maand lid geworden met ´e´en verhogen. Dit gebeurt met de volgende code: for(Membership member : members) { if(member.getMonth() == month) { numberJoinedInMonth++; } } Dit moet binnen een voorwaardelijke lus gezet die bepaalt of de opgegeven maand een geldige waarde heeft (dus tussen 1 en 12): public int joinedInMonth(int month) {
29
int numberJoinedInMonth = 0; if(month < 1 || month > 12) { System.out.println("Geen geldige maand"); return 0; } else { for(Membership member : members) { if(member.getMonth() == month) { numberJoinedInMonth++; } } } return numberJoinedInMonth; } De broncode van het hele programma wordt dan: import java.util.ArrayList; /** * Store details of club memberships. * * @author D. Slenders * @version 2010.02.19 */ public class Club { private ArrayList<Membership> members; private String name; /** * Constructor for objects of class Club */ public Club() { members = new ArrayList<Membership>(); } /** * Add a new member to the club’s list of members. * @param member The member object to be added. */ public void join(Membership member) { members.add(member); }
30
/** * Calculates the number of people joined in month x. * @param month The month we want information about. * @return The number of people joined. */ public int joinedInMonth(int month) { int numberJoinedInMonth = 0; if(month < 1 || month > 12) { System.out.println("Geen geldige maand"); return 0; } else { for(Membership member : members) { if(member.getMonth() == month) { numberJoinedInMonth++; } } } return numberJoinedInMonth; } /** * @return * */ public int { return }
The number of members (Membership objects) in the club. numberOfMembers() members.size();
} met Membership: /** * Store details of a club membership. * * @author David J. Barnes and Michael Kolling * @version 2008.03.30 */ public class Membership { // The name of the member. private String name; // The month in which the membership was taken out. private int month;
31
// The year in which the membership was taken out. private int year;
/** * Constructor for objects of class Membership. * @param name The name of the member. * @param month The month in which they joined. (1 ... 12) * @param year The year in which they joined. */ public Membership(String name, int month, int year) throws IllegalArgumentException { if(month < 1 || month > 12) { throw new IllegalArgumentException( "Month " + month + " out of range. Must be in the range 1 ... 1 } this.name = name; this.month = month; this.year = year; } /** * @return The member’s name. */ public String getName() { return name; } /** * @return * */ public int { return }
The month in which the member joined. A value in the range 1 ... 12 getMonth() month;
/** * @return The year in which the member joined. */ public int getYear() { return year; } /** * @return A string representation of this membership. */ public String toString()
32
{ return "Name: " + name + " joined in month " + month + " of " + year; } }
33
Oefenzitting 3 Oefening 4.35 Vraag Definieer een methode in de klasse Club met de volgende omschrijving: /** * Delete all members of the club who joined in the given month. * Return them in a different ArrayList: * @param month The month member joined. * @return Members who joined in the given month. */ public ArrayList<Memberhip> purge(int month)
Oplossing Allereerst moeten we een nieuwe ArrayList aanmaken waarin de desbetreffende leden geretourneerd worden: private ArrayList<Membership> purgedMembers; Om de leden te zoeken die in de desbetreffende maand lid zijn geworden, gebruiken we een foreach-lus die alle leden afgaat en de gevraagde leden kopieert naar de ArrayList purgedMembers. Dit geeft de volgende code: for(Membership member : members) { if(member.getMonth() == month) { purgedMembers.add(member); } } Alle leden van purgedMembers moeten uit members verwijderd worden:
34
for(Membership member : purgedMembers) { members.remove(members.indexOf(member)); } Deze foreach-lus moet enkel uitgevoerd worden als er een geldige maand wordt opgegeven, dus zetten we dit binnen een voorwaardelijke lus dit dit controleerd: public ArrayList<Membership> purge(int month) { purgedMembers = new ArrayList<Membership>(); if(month < 1 || month > 12) { System.out.println("Geen geldige maand"); } else { for(Membership member : members) { if(member.getMonth() == month) { purgedMembers.add(member); } } for(Membership member : purgedMembers) { members.remove(members.indexOf(member)); } } return purgedMembers; } De broncode van het hele programma wordt dan: import java.util.ArrayList; /** * Store details of club memberships. * * @author D. Slenders * @version 2010.02.19 */ public class Club { private ArrayList<Membership> members; private String name; private ArrayList<Membership> purgedMembers; /** * Constructor for objects of class Club */
35
public Club() { members = new ArrayList<Membership>(); } /** * Add a new member to the club’s list of members. * @param member The member object to be added. */ public void join(Membership member) { members.add(member); } /** * Calculates the number of people joined in month x. * @param month The month we want information about. * @return The number of people joined. */ public int joinedInMonth(int month) { int numberJoinedInMonth = 0; if(month < 1 || month > 12) { System.out.println("Geen geldige maand"); return 0; } else { for(Membership member : members) { if(member.getMonth() == month) { numberJoinedInMonth++; } } } return numberJoinedInMonth; } /** * Delete all members of the club who joined in the given month. * Return them in a different ArrayList: * @param month The month member joined. * @return Members who joined in the given month. */ public ArrayList<Membership> purge(int month) { purgedMembers = new ArrayList<Membership>(); if(month < 1 || month > 12)
36
{ System.out.println("Geen geldige maand"); } else { for(Membership member : members) { if(member.getMonth() == month) { purgedMembers.add(member); } } for(Membership member : purgedMembers) { members.remove(members.indexOf(member)); } } return purgedMembers; } /** * @return * */ public int { return }
The number of members (Membership objects) in the club. numberOfMembers() members.size();
} met Membership: /** * Store details of a club membership. * * @author David J. Barnes and Michael Kolling * @version 2008.03.30 */ public class Membership { // The name of the member. private String name; // The month in which the membership was taken out. private int month; // The year in which the membership was taken out. private int year; /** * Constructor for objects of class Membership. * @param name The name of the member.
37
* @param month The month in which they joined. (1 ... 12) * @param year The year in which they joined. */ public Membership(String name, int month, int year) throws IllegalArgumentException { if(month < 1 || month > 12) { throw new IllegalArgumentException( "Month " + month + " out of range. Must be in the range 1 ... 1 } this.name = name; this.month = month; this.year = year; } /** * @return The member’s name. */ public String getName() { return name; } /** * @return * */ public int { return }
The month in which the member joined. A value in the range 1 ... 12 getMonth() month;
/** * @return The year in which the member joined. */ public int getYear() { return year; } /** * @return A string representation of this membership. */ public String toString() { return "Name: " + name + " joined in month " + month + " of " + year; } }
38
Oefening 4.28 Vraag Voeg een methode close toe aan de klassa Auction. Deze moet de collectie kavels doorlopen en informatie over alle kavels afdrukken. Je kunt hiervoor zowel een for-each-lus als een whilelus gebruiken. Een kavel waarop tenminste ´e´en bod is gedaan, wordt verondersteld verkocht te zijn. Bij verkochte kavels moet de naam van de bieder worden afgedrukt plus de waarde van diens bod. Bij kavels die niet verkocht zijn moet een melding worden afgedrukt om dit aan te geven.
Oplossing De structuur van het hele programma is als volgt: Auction gebruikt de klassa Lot (met de kavels). Lot gebruikt de klasse Bid (met de boden). En Bid gebruikt de klasse Person (met de personen). Voor de kavels die verkocht zijn moeten we de naam van de bieder en de waarde van diens bod weten. Dit geeft de volgende code: System.out.println("Person " + lot.getHighestBid().getBidder().getName()); System.out.println("Bid " + lot.getHighestBid().getValue()); Dit moet enkel afgeprint worden als er een bod gedaan is, dus als de waarde van het hoogste bod verschillend is van nul. We zetten dit dus in een voorwaardelijke lus: if(lot.getHighestBid() == null) { System.out.println("Lot unsold"); } else { System.out.println("Person " + lot.getHighestBid().getBidder().getName()); System.out.println("Bid " + lot.getHighestBid().getValue()); } Dit moet gebeuren voor alle kavels, dus laten we via een for-each-lus Java alle kavels overlopen: public void close() { for(Lot lot : lots) { if(lot.getHighestBid() == null) { System.out.println("Lot unsold"); } else {
39
System.out.println("Person " + lot.getHighestBid().getBidder().getN System.out.println("Bid " + lot.getHighestBid().getValue()); } } } De broncode van het hele programma wordt dan: import java.util.ArrayList; /** * A simple model of an auction. * The auction maintains a list of lots of arbitrary length. * * @author D. Slenders * @version 2010.02.19 */ public class Auction { // The list of Lots in this auction. private ArrayList
lots; // The number that will be given to the next lot entered // into this auction. private int nextLotNumber; /** * Create a new auction. */ public Auction() { lots = new ArrayList(); nextLotNumber = 1; } /** * Enter a new lot into the auction. * @param description A description of the lot. */ public void enterLot(String description) { lots.add(new Lot(nextLotNumber, description)); nextLotNumber++; } /** * Print info lots. */ public void close() { for(Lot lot : lots)
40
{
if(lot.getHighestBid() == null) { System.out.println("Lot unsold"); } else { System.out.println("Person " + lot.getHighestBid().getBidder(). System.out.println("Bid " + lot.getHighestBid().getValue()); } } } /** * Show the full list of lots in this auction. */ public void showLots() { for(Lot lot : lots) { System.out.println(lot.toString()); } } /** * Bid for a lot. * A message indicating whether the bid is successful or not * is printed. * @param number The lot number being bid for. * @param bidder The person bidding for the lot. * @param value The value of the bid. */ public void bidFor(int lotNumber, Person bidder, long value) { Lot selectedLot = getLot(lotNumber); if(selectedLot != null) { boolean successful = selectedLot.bidFor(new Bid(bidder, value)); if(successful) { System.out.println("The bid for lot number " + lotNumber + " was successful."); } else { // Report which bid is higher. Bid highestBid = selectedLot.getHighestBid(); System.out.println("Lot number: " + lotNumber + " already has a bid of: " + highestBid.getValue()); } } }
41
/** * Return the lot with the given number. Return null * if a lot with this number does not exist. * @param lotNumber The number of the lot to return. */ public Lot getLot(int lotNumber) { if((lotNumber >= 1) && (lotNumber < nextLotNumber)) { // The number seems to be reasonable. Lot selectedLot = lots.get(lotNumber - 1); // Include a confidence check to be sure we have the // right lot. if(selectedLot.getNumber() != lotNumber) { System.out.println("Internal error: Lot number " + selectedLot.getNumber() + " was returned instead of " + lotNumber); // Don’t return an invalid lot. selectedLot = null; } return selectedLot; } else { System.out.println("Lot number: " + lotNumber + " does not exist."); return null; } } } met Lot: /** * A class to model an item (or set of items) in an * auction: a lot. * * @author David J. Barnes and Michael Kolling. * @version 2008.03.30 */ public class Lot { // A unique identifying number. private final int number; // A description of the lot. private String description; // The current highest bid for this lot. private Bid highestBid; /** * Construct a Lot, setting its number and description.
42
* @param number The lot number. * @param description A description of this lot. */ public Lot(int number, String description) { this.number = number; this.description = description; } /** * Attempt to bid for this lot. A successful bid * must have a value higher than any existing bid. * @param bid A new bid. * @return true if successful, false otherwise */ public boolean bidFor(Bid bid) { if((highestBid == null) || (bid.getValue() > highestBid.getValue())) { // This bid is the best so far. highestBid = bid; return true; } else { return false; } } /** * @return A string representation of this lot’s details. */ public String toString() { String details = number + ": " + description; if(highestBid != null) { details += " Bid: " + highestBid.getValue(); } else { details += " (No bid)"; } return details; } /** * @return The lot’s number. */ public int getNumber() { return number;
43
} /** * @return The lot’s description. */ public String getDescription() { return description; } /** * @return * * */ public Bid { return }
The highest bid for this lot. This could be null if there is no current bid. getHighestBid() highestBid;
} en met Bid: /** * A class that models an auction bid. * It contains a reference to the Person bidding and the amount bid. * * @author David J. Barnes and Michael Kolling. * @version 2008.03.30 */ public class Bid { // The person making the bid. private final Person bidder; // The value of the bid. This could be a large number so // the long type has been used. private final long value; /** * Create a bid. * @param bidder Who is bidding for the lot. * @param value The value of the bid. */ public Bid(Person bidder, long value) { this.bidder = bidder; this.value = value; } /**
44
* @return The bidder. */ public Person getBidder() { return bidder; } /** * @return The value of the bid. */ public long getValue() { return value; } } en met Person: /** * Maintain details of someone who participates in an auction. * @author David J. Barnes and Michael Kolling. * @version 2008.03.30 */ public class Person { // The name of this person. private final String name; /** * Create a new person with the given name. * @param name The person’s name. */ public Person(String name) { this.name = name; } /** * @return The person’s name. */ public String getName() { return name; } }
45
Oefening 4.29 Vraag Voeg een methode getUnsold toe aan de klasse Auction met de volgende signatuur: public ArrayList getUnsold() Deze methode moet het veld lots doorzoeken en de kavels die niet verkocht zijn opslaan in een nieuwe lokale ArrayList-variabele. Retourneer aan het eind van de methode de lijst met onverkochte kavels.
Oplossing Met een for-each-lus kunnen we alle kavels van de ArrayList doorzoeken. Via een voorwaardelijke lus kunnen we de onverkochte kavels kopi¨eren naar een nieuwe ArrayList: unsold. Dit geeft de volgende code: ArrayList unsold; unsold = new ArrayList(); for(Lot lot : lots) { if(lot.getHighestBid() == null) { unsold.add(lot); } } De kavels in de nieuwe ArrayList moeten ook nog getoond worden: public void getUnsold() { ArrayList unsold; unsold = new ArrayList(); for(Lot lot : lots) { if(lot.getHighestBid() == null) { unsold.add(lot); } } for(Lot lot : unsold) { System.out.println(lot.toString()); } }
46
De broncode van het hele programma wordt dan: import java.util.ArrayList; /** * A simple model of an auction. * The auction maintains a list of lots of arbitrary length. * * @author D. Slenders * @version 2010.02.19 */ public class Auction { // The list of Lots in this auction. private ArrayList lots; // The number that will be given to the next lot entered // into this auction. private int nextLotNumber; /** * Create a new auction. */ public Auction() { lots = new ArrayList(); nextLotNumber = 1; } /** * Enter a new lot into the auction. * @param description A description of the lot. */ public void enterLot(String description) { lots.add(new Lot(nextLotNumber, description)); nextLotNumber++; } /** * Print info lots. */ public void close() { for(Lot lot : lots) { if(lot.getHighestBid() == null) { System.out.println("Lot unsold"); } else
47
{
System.out.println("Person " + lot.getHighestBid().getBidder(). System.out.println("Bid " + lot.getHighestBid().getValue()); } } } /** * Show the full list of lots in this auction. */ public void showLots() { for(Lot lot : lots) { System.out.println(lot.toString()); } } /** * Bid for a lot. * A message indicating whether the bid is successful or not * is printed. * @param number The lot number being bid for. * @param bidder The person bidding for the lot. * @param value The value of the bid. */ public void bidFor(int lotNumber, Person bidder, long value) { Lot selectedLot = getLot(lotNumber); if(selectedLot != null) { boolean successful = selectedLot.bidFor(new Bid(bidder, value)); if(successful) { System.out.println("The bid for lot number " + lotNumber + " was successful."); } else { // Report which bid is higher. Bid highestBid = selectedLot.getHighestBid(); System.out.println("Lot number: " + lotNumber + " already has a bid of: " + highestBid.getValue()); } } } /** * Return the lot with the given number. Return null * if a lot with this number does not exist. * @param lotNumber The number of the lot to return. */ public Lot getLot(int lotNumber)
48
{ if((lotNumber >= 1) && (lotNumber < nextLotNumber)) { // The number seems to be reasonable. Lot selectedLot = lots.get(lotNumber - 1); // Include a confidence check to be sure we have the // right lot. if(selectedLot.getNumber() != lotNumber) { System.out.println("Internal error: Lot number " + selectedLot.getNumber() + " was returned instead of " + lotNumber); // Don’t return an invalid lot. selectedLot = null; } return selectedLot; } else { System.out.println("Lot number: " + lotNumber + " does not exist."); return null; } } /** * Copy and return the unsold lots. */ public void getUnsold() { ArrayList unsold; unsold = new ArrayList(); for(Lot lot : lots) { if(lot.getHighestBid() == null) { unsold.add(lot); } } for(Lot lot : unsold) { System.out.println(lot.toString()); } } } met Lot: /** * A class to model an item (or set of items) in an * auction: a lot.
49
* * @author David J. Barnes and Michael Kolling. * @version 2008.03.30 */ public class Lot { // A unique identifying number. private final int number; // A description of the lot. private String description; // The current highest bid for this lot. private Bid highestBid; /** * Construct a Lot, setting its number and description. * @param number The lot number. * @param description A description of this lot. */ public Lot(int number, String description) { this.number = number; this.description = description; } /** * Attempt to bid for this lot. A successful bid * must have a value higher than any existing bid. * @param bid A new bid. * @return true if successful, false otherwise */ public boolean bidFor(Bid bid) { if((highestBid == null) || (bid.getValue() > highestBid.getValue())) { // This bid is the best so far. highestBid = bid; return true; } else { return false; } } /** * @return A string representation of this lot’s details. */ public String toString() { String details = number + ": " + description; if(highestBid != null) {
50
details += " Bid: " + highestBid.getValue(); } else { details += " } return details;
(No bid)";
} /** * @return The lot’s number. */ public int getNumber() { return number; } /** * @return The lot’s description. */ public String getDescription() { return description; } /** * @return * * */ public Bid { return }
The highest bid for this lot. This could be null if there is no current bid. getHighestBid() highestBid;
} en met Bid: /** * A class that models an auction bid. * It contains a reference to the Person bidding and the amount bid. * * @author David J. Barnes and Michael Kolling. * @version 2008.03.30 */ public class Bid { // The person making the bid. private final Person bidder; // The value of the bid. This could be a large number so
51
// the long type has been used. private final long value; /** * Create a bid. * @param bidder Who is bidding for the lot. * @param value The value of the bid. */ public Bid(Person bidder, long value) { this.bidder = bidder; this.value = value; } /** * @return The bidder. */ public Person getBidder() { return bidder; } /** * @return The value of the bid. */ public long getValue() { return value; } } en met Person: /** * Maintain details of someone who participates in an auction. * @author David J. Barnes and Michael Kolling. * @version 2008.03.30 */ public class Person { // The name of this person. private final String name; /** * Create a new person with the given name. * @param name The person’s name. */ public Person(String name) { this.name = name;
52
} /** * @return The person’s name. */ public String getName() { return name; } }
53
Oefenzitting 4 Oefening 5.14 Vraag
Schrijf een stukje code (in BlueJ) om het genereren van random getallen te testen. Maak hiervoor een nieuwe klasse met de naam RandomTester. Je kunt deze klasse maken in het projecht tech-support1, maar ook in een nieuw project. Verwerk twee methodes in de klasse RandomTester: printOneRandom (die ´e´en random getal afdrukt) en printMultiRandom(int howMany) (die een parameter heeft waarmee je aan kunt geven hoeveel getallen je wilt hebben en dan het gewenste aantal getallen afdrukt.
Oplossing Om random getallen te genereren moeten we allereerste de klasse Random importeren. Dit gebeurt met het volgende commando: import java.util.Random; Om een willekeurig getal van het type int te generenen hebben we de volgende code nodig: int index = randomGenerator.nextInt(); Eerst maken we randomGenerator in de constructor: private Random randomGenerator; public RandomTester() { randomGenerator = new Random(); } Om dan een willekeurig getal te genereren, gebruiken we de volgende code: public void printOneRandom() { int index = randomGenerator.nextInt(); System.out.println(index); }
54
Voor de methode printMultiRandom(int howMany) zetten we het vorige binnen een voorwaardelijke lus die controleert of x kleiner dan of gelijk is aan de parameter howNany: public void printMultiRandom(int howMany) { int x = 1; while(x <= howMany) { int index = randomGenerator.nextInt(); System.out.println(index); x++; } } De broncode van het hele programma wordt dan: import java.util.Random; /** * Generate random numbers. * * @author D. Slenders * @version 2010.02.24 */ public class RandomTester { private Random randomGenerator; /** * Construct RandomTester. */ public RandomTester() { randomGenerator = new Random(); } /** * Generate one random number */ public void printOneRandom() { int index = randomGenerator.nextInt(); System.out.println(index); } /** * Generate random numbers. * How many is chosen by input. */ public void printMultiRandom(int howMany)
55
{ int x = 1; while(x <= howMany) { int index = randomGenerator.nextInt(); System.out.println(index); x++; } } }
Oefening 5.16 Vraag Schrijf een methode in je klasse RandomTester met de naam throwDice die een random getal in het bereik van 1 tot en met 6 retourneert.
Oplossing Om een getal van 1 tot en met 6 te genereren, gebruiken we de methode nextInt(max) van de klasse Random met als parameter max. Dit is een geheel getal en zorgt dat er een random getal gegenereerd wordt tussen 0 en max − 1. Om een getal tussen 1 en 6 te genereren, stellen we max gelijk aan 6 en verhogen we elk gegenereerd getal met 1: public void throwDice() { int max = 6; int index = randomGenerator.nextInt(max) + 1; System.out.println(index); } De broncode van het hele programma wordt dan: import java.util.Random; /** * Generate random numbers between 1 and 6. * * @author D. Slenders * @version 2010.02.28 */ public class RandomTester { private Random randomGenerator;
56
/** * Construct RandomTester. */ public RandomTester() { randomGenerator = new Random(); } /** * Generate number between 1 and 6. */ public void throwDice() { int max = 6; int index = randomGenerator.nextInt(max) + 1; System.out.println(index); } }
Oefening 5.17 Vraag Schrijf een methode met de naam getResponse die willekeurig een van de strings ’ja’, ’nee’ of ’misschien’ retourneert.
Oplossing We maken allereerst een ArrayList met de drie strings in. Hiervoor moet de klasse ArrayList ge¨ımporteerd worden: import java.util.ArrayList; In de constructor maken we dan een Arraylist aan, en zetten we de drie mogelijke antwoorden erin: private ArrayList<String> randomList; public RandomTester() { randomList = new ArrayList<String>(); randomList.add("yes"); randomList.add("no"); randomList.add("maybe"); }
57
We laten een random getal genereren die het indexnummer van het random antwoord bepaalt. De overeenkomstige string wordt dan getoond: public void getResponse() { int index = randomGenerator.nextInt(3); System.out.println(randomList.get(index)); } De broncode van het hele programma wordt dan: import java.util.Random; import java.util.ArrayList; /** * Generate random answer. * * @author D. Slenders * @version 2010.02.28 */ public class RandomTester { private Random randomGenerator; private ArrayList<String> randomList; /** * Construct RandomTester. */ public RandomTester() { randomGenerator = new Random(); randomList = new ArrayList<String>(); randomList.add("yes"); randomList.add("no"); randomList.add("maybe"); } /** * Generate response: yes, no, maybe. */ public void getResponse() { int index = randomGenerator.nextInt(3); System.out.println(randomList.get(index)); } }
58
Oefening 5.25 Vraag Maak een klasse MapTester. Gebruik er een HashMap in om een telefoonboek te programmeren dat vergelijkbaar is met het bovenstaande voorbeeld. (Vergeet niet om java.util.HashMap te importeren.) Verwerk in deze klasse twee methodes: public void enterNumber(String name, String number) en public String lookupNumber(String name) De methodes moeten de methodes put en get van de klasse HashMap gebruiken.
Oplossing Allereerst moet de klasse HashMap ge¨ımporteerd worden: import java.util.HashMap; We moeten phonebook aanmaken. Dit object is een HashMap en moet in dit geval twee Strings bevatten: public MapTester() { phonebook = new HashMap<String, String>(); } De nethode enterNumber moet een nieuw element aan phonebook toevoegen. Hiervoor moeten twee Strings gevraagd worden: de naam en het telefoonnummer. Dit geeft: public void enterNumber(String name, String number) { phonebook.put(name, number); } De methode lookupNumber moet het telefoonnummer geven dat bij een bepaalde naam hoort. Hiervoor moet dus de naam gevraagd worden: public String lookupNumber(String name) { String number = phonebook.get(name); return number; }
59
De broncode van het hele programma wordt dan: import java.util.HashMap; /** * This class is a phonebook. * * @author D. Slenders * @version 2010.02.24 */ public class MapTester { private HashMap<String, String> phonebook; /** * Constructor for objects of class MapTester */ public MapTester() { phonebook = new HashMap<String, String>(); } /** * Enter object to phonebook. */ public void enterNumber(String name, String number) { phonebook.put(name, number); } /** * Get phonenumber of object. */ public String lookupNumber(String name) { String number = phonebook.get(name); return number; } }
Oefening 5.28 Vraag Hoe kun je controleren of een bepaalde sleutel al in een map aanwezig is? (Geef een codevoorbeeld in Java.)
60
Oplossing Hier zijn twee mogelijkheden voor. Ofwel gebruik je de methode containsKey(Object key) die al in de klasse HashMap aanwezig is, ofwel maak je zelf een methode. De methode containsKey(Object key) retourneert een boolean met de waarde true als de gegeven sleutel al in de map aanwezig is. Dit geeft: public boolean testName(String name) { boolean existence = phonebook.containsKey(name); return existence; } Als je zelf zo’n methode wilt maken, moet je controleren of de waarde van number verschillend is van null. Indien dit verschillend is, bestaat de opgegeven naam en komt daarmee het gevonden telefoonnummer overeen. Dit geeft de volgende code: public boolean testName(String name) { boolean existence = false; String number = phonebook.get(name); if(number != null) { existence = true; } return existence; } De broncode van het hele programma wordt dan: import java.util.HashMap; /** * This class is a phonebook. * * @author D. Slenders * @version 2010.02.24 */ public class MapTester { private HashMap<String, String> phonebook; /** * Constructor for objects of class MapTester */ public MapTester() { phonebook = new HashMap<String, String>(); }
61
/** * Enter object to phonebook. */ public void enterNumber(String name, String number) { phonebook.put(name, number); } /** * Get phonenumber of object. */ public String lookupNumber(String name) { String number = phonebook.get(name); return number; } /** * Test if name is an element of phonebook. */ public boolean testName(String name) { boolean existence = false; String number = phonebook.get(name); if(number != null) { existence = true; } return existence; } public boolean testName2(String name) { boolean existence = phonebook.containsKey(name); return existence; } }
Oefening 5.30 Vraag Hoe kun je het aantal in een map aanwezige records te weten komen?
62
Oplossing De methode size() retourneert het aantal records van een bepaalde HashMap: public int getSize() { return hashMap.size(); }
63