Musterklausur
Hinweise zur Klausur
- Die in dieser Klausur verwendeten Personenbezeichnungen beziehen sich – sofern nicht anders kenntlich gemacht – auf alle Geschlechter
- Pakete und Klassenimporte müssen nicht angegeben werden
- Die Klassen und Annotationen der Bibliotheken Lombok, JUnit 5 und Mockito dürfen verwendet werden
- Es kann davon ausgegangen werden, dass sämtliche Klassen entsprechende Implementierungen der Object-Methoden besitzen
- So nicht anders angegeben sollen Konstruktoren, Setter, Getter sowie die Object-Methoden wie in der Vorlesung gezeigt implementiert werden
- Die Konsolenausgaben-Methoden der Klasse
PrintStream
dürfen sinnvoll gekürzt geschrieben werden (zum Beispiel syso("Hello World") statt System.out.println("Hello World")) - Methoden- und Attributsbezeichner dürfen sinnvoll gekürzt geschrieben werden (zum Beispiel getLWMCP() statt getLectureWithMostCreditPoints())
Aufgabe 1 (16 Punkte)
Erstelle die Klasse SuperLeague<T extends SuperHuman>
anhand des abgebildeten
Klassendiagrams.
Klassendiagramm
Hinweise zur Klasse SuperLeague
- Die Schlüssel-Werte-Paare des Assoziativspeichers beinhalten als Schlüssel die Übermenschen der Liga sowie als Wert deren Verfügbarkeit
- Die Methode
Optional<T> getMostPowerfulSuperHuman()
soll den stärksten Übermenschen der Liga zurückgeben (5,5 Punkte) - Die Methode
void addSuperHuman(t: T)
soll der Liga den eingehenden Übermenschen als verfügbares Mitglied hinzufügen. Für den Fall, dass das Universum des eingehenden Übermenschen nicht dem Universum der Liga entspricht, soll die AusnahmeWrongUniverseException
ausgelöst werden (4 Punkte) - Die Methode
List<T> getAllAvailableSuperHumans()
soll alle verfügbaren Übermenschen der Liga zurückgeben (4,5 Punkte)
Musterlösung
SuperLeage.java
public record SuperLeague<T extends SuperHuman>(String name, Universe universe,
Map<T, Boolean> members) { // 2
public Optional<T> getMostPowerfulSuperHuman() { // 0,5
T mostPowerfulSuperHuman = null; // 0,5
int power = 0; // 0,5
for (T t : members.keySet()) { // 1
if (t.power() > power) { // 1
power = t.power(); // 0,5
mostPowerfulSuperHuman = t; // 0,5
}
}
return Optional.ofNullable(mostPowerfulSuperHuman); // 1
} // 5,5
public void addSuperHuman(T t) throws WrongUniverseException { // 1
if (!t.universe().equals(universe)) { // 1
throw new WrongUniverseException(); // 1
}
members.put(t, true); // 1
} // 4
public List<T> getAllAvailableSuperHumans() { // 0,5
List<T> allAvailableSuperHumans = new ArrayList<>(); // 0,5
for (Entry<T, Boolean> entry : members.entrySet()) { // 1
if (entry.getValue().equals(true)) { // 1
allAvailableSuperHumans.add(entry.getKey()); // 1
}
}
return allAvailableSuperHumans; // 0,5
} // 4,5
} // 16
Aufgabe 2 (18 Punkte)
Erstelle die JUnit-5-Testklasse SuperLeagueTest
anhand des abgebildeten
Klassendiagramms.
Klassendiagramm
Hinweise zur Klasse SuperLeagueTest
- Die Lebenszyklus-Methode
void setUp()
soll sämtliche Mock-Objekte sowie die Superheldenliga Avengers (Name: Avengers, Universum: MARVEL) erstellen und den entsprechenden Attributen zuweisen und der Superheldenliga Avengers den Superhelden Iron Man als verfügbaren sowie den Superhelden Spider-Man als nicht verfügbaren Superhelden hinzufügen (5 Punkte) - Die Testmethode
void testAddSuperHuman()
soll prüfen, ob beim Aufruf der Methodevoid addSuperHuman(t: T)
mit dem Superhelden Superman die AusnahmeWrongUniverseException
ausgelöst wird. Hierzu soll das Mock-Objekt Superman beim Aufruf der MethodeUniverse universe()
den Wert DC zurückgeben (3 Punkte) - Die Testmethode
void testGetAllAvailableSuperHumans()
soll prüfen, ob beim Aufruf der MethodeList<T> getAllAvailableSuperHumans()
eine Liste der Größe 1 zurückgegeben wird (2,5 Punkte) - Die Testmethode
void testGetMostPowerfulSuperHuman()
soll prüfen, ob beim Aufruf der MethodeOptional<T> getMostPowerfulSuperHuman()
der Superheld Spider-Man als Optional zurückgegeben wird. Hierzu soll das Mock-Objekt Iron Man beim Aufruf der Methodeint power()
den Wert 7 und das Mock-Objekt Spider-Man den Wert 8 zurückgeben (3,5 Punkte)
Musterlösung
SuperLeagueTest.java
public class SuperLeagueTest { // 0,5
private SuperLeague<Hero> avengers; // 0,5
@Mock // 0,5
private Hero superman; // 0,5
@Mock // 0,5
private Hero ironman; // 0,5
@Mock // 0,5
private Hero spiderman; // 0,5
@BeforeEach // 0,5
void setUp() { // 0,5
MockitoAnnotations.openMocks(this); // 1
avengers = new SuperLeague<>("Avengers", Universe.MARVEL, new HashMap<>()); // 1
avengers.getMembers().put(ironman, true); // 1
avengers.getMembers().put(spiderman, false); // 1
} // 5
@Test // 0,5
void testAddSuperHuman() { // 0,5
when(superman.universe()).thenReturn(Universe.DC); // 0,5
assertThrows(WrongUniverseException.class, () -> avengers.addSuperHuman(superman)); // 1,5
} // 3
@Test // 0,5
void testGetAllAvailableSuperHumans() { // 0,5
List<Hero> heroes = avengers.getAllAvailableSuperHumans(); // 0,5
assertEquals(1, heroes.size()); // 1
} // 2,5
@Test // 0,5
void testGetMostPowerfulSuperHuman() { // 0,5
when(ironman.power()).thenReturn(7); // 0,5
when(spiderman.power()).thenReturn(8); // 0,5
assertEquals(Optional.of(spiderman), avengers.getMostPowerfulSuperHuman()); // 1,5
} // 3,5
} // 18
Aufgabe 3 (18 Punkte)
Erstelle die Klasse SingleQueries
anhand des abgebildeten Klassendiagramms.
Klassendiagramm
Hinweise zur Klasse SingleQueries
- Die Methode
void printAllSinglesWithMoreThan25MillionSalesPerCountry()
soll alle Singles, die sich mehr als 25 Millionen mal verkauft haben, gruppiert nach dem Land in der Form [Land des Künstlers]: [Singles] ausgeben (4 Punkte) - Die Methode
void printAverageBirthYearOfAllDeceasedArtists()
soll das durchschnittliche Geburtsjahr aller verstorbenen Künstler ausgeben. Für den Fall, dass es keinen verstorbenen Künstler gibt, soll der Wert -1 ausgegeben werden (5,5 Punkte) - Die Methode
boolean isAnySingleFromChinaWithMoreThan10MillionSales()
soll zurückgeben, ob es eine Single eines Künstlers aus China (3,5 Punkte) gibt, welche sich mehr als 10 Millionen Mal verkauft hat - Die Methode
List<Single> getAllSinglesFromEdSheeran()
soll alle Singles des Künstlers Ed Sheeran (Land: Großbritannien, Geburtstag: 17.02.1991, Status: lebendig) zurückgeben (4 Punkte)
Musterlösung
SingleQueries
public record SingleQueries(List<Single> singles) { // 1
public void printAllSinglesWithMoreThan25MillionSalesPerCountry() { // 0,5
Map<Country, List<Single>> allSinglesWithMoreThan25MillionSalesPerCountry; // 0,5
allSinglesWithMoreThan25MillionSalesPerCountry = singles.stream() // 0,5
.filter(s -> s.salesInMillions() > 25) // 0,5
.collect(Collectors.groupingBy(s -> s.artist().country())); // 1
allSinglesWithMoreThan25MillionSalesPerCountry
.forEach((c, sl) -> System.out.println(c + ": " + sl)); // 1
} // 4
public void printAverageBirthYearOfAllDeceasedArtists() { // 0,5
OptionalDouble averageBirthYearOfAllDeceasedArtists; // 0,5
averageBirthYearOfAllDeceasedArtists = singles.stream() // 0,5
.map(Single::artist) // 0,5
.distinct() // 0,5
.filter(a -> !a.isAlive()) // 0,5
.mapToInt(a -> a.birthdate().getYear()) // 1
.average(); // 0,5
averageBirthYearOfAllDeceasedArtists.ifPresentOrElse(System.out::println,
() -> System.out.println(-1)); // 1
} // 5,5
public boolean isAnySingleFromChinaWithMoreThan10MillionSales() { // 0,5
boolean isAnySingleFromChinaWithMoreThan10MillionSales; // 0,5
isAnySingleFromChinaWithMoreThan10MillionSales = singles.stream() // 0,5
.filter(s -> s.salesInMillions() > 10) // 0,5
.anyMatch(s -> s.artist().country().equals(Country.CHN)); // 1
return isAnySingleFromChinaWithMoreThan10MillionSales; // 0,5
} // 3,5
public List<Single> getAllSinglesFromEdSheeran() { // 0,5
List<Single> allSinglesFromEdSheeran; // 0,5
Artist sheeran = new Artist("Ed Sheeran", Country.GBR, LocalDate.of(1991, 2, 17), true); // 1
allSinglesFromEdSheeran = singles.stream() // 0,5
.filter(s -> s.artist().equals(sheeran)) // 0,5
.toList(); // 0,5
return allSinglesFromEdSheeran; // 0,5
} // 4
} // 18