studyklar
GdI 2 · Übungsblatt 9 · Aufgabe 2

Reisen prüfen: CO2 mit Function, Fernreise und Kurzflug mit Predicate

Ein Lambda ist eine Methode ohne Namen. Man kann es in einer Variablen speichern und später aufrufen, sogar an eine andere Methode weitergeben. Hier rechnet ein Lambda den CO2-Ausstoß einer Reise aus. Zwei weitere beantworten Ja-Nein-Fragen zur Reise. Rechts steht das Programm im Stand des aktuellen Teils, die Zeilen zum Schritt sind hervorgehoben. Mit Weiter geht es Schritt für Schritt voran.

Die Aufgabe

Aufgabe 2

Gegeben ist die Klasse Reise. Für die Art des Verkehrsmittels wird das Enum „Verkehrsmittel“ verwendet.

In der main-Methode der Klasse „FunktionenFuerReisen“ werden bereits einige Reise-Objekte angelegt.

a) Es soll der durch eine Reise entstehende CO2-Ausstoß mit Hilfe eines Lambdas berechnet werden.

Der typische CO2-Ausstoß in kg pro Personen-km ist

  • Bei einem Auto (mit 2 Personen): 0,1
  • Bei der Bahn: 0,03
  • Beim Flugzeug: 0,2

Schreiben Sie einen Lambda-Ausdruck, der das Interface „Function<T, R>“ implementiert. Überlegen Sie, welche Typen für T und R eingesetzt werden müssen. Speichern Sie das Lambda in einer Variablen und wenden Sie es auf jedes Reiseobjekt an. Das Ergebnis soll jeweils auf der Konsole ausgegeben werden.

b) Es sollen zwei Lambdas geschrieben werden, die das Interface „Predicate<T>“ implementieren. Überlegen Sie sich, welcher Typ für T eingesetzt werden muss.

  • Das eine Lambda soll überprüfen, ob es sich bei einer Reise um eine Fernreise handelt. Das ist der Fall, wenn die Distanz größer als 1000 km ist.
  • Das andere Lambda soll überprüfen, ob es sich um einen Kurzstreckenflug handelt. Das ist der Fall, wenn die Distanz kleiner als 1000 km und das Verkehrsmittel „Flugzeug“ ist.

Wenden Sie die beiden Lambdas auf die Reisen an und überprüfen Sie die Ergebnisse.

c) Schreiben Sie weiterhin eine Methode (eine gewöhnliche statische Methode, kein Lambda), die überprüfen soll, ob für die betreffende Reise eine Freigabe erforderlich ist. Je nach Dienstreisevorschrift können unterschiedliche Regeln zur Anwendung kommen. Die Methode hat als Parameter eine Reise und ein Predicate. Wenn die Anwendung des Predicate für die Reise „true“ ergibt, dann soll auf der Konsole ausgegeben werden, dass für die Reise eine Freigabe erforderlich ist. Ansonsten soll ausgegeben werden, dass keine Freigabe erforderlich ist. Testen Sie die Methode mit verschiedenen Reisen und den beiden in b) geschriebenen Lambdas.

Eine Reise hat eine Distanz in Kilometern und ein Verkehrsmittel. Daraus sollen drei Dinge entstehen: der CO2-Ausstoß, zwei Prüfungen und eine Methode, die je nach Prüfung eine Freigabe verlangt.

Die Klassen Reise und Verkehrsmittel und die Datei FunktionenFuerReisen mit den Reisen liegen uns nicht vor. Wir schreiben sie knapp selbst. Die vier Reisen sind die aus der Musterlösung: 1000 km mit dem PKW, 500 km mit der Bahn, 5000 km und 800 km mit dem Flugzeug.

Merke: Function<T, R> nimmt ein Lambda auf, das aus einem Wert vom Typ T ein Ergebnis vom Typ R macht. Ein Predicate<T> macht aus einem T immer true oder false.
  1. a) Ein Lambda vom Typ Function berechnet den CO2-Ausstoß jeder Reise.
  2. b) Zwei Lambdas vom Typ Predicate: Fernreise? Kurzstreckenflug?
  3. c) Eine Methode bekommt eine Reise und ein Predicate und meldet die Freigabe.

Die Vorgabe: Verkehrsmittel, Reise und vier Reisen

public enum Verkehrsmittel {    PKW, Bahn, Flugzeug}
public class Reise {     private int distanz;    private Verkehrsmittel verkehrsmittel;     public Reise(int distanz, Verkehrsmittel verkehrsmittel) {        this.distanz = distanz;        this.verkehrsmittel = verkehrsmittel;    }     public int getDistanz() {        return distanz;    }     public Verkehrsmittel getVerkehrsmittel() {        return verkehrsmittel;    }     @Override    public String toString() {        return distanz + " km " + verkehrsmittel;    }}
    public static void main(String[] args) {        Reise r1 = new Reise(1000, Verkehrsmittel.PKW);        Reise r2 = new Reise(500, Verkehrsmittel.Bahn);        Reise r3 = new Reise(5000, Verkehrsmittel.Flugzeug);        Reise r4 = new Reise(800, Verkehrsmittel.Flugzeug);        Reise[] reisen = {r1, r2, r3, r4};

Verkehrsmittel ist ein Enum, ein Typ mit genau festgelegten Werten: PKW, Bahn und Flugzeug. Eine Reise speichert die Distanz in km und ein Verkehrsmittel. Unser toString liefert einen kurzen Text wie „1000 km PKW“.

Aus Vorlesung 5, Folie 33 („Besser: Enum (Aufzählungstyp)“): Ein Enum zählt seine möglichen Werte auf. Man greift mit dem Enum-Namen darauf zu, etwa Verkehrsmittel.PKW.

In main legen wir die vier Reisen an und fassen sie in einem Array zusammen. So können wir später jedes Lambda in einer Schleife auf alle vier anwenden.

Aus Blatt 3, Aufgabe 1 („Ein Array mit den Vielfachen von 3 füllen“): Ein Array ist eine Reihe von Werten gleichen Typs. {r1, r2, r3, r4} legt es gleich mit vier Elementen an.

Welche Typen für T und R?

import java.util.function.Function;
        Function<Reise, Double> berechneCO2 = reise -> {
PlatzhalterBedeutunghier
TTyp des ParametersReise
RTyp des ErgebnissesDouble

Ein Lambda soll in einer Variablen stehen. Dafür braucht die Variable einen Typ. Function<T, R> passt für ein Lambda mit einem Parameter vom Typ T und einem Ergebnis vom Typ R.

Das Lambda bekommt eine Reise, also ist T gleich Reise. Es liefert eine Kommazahl, die kg CO2. Also ist R eine Kommazahl. In spitzen Klammern ist double aber nicht erlaubt, nur eine Klasse. Die Klasse zu double heißt Double.

Aus Vorlesung 11, Folie 12 („Anonyme Methoden (Lambdas)“): Function<T, R> nimmt ein Lambda mit einem Argument vom Typ T und einem Ergebnis vom Typ R auf. Ausgeführt wird es mit apply.
Aus Vorlesung 7, Folie 8 („Listen mit Zahlen“): Grundtypen wie int und double sind keine Klassen. In spitzen Klammern stehen deshalb ihre Wrapper-Klassen Integer und Double.
Noch 9 Schritte bis zum Ergebnis
Den ganzen Lösungsweg sehen Studierende und Lehrende der HS KL. Registriere dich mit deiner Adresse @stud.hs-kl.de oder @hs-kl.de, dann geht es hier direkt weiter.

FunktionenFuerReisen.java

Stand nach Teil a)

Abbildung 1FunktionenFuerReisen.java

Stand nach Teil a)

import java.util.function.Function; public class FunktionenFuerReisen {     public static void main(String[] args) {        Reise r1 = new Reise(1000, Verkehrsmittel.PKW);        Reise r2 = new Reise(500, Verkehrsmittel.Bahn);        Reise r3 = new Reise(5000, Verkehrsmittel.Flugzeug);        Reise r4 = new Reise(800, Verkehrsmittel.Flugzeug);        Reise[] reisen = {r1, r2, r3, r4};         Function<Reise, Double> berechneCO2 = reise -> {            double faktor = switch (reise.getVerkehrsmittel()) {                case PKW -> 0.1;                case Bahn -> 0.03;                case Flugzeug -> 0.2;            };            return reise.getDistanz() * faktor;        };         System.out.println("CO2-Ausstoß in kg pro Person:");        for (Reise reise : reisen) {            System.out.println(reise + ": " + berechneCO2.apply(reise));        }    }}
LegendeDas Programm nach Teil a).