Ereignisse analysieren
Wir nehmen an, dass unser Smart Home viele Ereignisse gesammelt hat. Nun wollen wir diese analysieren und etwas über unser Verhalten herausfinden – oder Daten für ein Dashboard abgreifen.
Zur Verwaltung der Ereignisse benutzen wir die lineare Datenstruktur des Arrays.
Der Ausgangspunkt
Im Übungsbereich liegt das Projekt vollständig: die Klasse Event mit ihren drei Spezialisierungen und die Klasse SmartHome mit 23 Beispielereignissen aus einem Tag.
Die vier Methoden von SmartHome sind noch leer – die füllst du in den Aufgaben.
Du kannst hier im Browser arbeiten oder dir das Projekt herunterladen und in deinem eigenen Editor öffnen – du brauchst dafür ein JDK 25. Der Quelltext ist in beiden Fällen derselbe: Die Dateien unten werden beim Bauen des Buches aus dem Archiv gelesen.
Projekt: EreignisseAufgaben
Aufgabe 1: Den Verlauf ausgeben
Fülle die Methode showBacklog(). Sie soll alle Ereignisse ausgeben, eines je Zeile:
1. 0, 2026-03-17T01:00, wohnzimmer.sensor1
2. 1, 2026-03-17T02:00, wohnzimmer.sensor1
3. 2, 2026-03-17T03:00, wohnzimmer.sensor1
Achte darauf, dass das Array 100 Plätze hat, aber nur 23 davon belegt sind.
Tipp 1: Wie komme ich an die Werte?
Die Attribute von Event sind private. Von außen kommst du über die Anfragen heran:
eventBacklog[i].getId()
eventBacklog[i].getTimeFired()
eventBacklog[i].getContext()
Tipp 2: Was ist mit den leeren Plätzen?
Ein Array von Objekten ist nach new Event[100] mit null gefüllt – dort liegt kein Objekt. Ein Aufruf wie eventBacklog[50].getId() bricht deshalb ab.
Brich die Schleife ab oder überspringe die leeren Plätze:
for (int i = 0; i < eventBacklog.length; i++) {
if (eventBacklog[i] == null) {
break;
}
// ...
}
Aufgabe 2: Nur die Lampen
Fülle showLights(). Ausgegeben werden sollen nur die Zustandsänderungen, mit Kontext und neuem Zustand:
wohnzimmer.lampe1, off
wohnzimmer.lampe2, off
Das Array enthält aber alle Ereignisarten. Wie erkennst du die richtigen?
Tipp: Woran erkenne ich den Typ?
Mit instanceof fragst du, ob ein Objekt von einer bestimmten Klasse ist:
if (eventBacklog[i] instanceof StateChangedEvent) {
// ...
}
Danach brauchst du noch eine Typumwandlung, denn getNewState() gibt es nur bei der Spezialisierung:
StateChangedEvent e = (StateChangedEvent) eventBacklog[i];
Aufgabe 3: Die höchste Temperatur
Fülle getMaxTemperature(). Zurückgegeben werden soll die höchste neue Temperatur, die in einem TemperatureChangedEvent vorkommt.
a) Welchen Startwert nimmst du – und warum ist 0 hier eine schlechte Wahl?
b) Schreib die Methode.
c) Prüf dein Ergebnis: In den Beispieldaten sollte 21.2 herauskommen.
Tipp zum Startwert
Ein Startwert von 0 behauptet stillschweigend: „Keine Temperatur ist kleiner als 0." Im Winter im Garten stimmt das nicht.
Sicher ist der erste passende Wert aus den Daten – oder ein Startwert, der garantiert kleiner ist als alles, was vorkommen kann.
Aufgabe 4: Automationen zählen
Fülle countAutomationTriggered(). Zurückgegeben wird, wie viele AutomationTriggeredEvent im Verlauf stehen.
In den Beispieldaten sind es null – das ist kein Fehler, sondern die Vorlage für die nächste Seite.
Aufgabe 5: Neue Ereignisse annehmen
Fülle receiveEvent(Event pEvent). Das neue Ereignis kommt an die erste freie Stelle.
Ist kein Platz mehr frei, rückt alles um eins nach vorn: Das älteste Ereignis fällt heraus, und das neue kommt ans Ende.
a) Schreib die Methode.
b) Was passiert mit dem ältesten Ereignis? Kann man es zurückholen?
c) Diese Datenstruktur hat einen Namen. Welchen?
Tipp: Das Nachrücken
Beim Nachrücken läufst du von vorne nach hinten und ziehst jedes Element einen Platz nach vorn:
for (int i = 0; i < eventBacklog.length - 1; i++) {
eventBacklog[i] = eventBacklog[i + 1];
}
Danach ist der letzte Platz doppelt belegt – dort kommt das neue Ereignis hin.
Und wenn es schiefgeht
Zwei Fehlermeldungen wirst du hier fast sicher sehen:
| Meldung | Bedeutung |
|---|---|
NullPointerException |
Du hast auf einem leeren Platz eine Methode aufgerufen. Prüfe auf null, bevor du zugreifst. |
ClassCastException |
Du hast ein Ereignis in eine Klasse umgewandelt, zu der es nicht gehört. Frag vorher mit instanceof. |
Beide kommen erst beim Ausführen – der Übersetzer kann sie nicht finden.