Her ligger løsningsforslaget til kontinuasjonseksamen 2021. Vi vil senere legge til ofte forekommende feil og misforståelser i kombinasjon med kildekoden .

På gitlab finner dere full kode til alle deler i oppgaven.


package del1;

public class VoterCounter {

	// Add any needed fields here
	public static final String TIE_RESULT = "TIE";

	/**
	 * Register a candidate to the poll
	 * 
	 * @param candidate the new candidate to add
	 */
	public void addCandidate(String candidate) {
		// TODO
	}

	/**
	 * Vote on a given candidate
	 * 
	 * @param candidate the candidate to vote on
	 * 
	 * @throws IllegalArgumentException if the candidate is not registered
	 */
	public void castVote(String candidate) {
		// TODO
	}

	/**
	 * Prints all the results in an arbitrary order. The results should be on the
	 * format {candidate name}-{number of votes for the candidate} with each
	 * candidate on a new line
	 * 
	 * Example output with two candidates, "Candidate1" with 7 votes, and
	 * "Candidate2" with 6 votes
	 * 
	 * Candidate1-7 
	 * Candidate2-6
	 */
	public String getFormattedResults() {
		// TODO
		return null;
	}

	/**
	 * Returns the number of votes a candidate has received
	 * 
	 * @param candidate the candidate to get number of votes for
	 * @return the number of votes the candidate has received. Returns null if the
	 *         candidate is not registered
	 */
	public Integer getNumberOfVotes(String candidate) {
		// TODO
		return 0;
	}

	/**
	 *
	 * @return the name of the candidate who won the election. If two or more
	 *         candidates got the same number of maximum votes, return the
	 *         TIE_RESULT field. Return null if there are no candidates.
	 */
	public String getWinner() {
		// TODO
		return null;
	}

	public static void main(String[] args) {
		String candidate1 = "CANDIDATE1";
		String candidate2 = "CANDIDATE2";
		VoterCounter counter = new VoterCounter();
		counter.addCandidate(candidate1);
		counter.addCandidate(candidate2);
		// Should print 0
		System.out.println(counter.getNumberOfVotes(candidate1));
		counter.castVote(candidate1);
		// Should print 1;
		System.out.println(counter.getNumberOfVotes(candidate1));
		// Should print CANDIDATE 1
		System.out.println(counter.getWinner());
		counter.castVote(candidate2);
		// Should print TIE
		System.out.println(counter.getWinner());
	}
}

Utfyll klassen VoterCounter, og alle metodene i denne klassen. Legg til egne nødvendige felt. VoterCounter skal ha oversikt over kandidater som stiller til valg, og antall stemmer de har fått.

  • addCandidate(String candidateName) - Registrerer en kandidat en kan stemme på
  • castVote(String candidate) - Gir en stemme til kandidaten
  • getFormattedResults() - Returnerer antall stemmer hver kandidat har fått
  • getVotes(String candidate) - Returnerer antall stemmer en kandidat har fått
  • getWinner() - Returnerer kandidaten som fikk flest stemmer, eventuelt om det ble uavgjort
package del1;

import java.util.HashMap;
import java.util.Map;

public class VoterCounter {

	private Map<String, Integer> votes = new HashMap<>();
	public static final String TIE_RESULT = "TIE";

	/**
	 * Register a candidate to the poll
	 * 
	 * @param candidate the new candidate to add
	 */
	public void addCandidate(String candidate) {
		votes.put(candidate, 0);

	}

	/**
	 * Vote on a given candidate
	 * 
	 * @param candidate the candidate to vote on
	 * 
	 * @throws IllegalArgumentException if the candidate is not registered
	 */
	public void castVote(String candidate) {
		if (!this.votes.containsKey(candidate)) {
			throw new IllegalArgumentException();
		}
		votes.replace(candidate, votes.get(candidate) + 1);
	}

	/**
	 * Prints all the results in an arbitrary order. The results should be on the
	 * format {candidate name}-{number of votes for the candidate} with each
	 * candidate on a new line
	 */
	public String getFormattedResults() {
		String s = "";
		for (String candidate : votes.keySet()) {
			s += (candidate + "-" + votes.get(candidate)) + "\n";
		}
		return s;
	}

	/**
	 * Get's the number of votes a candidate has received
	 * 
	 * @param candidate the candidate to get number of votes for
	 * @return the number of votes the candidate has received. null if the candidate
	 *         is not registered
	 */

	public Integer getNumberOfVotes(String candidate) {
		return votes.getOrDefault(candidate, null);
	}

	/**
	 *
	 * @return the name of the candidate who won the election. If two or more
	 *         candidates got the same number of maximum votes, return the
	 *         TIE_RESULT field. Return null if there is no candidates.
	 */

	public String getWinner() {
		int maxValue = 0;
		String winner = null;
		for (String candidate : votes.keySet()) {
			if (votes.get(candidate) > maxValue) {
				winner = candidate;
				maxValue = votes.get(candidate);
			}
		}
		for (String candidate : votes.keySet()) {
			if (votes.get(candidate) == maxValue && !winner.equals(candidate)) {
				return TIE_RESULT;
			}
		}
		return winner;
	}

	public static void main(String[] args) {
		String candidate1 = "CANDIDATE1";
		String candidate2 = "CANDIDATE2";
		VoterCounter counter = new VoterCounter();
		counter.addCandidate(candidate1);
		counter.addCandidate(candidate2);
		// Should print 0
		System.out.println(counter.getNumberOfVotes(candidate1));
		counter.castVote(candidate1);
		// Should print 1;
		System.out.println(counter.getNumberOfVotes(candidate1));
		// Should print CANDIDATE 1
		System.out.println(counter.getWinner());
		counter.castVote(candidate2);
		// Should print TIE
		System.out.println(counter.getWinner());
	}
}


Komplementer AppController og UI.fxml så de fungerer sammen etter hensikten. Dette kan innebære å knytte opp felt/metoder i både Controller og .fxml-filen.

package del2;

import javafx.fxml.FXML;
import javafx.scene.control.TextArea;

public class AppController {

	// TODO - Add any needed fields here
	@FXML
	public TextArea output;
	public static String logInSuccess = "Gratulerer du har logget inn!";
	public static String logInFailed = "Feil brukernavn eller passord";

	/**
	 * TODO - what should be the name of this method? Uncomment this part of the
	 * code and put it inside the correct function public void { String brukernavn;
	 * // Extract username from FXML here String passord; // Extract password from
	 * FXML here
	 * 
	 * if (brukernavn.equals("admin") && passord.equals("admin")) {
	 * output.setText(logInSuccess); } else { output.setText(logInFailed); } }
	 */

}


package del2;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class App extends Application {
	
	@Override
	public void start(final Stage primaryStage) throws Exception {
		primaryStage.setTitle("My app");
		primaryStage.setScene(new Scene(FXMLLoader.load(App.class.getResource("Ui.fxml"))));
		primaryStage.show();
	}

	public static void main(String[] args) {
		App.launch(args);
	}

}
//Code for the fxml-file

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="400.0" prefWidth="695.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="del2.AppController">
   <children>
      <Label layoutX="112.0" layoutY="111.0" text="Brukernavn" />
      <Label layoutX="272.0" layoutY="111.0" text="Passord" />
      <TextField fx:id="username" layoutX="53.0" layoutY="128.0" />
      <TextField fx:id="password" layoutX="249.0" layoutY="128.0" />
      <TextArea fx:id="output" layoutX="114.0" layoutY="178.0" prefHeight="200.0" prefWidth="200.0" />
      <Button layoutX="464.0" layoutY="128.0" mnemonicParsing="false" onAction="#onLogIn" text="Logg inn" />
   </children>
</AnchorPane>


package del2;

import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;

public class AppController {
	
	//TODO - Add any needed fields here
	@FXML 
	public TextArea output;
	@FXML
	private TextField username, password;
	
	public static String logInSuccess = "Gratulerer du har logget inn!";
	public static String logInFailed = "Feil brukernavn eller passord";
	
	@FXML
	public void onLogIn() {
		String brukernavn = username.getText();// Extract username from FXML here
		String passord = password.getText(); // Extract password from FXML here
		
		if (brukernavn.equals("admin") && passord.equals("admin")) {
			output.setText(logInSuccess);
		}
		else {
			output.setText(logInFailed);
		}
	}
	
}



//Code for the fxml-file
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="400.0" prefWidth="695.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kortforklart.AppController">
   <children>
      <Label layoutX="112.0" layoutY="111.0" text="Brukernavn" />
      <Label layoutX="272.0" layoutY="111.0" text="Passord" />
      <TextField fx:id="username" layoutX="53.0" layoutY="128.0" />
      <TextField fx:id="password" layoutX="249.0" layoutY="128.0" />
      <TextArea fx:id="output" layoutX="114.0" layoutY="178.0" prefHeight="200.0" prefWidth="200.0" />
      <Button layoutX="464.0" layoutY="128.0" mnemonicParsing="false" onAction="#onLogIn" text="Logg inn" />
   </children>
</AnchorPane>

Følgende vedlagte klasser/interfaces brukes, men skal ikke endres i denne klassen. Du trenger ikke forstå hvordan metodene er implementert, bare benytte deg direkte av dem.

  • CalculationsImpl - Implementasjon av Calculations
  • Calculations - Grensesnitt som implementeres i både CalculationsImpl og CachingCalculations

Du skal fylle ut CachingCalculations og metodene/konstruktør i denne klassen.

CachingCalculations skal delegere til en delegate, som skal utføre arbeidet og deretter memoisere resultatet. memoisere betyr her at hvis metoden får et argument den tidligere har sett skal den heller returnere det tidligere kalkulerte resultatet, enn å be delegate gjøre beregningen på nytt. Denne teknikken brukes gjerne når beregninger er kostbare å utføre.

  • CachingCalculations(Calculations delegate) - Oppretter et CachingCalculations objekt
  • getCalculation1(int number) - Gjør beregning 1
  • getCalculation2(int number) - Gjør beregning 2.
package del3;

public class CalculationsImpl implements Calculations {

	@Override
	public int getCalculation1(int number) {
		return (int) Math.sqrt(number);

	}

	@Override
	public int getCalculation2(int number) {
		return number * number;
	}
}

package del3;

public interface Calculations {
	
	
	public int getCalculation1(int number);
	
	public int getCalculation2(int number);
}

package del3;

public class CachingCalculations implements Calculations {

	public CachingCalculations(Calculations delegate) {
		// TODO
	}

	@Override
	/**
	 * Delegates the job of calculating the square root to the delegate If the
	 * argument has been previously seen, the delegate should not be used and a
	 * local cached version of the result should be returned
	 * 
	 * @returns the calculation applied to the argument
	 */
	public int getCalculation1(int number) {
		// TODO
		return 0;
	}

	@Override
	/**
	 * Delegates the job of calculating the square to the delegate If the argument
	 * has been previously seen, the delegate should not be used and a local cached
	 * version of the result should be returned
	 * 
	 * @returns the calculation applied to the argument
	 */
	public int getCalculation2(int number) {
		// TODO
		return 0;

	}

	public static void main(String[] args) {
		CachingCalculations calc = new CachingCalculations(new CalculationsImpl());
		// Should print 81
		System.out.println(calc.getCalculation2(9));
		// Should print 81 again, should not use the delegate
		System.out.println(calc.getCalculation2(9));
		// Should print 3
		System.out.println(calc.getCalculation1(9));
	}

}



package del3;

import java.util.HashMap;
import java.util.Map;

public class CachingCalculations implements Calculations {

	private Calculations delegate;
	private Map<Integer, Integer> cache1 = new HashMap<>();
	private Map<Integer, Integer> cache2 = new HashMap<>();

	public CachingCalculations(Calculations delegate) {
		this.delegate = delegate;
	}

	@Override
	/**
	 * Delegates the job of calculating the square root to the delegate If the
	 * argument has been previously seen, the delegate should not be used and a
	 * local cached version of the result should be returned
	 * 
	 * @returns the square root of the argument
	 */
	public int getCalculation1(int number) {
		if (cache1.containsKey(number)) {
			return cache1.get(number);
		}
		int result = delegate.getCalculation1(number);
		cache1.put(number, result);
		return result;
	}

	@Override
	/**
	 * Delegates the job of calculating the square to the delegate If the argument
	 * has been previously seen, the delegate should not be used and a local cached
	 * version of the result should be returned
	 * 
	 * @returns the square of the argument
	 */
	public int getCalculation2(int number) {
		if (cache2.containsKey(number)) {
			return cache2.get(number);
		}
		int result = delegate.getCalculation2(number);
		cache2.put(number, result);
		return result;
	}

	public static void main(String[] args) {
		CachingCalculations calc = new CachingCalculations(new CalculationsImpl());
		// Should print 81
		System.out.println(calc.getCalculation2(9));
		// Should print 81 again, should not use the delegate
		System.out.println(calc.getCalculation2(9));
		// Should print 3
		System.out.println(calc.getCalculation1(9));
	}

}


Oppgave a) Objektstrukturer (12 %)

Fyll inn vedlagte Temperature. Temperature har oversikt over en temperatur som enten er i Fahrenheit eller i Celsius.

Temperature har følgende metoder

  • Temperature(double degrees, char scale) - Initialiserer et Temperature-objekt med en skala (Fahrenheit/Celsius) og et antall grader
  • getScale() - Returnerer om temperaturen er i Fahrenheit eller Celsius.
  • getDegrees() - Returnerer temperaturen i antall grader.
  • toOther() - Gjør om dette temperatur-objektet til den andre skalaen og returnerer det.
  • inOther() - Lager et nytt temperatur-objekt i den den andre skalaen og returnerer det.
  • lower(double amount) - Senker temperaturen med et antall grader.
package del4;

public class Temperature {

	// Add any needed fields
	/**
	 * 
	 * @param degrees an arbitrary number
	 * @param scale   a character declaring the scale
	 * 
	 * @throws IllegalArgumentException if scale is not 'C' or 'F'
	 */
	public Temperature(double degrees, char scale) {
		// TODO

	}

	/**
	 * 
	 * @return The current scale
	 */
	public char getScale() {
		// TODO
		return '0';
	}

	/**
	 * 
	 * @return the current degree of this object
	 */
	public double getDegrees() {
		// TODO
		return 0;
	}

	/**
	 * Converts this temperature object to be the opposite scale of what it
	 * currently is
	 * 
	 * @return this temperature object, converted with value in Celsius if the scale
	 *         of this temperature object is Fahrenheit, and value in Fahrenheit if
	 *         this the scale of this temperature object is Celsius
	 */
	public Temperature toOther() {
		// TODO
		return null;
	}

	/**
	 * Creates a new temperature object with values in the other scale of this
	 * temperature object
	 * 
	 * @return a new Temperature object, with value in Celsius if the scale of this
	 *         temperature object is Fahrenheit, and value in Fahrenheit if the
	 *         scale of this temperature object is Celsius
	 */
	public Temperature inOther() {
		// TODO
		return null;
	}

	/**
	 * Lowers the temperature
	 * 
	 * @param amount the amount to lower by
	 */
	public void lower(double amount) {
		// TODO
	}

	/**
	 * 
	 * @param celsius
	 * @return the temperature in Fahrenheit
	 */
	public static double convertCelsisusToFahrenheit(double celsius) {
		return (celsius * 1.8 + 32.0);
	}

	/**
	 * 
	 * @param fahrenheit
	 * @return the temperature in Celsius
	 */
	public static double convertFahrenheitToCelsius(double fahrenheit) {
		return (fahrenheit - 32.0) / 1.8;
	}

	public static void main(String[] args) {
		Temperature t = new Temperature(20, 'C');
		// Should print 20
		System.out.println(t.getDegrees());
		t.lower(10);
		// Should now print 10
		System.out.println(t.getDegrees());
		t.toOther();
		// Should now print 50
		System.out.println(t.getDegrees());
		t.toOther();

		Temperature t2 = t.inOther();
		// Should be 50;
		System.out.println(t2.getDegrees());

		// Should be 10
		System.out.println(t.getDegrees());
	}

}


package del4;

public class Temperature {
	
	private char scale; // Only valid values are C or F
	private double degree;
	
	/**
	 * 
	 * @param degrees an arbitrary number
	 * @param scale a character declaring the scale
	 * 
	 * @throws IllegalArgumentException if scale is not 'C' or 'F'
	 */
	public Temperature(double degrees, char scale) {
		this.degree = degrees;
		if (scale != 'C' && scale != 'F') {
			throw new IllegalArgumentException();
		}
		this.scale = scale;
	}

	/**
	 * 
	 * @return The current scale
	 */
	public char getScale() {
		return scale;
	}

	
	/**
	 * 
	 * @return the current degree of this object
	 */
	public double getDegrees() {
		return degree;
	}

	/**
	 * Converts this temperature object to be the opposite scale of what it
	 * currently is
	 * 
	 * @return this temperature object, converted with value in Celsius if the value
	 *         of this temperature object is Fahrenheit, and value in Fahrenheit if
	 *         this temperature object is Celsius
	 */
	public Temperature toOther() {
		if (this.scale == 'C') {
			this.scale = 'F';
			this.degree = convertCelsisusToFahrenheit(this.degree);
		}
		else {
			this.scale = 'C';
			this.degree = convertFahrenheitToCelsius(this.degree);
		}
		return this;
	}

	/**
	 * Creates a new temperature object with values in the other scale of this
	 * temperature object.
	 * 
	 * @return a new Temperature object, with value in Celsius if the value of this
	 *         temperature object is Fahrenheit, and value in Fahrenheit if this
	 *         temperature object is Celsius
	 */
	public Temperature inOther() {
		if (this.scale == 'C') {
			return new Temperature(convertCelsisusToFahrenheit(this.degree), 'F');
	
		}
		else {
			return new Temperature(convertFahrenheitToCelsius(this.degree), 'C');

		}
	}


	
	/**
	 * Lowers the temperature
	 * @param amount the amount to lower by
	 */
	public void lower(double amount) {
		this.degree -= amount;
	}
	
	/**
	 * 
	 * @param celsius
	 * @return the temperature in Fahrenheit
	 */
	public static double convertCelsisusToFahrenheit(double celsius) {
		return (celsius * 1.8 + 32.0);
	}
	
	/**
	 * 
	 * @param fahrenheit
	 * @return the temperature in Celsius
	 */
	public static double convertFahrenheitToCelsius(double fahrenheit) {
		return (fahrenheit - 32.0) / 1.8;
	}
	
	public static void main(String[] args) {
		Temperature t = new Temperature(20, 'C');
		// Should print 20
		System.out.println(t.getDegrees());
		t.lower(10);
		// Should now print 10
		System.out.println(t.getDegrees());
		t.toOther();
		// Should now print 50
		System.out.println(t.getDegrees());
		t.toOther();

		Temperature t2 = t.inOther();
		// Should be 50;
		System.out.println(t2.getDegrees());

		// Should be 10
		System.out.println(t.getDegrees());
	}


	
	
}


Oppgave b) Delegering (8%)

Fyll inn DelegatingTemperature. DelegatingTemperature skal delegere til et underliggende Temperature-objekt og ha metodene beskrevet under. Du kan gå ut ifra at alle metodene til delegaten fungerer slik de skal.

  • DelegatingTemperature(Temperature delegate, char scale) - Oppretter et DelegatingTemperature-objekt med en skala (Fahrenheit/Celsisus) og et antall grader som er representert i delegaten.
  • getScale() - Returnerer om temperaturen er i Fahrenheit eller Celsius.
  • getDegrees() - Returnerer temperaturen i antall grader.
  • toOther() - Gjør om dette temperatur-objektet til den andre skalaen og returnerer det.
  • inOther() - Lager et nytt temperatur-objekt i den den andre skalaen og returnerer det.
package del4;

public class DelegatingTemperature {

	// Add any needed fields
	/**
	 * 
	 * @param delegate - the Temperature to get degree from
	 * @param scale    a character declaring the scale of this temperature object
	 * 
	 * @throws IllegalArgumentException if scale is not 'C' or 'F'
	 */
	public DelegatingTemperature(Temperature delegate, char scale) {
		// TODO
	}

	/**
	 * 
	 * @return The current scale
	 */
	public char getScale() {
		// TODO
		return '0';
	}

	/**
	 * 
	 * @return the current degree from the delegate, converted to the correct scale
	 */
	public double getDegrees() {
		// TODO
		return 0;
	}

	/**
	 * 
	 * @return this temperature object, with scale converted to Celsius if the
	 *         current scale of this delegatingTemperature object is in Fahrenheit,
	 *         and value in Fahrenheit if this delegatingTemperature object is in
	 *         Celsius
	 */
	public DelegatingTemperature toOther() {
		// TODO
		return null;
	}

	/**
	 * 
	 * @return a new DelegatingTemperature object, with the same delegate, with
	 *         scale converted to Celsius if the current scale of this
	 *         delegatingTemperature object is Fahrenheit, and value in Fahrenheit
	 *         if this delegatingTemperature object is Celsius
	 */
	public DelegatingTemperature inOther() {
		// TODO
		return null;

	}

	public static void main(String[] args) {
		Temperature t = new Temperature(10, 'C');
		DelegatingTemperature dt = new DelegatingTemperature(t, 'F');
		// Should now print 10
		System.out.println(t.getDegrees());
		// Should now print 50
		System.out.println(dt.getDegrees());
		dt.toOther();
		// Should now print 10
		System.out.println(dt.getDegrees());
		// Should now print 10
		System.out.println(t.getDegrees());
	}
}


package del4;

public class DelegatingTemperature {

	// Add any needed fields
	private Temperature delegate;
	private char scale;
	/**
	 * 
	 * @param delegate - the Temperature to get degree from
	 * @param scale    a character declaring the scale of this temperature object
	 * 
	 * @throws IllegalArgumentException if scale is not 'C' or 'F'
	 */
	public DelegatingTemperature(Temperature delegate, char scale) {
		this.delegate = delegate;
		this.setScale(scale);
	}

	/**
	 * 
	 * @return The current scale
	 */
	public char getScale() {
		return this.scale;
	}
	
	private void setScale(char scale) {
		if (scale != 'F' && scale != 'C') {
			throw new IllegalArgumentException() ;
		}
		this.scale = scale;
	}

	/**
	 * 
	 * @return the current degree from the delegate, converted to the correct scale
	 */
	public double getDegrees() {
		if (this.scale == this.delegate.getScale()) {
			return this.delegate.getDegrees();
		}
		return this.delegate.inOther().getDegrees();
	}

	/**
	 * 
	 * @return this temperature object, with scale converted to Celsius if the
	 *         current scale of this delegatingTemperature object is in Fahrenheit, and
	 *         value in Fahrenheit if this delegatingTemperature object is in Celsius
	 */
	public DelegatingTemperature toOther() {
		this.scale = this.scale == 'C' ? 'F' : 'C';
		return this;
	}

	/**
	 * 
	 * @return a new DelegatingTemperature object, with the same delegate, with
	 *         scale converted to Celsius if the current scale of this
	 *         delegatingTemperature object is Fahrenheit, and value in Fahrenheit
	 *         if this delegatingTemperature object is Celsius
	 */
	public DelegatingTemperature inOther() {
		return new DelegatingTemperature(this.delegate, this.scale == 'C' ? 'F' : 'C');

	}

	public static void main(String[] args) {
		Temperature t = new Temperature(10, 'C');
		DelegatingTemperature dt = new DelegatingTemperature(t, 'F');
		// Should now print 10
		System.out.println(t.getDegrees());
		// Should now print 50
		System.out.println(dt.getDegrees());
		dt.toOther();
		// Should now print 10
		System.out.println(dt.getDegrees());
		// Should now print 10
		System.out.println(t.getDegrees());
	}
}


Del 5, 6, 7 og 8 bygger på hverandre, men kan løses uavhengig av hverandre selv om main-metodene da ikke nødvendigvis vil gi rett resultat. Det vil ofte kreve at du har forstått hva metodene skal gjøre, men du kan gå ut ifra at implementasjonen er rett selv om du ikke har fått til en metode.


Ta utgangspunkt i Property-klassen. Property er en klasse som implementerer en eiendom som kan motta bud for å bli kjøpt.

Interessenter i eiendommen er interessert i å kunne lytte på nye bud Bid på eiendommen.

Fyll ut nødvendige metoder og felt for å støtte lytting i Property klassen, for å gjøre det mulig og lytte på nye bud på eiendommen. Følgende metoder skal implementeres:

  • setIsSold() - Markerer eiendommen som solgt.
  • addListener(BidListener listener) - Registrerer en lytter
  • emoveListener(BidListener listener) - Fjerner en lytter
  • bidReceived(String bidder, int bid) - Oppretter et nytt Bid og registrerer dette, og sier ifra registrerte lyttere avhengig om budet er det høyeste til nå eller ikke.
  • addListenerForHighestBids(BidListener listener) - Registrerer en lytter som kun skal lytte på bud som er det høyeste budet til nå
  • notifyListeners(Bid bid) - Sier ifra til alle lytterne om det nye budet
  • getHighestBid - Returnererer det høyeste budet
package del5_8;

public class Property {

	// Add any needed fields here

	/**
	 * 
	 * @param name  the name of the property to be sold
	 * @param price the listing price of the property
	 */
	public Property(String name, int price) {
		// TODO
	}

	/**
	 * 
	 * @return the name of the property
	 */
	public String getName() {
		// TODO
		return null;
	}

	/**
	 * 
	 * @return the price of the property
	 */
	public int getPrice() {
		// TODO
		return 0;
	}

	/**
	 * 
	 * @return whether the property is sold, default value is false
	 */
	public boolean isSold() {
		// TODO
		return false;
	}

	/**
	 * Sets the property as sold
	 * 
	 * @throws IllegalStateException if no bids have been received
	 */
	public void setIsSold() {
		// TODO
	}

	/**
	 * 
	 * @return the number of bids received on this property
	 */
	public int getNumberOfBids() {
		// TODO
		return 0;
	}

	/**
	 * 
	 * @param listener register listener to be notified of any bids to this property
	 */
	public void addListenerForAllBids(BidListener listener) {
		// TODO
	}

	/**
	 * 
	 * @param listener register listener to be notified of only bids that are new
	 *                 highest bids You do not need to handle the case where a
	 *                 listener gets registered both for highest bid and for all
	 *                 bids
	 */
	public void addListenerForHighestBids(BidListener listener) {
		// TODO
	}

	/**
	 * 
	 * @param listener removes listener from this property, registered with any of
	 *                 the above methods
	 */
	public void removeListener(BidListener listener) {
		// TODO
	}

	/**
	 * Creates a new bid object and notifies all listeners that a bid has been given
	 * 
	 * @param bidder the name of the bidder
	 * @param bid    the amount of the bid
	 * 
	 * @throws IllegalStateException - if the property is already sold
	 */
	public void bidReceived(String bidder, int bid) {
		// TODO
	}

	/**
	 * Notifies listeners that a bid has been received. There are currently no
	 * listeners implemented in the main method, but this is used for test purposes
	 * by us after the exam.
	 * 
	 * This is package private for testing purposes
	 * 
	 * @param bid the most recent bid
	 */
	void notifyListeners(Bid bid) {
		// TODO
	}

	/**
	 * 
	 * @return the current highest bid. If the property has no bids, return 0
	 */
	public int getHighestBid() {
		// TODO
		return 0;
	}

	public static void main(String[] args) {
		Property p = new Property("name", 1000);
		p.bidReceived("BIDDER", 500);
		// 500
		System.out.println(p.getHighestBid());
		p.bidReceived("BIDDER2", 1100);
		// 1100
		System.out.println(p.getHighestBid());
		// false
		System.out.println(p.isSold());
		p.setIsSold();
		// true
		System.out.println(p.isSold());

	}
}







package del5_8;

public class Bid {
	
	private int bid;
	private Property property;
	private String bidder;
	
	public Bid(String bidder, Property property, int bid) {
		this.bid = bid;
		this.property = property;
		this.bidder = bidder;
	}

	public int getBid() {
		return bid;
	}

	public Property getProperty() {
		return property;
	}

	public String getBidder() {
		return bidder;
	}
	
	public boolean equals(Object otherBid) {
		
		if (otherBid instanceof Bid) {
			Bid bid2 = (Bid) otherBid;
			boolean isBidEqual = this.bid == bid2.bid;
			boolean isPropertyEqual = this.property.getName().equals(bid2.property.getName());
			boolean isBidderEqual = this.bidder.equals(bid2.bidder);
			boolean isEqual = isBidEqual &&  isPropertyEqual && isBidderEqual;
			return isEqual;
		}
		return false;

	}
	
	public String toString() {
		return this.property.getName() + bid;
	}
	

}
package del5_8;

import java.util.ArrayList;
import java.util.List;

public class Property {

	private String name;
	private List<BidListener> interests = new ArrayList<>();
	private List<BidListener> highestBidInterests = new ArrayList<>();
	private List<Bid> bids = new ArrayList<>();
	private int price;
	private boolean isSold = false;

	/**
	 * 
	 * @param name  the name of the property to be sold
	 * @param price the listing price of the property
	 */
	public Property(String name, int price) {
		this.name = name;
		this.price = price;
	}

	/**
	 * 
	 * @return the name of the property
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * 
	 * @return the price of the property
	 */
	public int getPrice() {
		return this.price;
	}

	/**
	 * 
	 * @return whether the property is sold, default value is false
	 */
	public boolean isSold() {
		return this.isSold;
	}

	/**
	 *
	 * @return the number of bids received on this property
	 */
	public int getNumberOfBids() {
		return this.bids.size();
	}

	/**
	 * Sets the property as sold
	 * 
	 * @throws IllegalStateException if no bids have been received
	 */
	public void setIsSold() {
		// TODO
		if (this.bids.size() == 0) {
			throw new IllegalStateException("no bids received");
		}
		this.isSold = true;
	}

	/**
	 * 
	 * @param listener register listener to be notified of any bids to this property
	 */
	public void addListenerForAllBids(BidListener listener) {
		// TODO
		this.interests.add(listener);
	}

	/**
	 * 
	 * @param listener register listener to be notified of only bids that are higher
	 *                 than the current highest bid
	 */
	public void addListenerForHighestBids(BidListener listener) {
		this.highestBidInterests.add(listener);
	}

	/**
	 * 
	 * @param listener removes listener from this property
	 */
	public void removeListener(BidListener listener) {
		// TODO
		this.interests.remove(listener);
	}

	/**
	 * Creates a new bid object and notifies all listeners that a bid has been given
	 * 
	 * @param bidder the name of the bidder
	 * @param bid    the amount of the bid
	 * 
	 * @throws IllegalStateException - if the property is already sold.
	 */
	public void bidReceived(String bidder, int bid) {
		// TODO
		if (this.isSold()) {
			throw new IllegalStateException();
		}
		Bid b = new Bid(bidder, this, bid);
		this.notifyListeners(b);
		this.bids.add(b);
	}

	/**
	 * Notifies listener that a bid has been received
	 * 
	 * @param bid the most recent bid
	 */
	public void notifyListeners(Bid bid) {
		this.interests.forEach(listener -> listener.propertyBid(bid));
		if (bid.getBid() > this.getHighestBid()) {
			this.highestBidInterests.forEach(listener -> listener.propertyBid(bid));
		}
	}

	/**
	 * 
	 * @return the current highest bid. If the property has no bids, return 0
	 */
	public int getHighestBid() {
		return this.bids.stream().mapToInt(b -> b.getBid()).max().orElse(0);
	}

	public static void main(String[] args) {
		Property p = new Property("name", 1000);
		p.bidReceived("BIDDER", 500);
		// 500
		System.out.println(p.getHighestBid());
		p.bidReceived("BIDDER2", 1100);
		// 1100
		System.out.println(p.getHighestBid());
		// false
		System.out.println(p.isSold());
		p.setIsSold();
		// true
		System.out.println(p.isSold());

	}

}

BusinessProperty BusinessProperty arver fra Property men har noe ulik oppførsel.

BusinessProperty tar imot bud på samme måte, men skal registreres som solgt med en gang et bud som er over prisen på eiendommen er satt.

Gjør nødvendige endringer for å få til dette i BusinessProperty.

package del5_8;

public class BusinessProperty extends Property {

	/**
	 * BusinessProperty should implement the following extensions from Property. As
	 * soon as a bid is received that is equal to or higher than the price, the
	 * property should be marked as sold
	 */

	public BusinessProperty(String name, int price) {
		super(name, price);
	}

	public static void main(String[] args) {
		Property p = new BusinessProperty("name", 1000);
		p.bidReceived("BIDDER", 500);
		// 500
		System.out.println(p.getHighestBid());
		p.bidReceived("BIDDER2", 1100);
		// 1100
		System.out.println(p.getHighestBid());
		// true
		System.out.println(p.isSold());

package del5_8;

public class BusinessProperty extends Property {

	/**
	 * BusinessProperty should implement the following extensions from Prope rty. As
	 * soon as a bid is received that is equal to or higher than the price, the
	 * property should be marked as sold
	 */
	public BusinessProperty(String name, int price) {
		super(name, price);
	}

	@Override
	/**
	 * Creates a new bid and notifies any listeners that the bid has been received
	 * If the bid is higher oe equal than the asking price, the property should be
	 * registered as sold
	 * 
	 * @param bidder the name of the bidder
	 * @param bid    the amount of the bid
	 */
	public void bidReceived(String bidder, int bid) {
		super.bidReceived(bidder, bid);
		if (bid >= this.getPrice()) {
			this.setIsSold();
		}
	}

	public static void main(String[] args) {
		Property p = new BusinessProperty("name", 1000);
		p.bidReceived("BIDDER", 500);
		// 500
		System.out.println(p.getHighestBid());
		p.bidReceived("BIDDER2", 1100);
		// 1100
		System.out.println(p.getHighestBid());
		// true
		System.out.println(p.isSold());
	}
}

Implementer metodene i Realtor

  • Realtor(double comission) oppretter et Realtor objekt med en gitt provisjon
  • setCommission(double comission) Oppdaterer provisjonen til megleren
  • addProperty(Property property) Legger til en eiendom i porteføljen til megleren
  • calculateTotalCommission() - Regner ut total provisjonslønn basert på alle solgte boliger megleren har
  • iterator() - Returnerer en iterator for å iterere gjennom alle eiendommene til megleren
package del5_8;

import java.util.Iterator;

public class Realtor implements Iterable<Property> {

	/**
	 * Creates a Realtor object
	 * 
	 * @param name       the name of the realtor
	 * @param commission the commission the realtor takes for a sale
	 */
	public Realtor(String name, double commission) {
		// TODO
	}

	/**
	 * 
	 * @return the name of the realtor
	 */
	public String getName() {
		// TODO
		return null;
	}

	/**
	 * 
	 * @param commission the new commission of the realtor
	 * 
	 * @throws IllegalArgumentException if the commission not between (excluding) 0
	 *                                  and (including) 100.
	 */
	public void setCommission(double commission) {
		// TODO
	}

	/**
	 * Adds a property to the realtor's sale collection
	 * 
	 * @param property a property
	 */
	public void addProperty(Property property) {
		// TODO
	}

	/**
	 * The total commission is calculated as the sum of the highest bid of each sold
	 * property times the commission rate. The commission rate is calculated based
	 * on the realtor's current commission rate and does not need to consider
	 * historical commission rates
	 * 
	 * A realtor with commission of 10 %, and two sold properties sold at 1000 each,
	 * would have a total commission value of 200
	 * 
	 * @return the calculated commission of the realtor
	 */
	public double calculateTotalCommission() {
		// TODO
		return 0;
	}

	@Override
	public Iterator<Property> iterator() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * 
	 * @return an iterator to be able to iterate through all the properties of this
	 *         realtor
	 */
	public Iterator<Property> iterable() {
		return null;
	}

	public static void main(String[] args) {
		Realtor realtor = new Realtor("test", 10);
		// The following will only work if BusinessProperty and Property has the correct
		// implementation
		Property p = new Property("name", 1500);
		p.bidReceived("BIDDER", 2000);
		p.setIsSold();
		realtor.addProperty(p);
		// Should be 200
		System.out.println(realtor.calculateTotalCommission());
	}

}
package del5_8;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Realtor implements Iterable<Property>{

	private List<Property> properties = new ArrayList<>();
	private double commission;
	private String name;
	/**
	 * Creates a Realtor object
	 * 
	 * @param name      the name of the realtor
	 * @param comission the commission the realtor takes for a sale
	 */
	public Realtor(String name, double commission) {
		this.setCommission(commission);
		this.name = name;
	}
	
	public String getName() {
		return this.name;
	}

	/**
	 * 
	 * @param comission the new comission of the realtor
	 * 
	 * @throws IllegalArgumentException if the commission not between (excluding) 0
	 *                                  and (including) 100.
	 */
	public void setCommission(double commission) {
		if (commission <= 0 || commission > 100) {
			throw new IllegalArgumentException("Comission must be between 0 and 100");
		}
		this.commission = commission;
	}

	/**
	 * Adds a property to the realtor's sale collection
	 * 
	 * @param property a property
	 */
	public void addProperty(Property property) {
		this.properties.add(property);
	}

	/**
	 * The total comission is calculated as the sum of the highest bid of each sold
	 * property times the commission rate The comission rate is calculated based on
	 * the realtor's current commission rate and does not need to consider
	 * historical commission rates
	 * 
	 * @return the calculated commission of the realtor
	 */
	public double calculateTotalCommission() {
		return this.properties.stream().filter(p -> p.isSold()).mapToDouble(Property::getHighestBid)
				.map(price -> price * (commission) / 100.0).sum();
	}

	@Override
	public Iterator<Property> iterator() {
		return this.properties.iterator();
	}
	
	public String toString() {
		return this.name;
	}	
	public static void main(String[] args) {
		Realtor realtor = new Realtor("test", 10);
		// Will only work if BusinessProperty and Property has the correct
		// implementation
		Property p = new Property("name", 1500);
		p.bidReceived("BIDDER", 2000);
		p.setIsSold();
		realtor.addProperty(p);
		// Should be 200
		System.out.println(realtor.calculateTotalCommission());
	}

}

Implementer metoden i RealtorComparator

  • sortRealtorsByHighestBidReceived - Returnerer en Comparator som sorterer en liste med Realtor-objekter. Disse skal sorteres etter hvilken megler som har oppnådd det høyeste budet basert på alle eiendommene fra høyest til lavest

    package del5_8;
    
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class RealtorComparator {
    
    	/**
    	 * 
    	 * @return a comparator that sorts Realtor objects based on the highest bid they
    	 *         have received on any of their properties from highest to lowest
    	 * 
    	 *         Example output with a list of one "realtor1" with two properties,
    	 *         property1 with highest bid 1000, and property2 with highest bid 2000,
    	 *         and a second "realtor2" with one property with the highest bid of
    	 *         500, and a third "realtor3" with one property with the highest bid of
    	 *         3000 would yield the following result
    	 * 
    	 *         realtor3
    	 *         realtor1 
    	 *         realtor2
    	 * 
    	 *         I.e: This sorts by the highest, single sale, and not the total of
    	 *         sales for each realtor.
    	 * 
    	 * 
    	 */
    	public static Comparator<Realtor> sortRealtorsByHighestBidReceived() {
    		return null;
    	}
    
    	public static void main(String[] args) {
    		// This may not yield the correct results if Property/BusinessProperty/Realtor
    		// has not been correctly implemented
    		Realtor realtor = new Realtor("test1", 10);
    		Realtor realtor2 = new Realtor("test2", 10);
    		Property p = new BusinessProperty("name", 1500);
    		p.bidReceived("BIDDER", 2000);
    		Property p2 = new BusinessProperty("name2", 1000);
    		p2.bidReceived("BIDDER", 1500);
    		realtor.addProperty(p);
    		realtor2.addProperty(p2);
    		List<Realtor> realtors = Arrays.asList(realtor2, realtor);
    		System.out.println(realtors);
    		Collections.sort(realtors, sortRealtorsByHighestBidReceived());
    		// A more useful to string method or using the debugger might be helpful here
    		// Should be in the opposite direction with realtor, and then realtor2
    		System.out.println(realtors);
    
    	}
    
    }
    
    package del5_8;
    
    
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class RealtorComparator {
    
    	/**
    	 * 
    	 * @return a comparator that sort Realtor objects based on the highest bid they
    	 *         have received on any of their properties from highest to lowest
    	 * 
    	 *         Example output with a list of one "realtor1" with two properties,
    	 *         property1 with highest bid 1000, and property2 with highest bid 2000,
    	 *         and a second "realtor2" with one property with the highest bid of
    	 *         500, and a third "realtor3" with one property with the highest bid of
    	 *         3000 would yield the following result
    	 * 
    	 *         realtor3 
    	 *         realtor1 
    	 *         realtor2
    	 * 
    	 * 
    	 */
    	public static Comparator<Realtor> sortRealtorsByHighestBidReceived() {
    		return (Realtor r1, Realtor r2) -> {
    			int highestBidR1 = 0;
    			for (Property property: r1) {
    				highestBidR1 = Math.max(highestBidR1, property.getHighestBid());
    			}
    			int highestBidR2 = 0;
    			for (Property property: r2) {
    				highestBidR1 = Math.max(highestBidR2, property.getHighestBid());
    			}
    			return highestBidR2-highestBidR1;
    		};
    	}
    	
    	public static void main(String[] args) {
    		// This may not yield the correct results if Property/BusinessProperty/Realtor has not been correctly implemented
    		Realtor realtor = new Realtor("test1", 10);
    		Realtor realtor2 = new Realtor("test2", 10);
    		Property p = new BusinessProperty("name", 1500);
    		p.bidReceived("BIDDER", 2000);
    		Property p2 = new BusinessProperty("name2", 1000);
    		p2.bidReceived("BIDDER", 1500);
    		realtor.addProperty(p);
    		realtor2.addProperty(p2);
    		List<Realtor> realtors=  Arrays.asList(realtor2, realtor);
    		System.out.println(realtors);
    		Collections.sort(realtors, sortRealtorsByHighestBidReceived());
    		// A more useful to string method or using the debugger might be helpful here
    		System.out.println(realtors);
    		
    	}
    
    }
    

Fyll ut UniversityHandbookUtils sine metoder for operasjoner på en liste med Course-objekter.

    • getCourseNames(List courses) - Returnerer en liste med navnene til alle emnene
    • getCourseProperties(List courses, Function<Course, String> function) - Returnerer alle emner transformerte ved hjelp av funksjonen
    • calculateGradesSummary(List courses, BinaryOperator operator) - Returnerer resultatet av å kjøre operatoren på alle karaktersnittene til emnene
    • getCoursesYouCanTake(List courses, List takenCourses) - Returnerer alle emnene hvor du tilfredstiller alle forkunnskapskravene (takenCourses representerer her emnene du tidligere har tatt)

package del9;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Course {
	private String courseName;
	private List<Course> prerequisites = new ArrayList<>();
	private double averageGrade;

	public Course(String courseName, double averageGrade) {
		this(courseName);
		this.averageGrade = averageGrade;
	}

	public Course(String courseName) {
		this.courseName = courseName;
	}
	
	public String getCourseName() {
		return courseName;
	}

	public void setAverageGrade(double averageGrade) {
		this.averageGrade = averageGrade;
	}
	
	public double getAverageGrade() {
		return averageGrade;
	}

	public void addPrequisite(Course course) {
		this.prerequisites.add(course);
	}
	
	public Collection<Course> getPrerequisites() {
		return new ArrayList<>(prerequisites);
	}
	
	public String toString() {
		return this.courseName;
	}

}

package del9;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Function;

public class UniversityHandbookUtils {

	/**
	 * 
	 * @param courses List of course objects
	 * @return a list of course names
	 */
	public static Collection<String> getCourseNames(Collection<Course> courses) {
		// TODO
		return Arrays.asList();
	}

	/**
	 * 
	 * @param courses List of course objects
	 * @return a list of a course objects transformed by the function
	 */
	public static Collection<String> getCourseProperties(Collection<Course> courses,
			Function<Course, String> function) {
		// TODO
		return Arrays.asList();
	}

	/**
	 * 
	 * @param courses  a list of course objects
	 * @param operator a binary operator
	 * @return the result of applying the operator across all average grades
	 */
	public static double calculateGradesSummary(Collection<Course> courses, BinaryOperator<Double> operator) {
		// TODO
		return 0;
	}

	/**
	 * 
	 * @param courses      List of course objects
	 * @param takenCourses List of course objects
	 * @return a list of courses where takenCourses contains all prerequisites
	 *         needed to enroll in the course
	 */
	public static Collection<Course> getCoursesYouCanTake(Collection<Course> courses, Collection<Course> takenCourses) {
		// TODO
		return Arrays.asList();
	}

	public static void main(String[] args) {
		Course tdt4109 = new Course("TDT4109", 3.23);
		Course tdt4100 = new Course("TDT4100", 3.23);
		Course tdt4120 = new Course("TDT4120", 3.23);
		Course tdt1337 = new Course("TDT1337", 3.23);
		Course tdt3713 = new Course("TDT3713", 3.23);

		tdt4100.addPrequisite(tdt4109);
		tdt4120.addPrequisite(tdt4109);
		tdt4120.addPrequisite(tdt4100);
		tdt1337.addPrequisite(tdt3713);
		tdt3713.addPrequisite(tdt1337);
		List<Course> courses = Arrays.asList(tdt4109, tdt4100, tdt4120, tdt1337, tdt3713);

		// These two lines should print the same list of course names
		System.out.println(getCourseNames(courses));
		System.out.println(getCourseProperties(courses, c -> c.getCourseName()));

		// Should print 16.15
		System.out.println(calculateGradesSummary(courses, (prevGrade, currentGrade) -> prevGrade + currentGrade));

		// Should print tdt4109, tdt4100 (order does not matter)
		System.out.println(getCoursesYouCanTake(courses, Arrays.asList(tdt4109)));

	}

}
package del9;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

public class UniversityHandbookUtils {

	/**
	 * 
	 * @param courses List of course objects
	 * @return a list of course names
	 */
	public static List<String> getCourseNames(Collection<Course> courses) {
		return courses.stream().map(Course::getCourseName).collect(Collectors.toList());
	}

	/**
	 * 
	 * @param courses List of course objects
	 * @return a list of a course objects transformed by the function
	 */
	public static Collection<String> getCourseProperties(Collection<Course> courses,
			Function<Course, String> function) {
		return courses.stream().map(function).collect(Collectors.toList());
	}

	/**
	 * 
	 * @param courses  a list of course objects
	 * @param operator a binary operator
	 * @return a summary of all the grades of the courses by applying the binary
	 *         operator
	 */
	public static double calculateGradesSummary(Collection<Course> courses, BinaryOperator<Double> operator) {
		return courses.stream().map(Course::getAverageGrade).reduce(operator).get();

	}

	/**
	 * 
	 * @param courses      List of course objects
	 * @param takenCourses List of course objects
	 * @return a list of courses where takenCourses contains all prerequisites
	 *         needed to enroll in the course
	 */
	public static Collection<Course> getCoursesYouCanTake(Collection<Course> courses, Collection<Course> takenCourses) {
		return courses.stream().filter(course -> takenCourses.containsAll(course.getPrerequisites()))
				.collect(Collectors.toList());
	}
	
	public static void main(String[] args) {
		Course tdt4109 = new Course("TDT4109", 3.23);
		Course tdt4100 = new Course("TDT4100", 3.23);
		Course tdt4120 = new Course("TDT4120", 3.23);
		Course tdt1337 = new Course("TDT1337", 3.23);
		Course tdt3713 = new Course("TDT3713", 3.23);

		tdt4100.addPrequisite(tdt4109);
		tdt4120.addPrequisite(tdt4109);
		tdt4120.addPrequisite(tdt4100);
		tdt1337.addPrequisite(tdt3713);
		tdt3713.addPrequisite(tdt1337);
		List<Course> courses = Arrays.asList(tdt4109, tdt4100, tdt4120, tdt1337, tdt3713);
		
		// These two lines should print the same list of course names
		System.out.println(getCourseNames(courses));
		System.out.println(getCourseProperties(courses, c -> c.getCourseName()));
		
		// Should print 16.15 
		System.out.println(calculateGradesSummary(courses, (prevGrade, currentGrade) -> prevGrade + currentGrade));
		
		// Should print tdt4109, tdt4100 (order does not matter) 
		System.out.println(getCoursesYouCanTake(courses, Arrays.asList(tdt4109)));
		
	}


}

Ta utgangspunkt i TestableClass. De to metodene utenom konstruktøren har feil i implementasjonen, eller håndterer ikke alle tilfeller like godt.

Fyll ut testmetodene i TestableClassTest i src/test/java/del10 som skal eksponere feilene. (Testen bør ikke bestå)

  • testIsMyStringEqualsToYieldsWrongResult() - Fanger opp et tilfelle hvor isMyStringEqualsTo gir feil resultatet
  • testIncrementIntegerHandlesEdgeCases() - Fanger opp et tilfelle hvor getMyIntegerIncrement ikke oppfører seg slik den skal.
package del10;

public class TestableClass {
	
	private Integer myInteger;
	private String myString;
	
	public TestableClass(Integer myInteger, String myString) {
		this.myInteger = myInteger;
		this.myString = myString;
	}
	
	/**
	 * 
	 * @param otherString a string
	 * @return whether myString text value is equal to the otherString
	 */
	public boolean isMyStringEqualTo(String otherString) {
		return this.myString == otherString;
	}
	
	/**
	 * 
	 * @return myInteger + 1;
	 */
	public Integer getMyIntegerIncrement() {
		return this.myInteger + 1;
	}
}


package del10;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class TestableClassTest {

	@Test
	public void testIsMyStringEqualsToYieldsWrongResult() {

	}

	@Test
	public void testIncrementIntegerHandlesEdgeCases() {

	}
}


package del10;

public class TestableClass {

	private Integer myInteger;
	private String myString;
	
	public TestableClass(Integer myInteger, String myString) {
		this.myInteger = myInteger;
		this.myString = myString;
	}
	
	/**
	 * 
	 * @param otherString a string
	 * @return whether myString text value is equal to the otherString
	 */
	public boolean isMyStringEqualTo(String otherString) {
		return this.myString == otherString;
	}
	
	/**
	 * 
	 * @return myInteger + 1;
	 */
	public Integer getMyIntegerIncrement() {
		return this.myInteger + 1;
	}

}

package del10;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class TestableClassTest {

	@Test
	public void testIsMyStringEqualsToYieldsWrongResult() {
		TestableClass test = new TestableClass(1, "test");
		String equalString = new String("test");
		Assertions.assertTrue(test.isMyStringEqualTo(equalString));
		
	}
	
	@Test
	public void testIncrementIntegerHandlesEdgeCases() {
		TestableClass test = new TestableClass(null, "test");
		Assertions.assertNull(test.getMyIntegerIncrement());

	}
}