Java Lambda Ausdruck in äquivalente Definition einer anonymen Klasse

sasbro97

Lt. Junior Grade
Registriert
Nov. 2014
Beiträge
417
Wie im Titel beschrieben muss ich einen Lambda Ausdruck in eine anonyme Klasse überführen.

Der Lambda Ausdruck lautet:
Java:
IOperation operation = (a,b) -> System.out.println (a*b);

Als Lösung dachte ich an:
Java:
IOperation operation = new IOperation(); {
    public int operation (int a, int b) {
        System.out.println (a*b);
    }
};

Ich kann das aber leider nicht überprüfen, da ich irgendwie zu doof bin, dass in eine ausführbare Klasse zu packen. Ich weiß leider wirklich überhaupt nicht wie das funktioniert, gerade wegen dem System.out.println
 
Java:
BiFunction<Integer, Integer, Integer> bi = (x, y) -> { return x * y; };
System.out.println(bi.apply(2, 2));
 
Ehm, das mit dem apply ist mir gänzlich neu. Ich zeige mal nur kurz, was im Skript steht:
 

Anhänge

  • Unbenannt.PNG
    Unbenannt.PNG
    10 KB · Aufrufe: 430
Mir fehlt da etwas der Kontext. Aber zu deinem Code:
- Die Methode operation(...) ist falsch, da diese nichts zurück liefert.
- IOperations habe ich auch nicht mit google gefunden (nur etwas mit Eclipse Plugin)?
Meine Annahme ist, dass es im Grunde um das Thema geht, was ich gepostet habe. Sonst bitte ich um etwas mehr Kontext.
 
@baizon
Ich hab genau so wenig Kontext wie du. Eben nur das gegeben. Glaube der Prof nennt nur die Klassen so.
Hier noch mehr Beispiele, aber das war es auch. Ich bekomm es nur mit dem print nicht hin. Den Rest kann man wohl so machen.
 

Anhänge

  • Unbenannt.PNG
    Unbenannt.PNG
    42,1 KB · Aufrufe: 408
Also, dann bringen wir mal etwas Licht ins Dunkle.

Es gab einmal eine Zeit vor Java 8 und damit der Einführung von Lamba-Ausdrücken.

Als man damals eine "Funktionalität" als Parameter übergeben wollte, so hat man dies als Implementierung eines Interfaces gemacht.

Das wohl beste Beispiel ist das Runnable Interface. Es besitzt nur eine einzige Methode, die wie folgt aussieht:
Java:
public interface Runnable {
    public abstract void run();
}

Wenn man ein neues Thread Object erzeugen wollte, musste man eine Implementierung des Runnable Interfaces mitgeben. Das sah dann so aus:
Java:
Runnable r = new Runnable() {

    public void run() {
        System.out.println("Hello World!");
    }
};

new Thread(r).start();

Das ist ziemlich viel Code. Daher hat man in Java 8 etwas eingebaut, was sich Funktionale Interfaces nennt. Dies sind Interfaces, die genau nur eine einzige Funktion definieren. Runnable ist zum Beispiel so ein Interface.

Das Tolle an Funktionalen Interfaces ist nun, dass man eigentlich weiß, welche Funktion darin aufgerufen werden soll, denn es gibt ja nur eine! Damit kann man nun Lamba Ausdrücke schreiben anstatt das ganze Interface zu implementieren.

Folgender Code definiert auch ein Runnable, allerdings mit einem Lamba Ausdruck.
Java:
Runnable r = () -> {
    System.out.println("Hello World!");
};

Es geht aber noch kürzer:
Java:
new Thread(() -> {
    System.out.println("Hello World!");
}).start();

Nehmen wir nun mal deine IOperations. Das Interface hat nur eine Methode, die zwei Integer als Parameter erwartet und einen Integer zurückgibt. Das kann wieder sehr einfach mit einem Lamba Ausdruck geschrieben werden:
Java:
IOperation addition = (int a, int b) -> {
    return a + b;
}
 
Jetzt habe ich den Kontext nun auch verstanden. Hier nun bitte ein lauffähiges Beispiel:
Java:
public interface IOperation {
    int operation(int x, int y);
}

Java:
public class Test01 {
    public static void main(String[] args) {
        IOperation mod = (x,y) -> x+y;
        System.out.println(mod.operation(2, 2));
        IOperation pow = (x,y) -> {int z=1; while(y-->0) z*=x; return z;};
        System.out.println(pow.operation(1, 2));
    }
}
 
Ich danke euch beiden vielmals. Dass es erst mit Java 8 eingeführt wurde steht auch in den Unterlagen, aber den genauen Sinn, bis auf eine Vereinfachung, habe ich nie verstanden.
Habe nun auch dank @baizon ein lauffähiges Beispiel erstellt.

Nun aber zu der ursprünglichen Frage. Gibt es das überhaupt dann als gegebenen Lambda-Ausdruck:
IOperation operation = (a,b) -> System.out.println (a*b);

und war meine oben definierte Umwandlung in eine anonyme Klasse davon richtig?

Mein lauffähiges Beispiel sieht jetzt so aus:
Java:
public class IOperation {

    
     interface MathOperation {
          int operation(int a, int b);
     }
    
     public static void main(String[] args) {
        
         MathOperation addition = (int a, int b) -> a + b;
         MathOperation multiTest = (a,b) -> a * b;
         System.out.println(addition.operation(2, 2));
         System.out.println(multiTest.operation(6, 2));
     }

}
 
Ja, mit einem Consumer...
Java:
public interface IOperation<T> {
    void print(T t);
}
Java:
public class Test02 {

    public static void main(String[] args) {
        IOperation<String> printer = (x) -> System.out.println(x);
        printer.print("abc");
    }
}
 
Also mit Generics? Aber glaube nicht, dass das so geht oder so sein soll, da das eine 3 Pkt Klausuraufgabe war und deshalb glaube ich schon zu aufwendig, dafür dass wir eigentlich nichts über das Thema erfahren haben, wie du vielleicht schon bemerkt hast. Ich glaube ich muss da echt mal nachhaken beim Lehrstuhl. Sehr komisch.
 
sasbro97 schrieb:
Also mit Generics?

Nein. Dein erster Lösungsversuch war schon fast richtig. Lediglich den Return Typen musst Du ändern und den Syntaxfehler beheben.

Das Interface "IOperation" ist nicht vorgegeben?
 
@Rossie
Das Problem hierbei ist, dass ich ja keine Klassenstrukturen oder sonst etwas vorgegeben habe, sondern nur wandeln sie diesen Lambda Ausdruck um.

Also wär es dann laut dir eigentlich:

Java:
IOperation operation = new IOperation(); {
    public void operation (int a, int b) {
        System.out.println (a*b);
    }
};

Bin da echt am überlegen, weil ich das auch mit Eclipse nicht ausführbar bekomme, weil wir echt überhaupt keine Beispiele dazu haben und auch nichts dazu gemacht haben.
 
Rossie schrieb:
Den Syntaxfehler musst Du schon beheben...
Welchen Syntaxfehler denn? Ich weiß gar nicht was du meinst leider.
 
Den Syntaxfehler in Deinem Code:

Java:
IOperation operation = new IOperation(); {
    public void operation (int a, int b) {
        System.out.println (a*b);
    }
};

Eclipse zeigt Dir doch wohl Fehler an?
 
Irgendwie schon, aber daraus werde ich nicht schlau. Ich bin mir nichtmal sicher, ob die anonyme Klasse in die Main-Methode muss oder sonst wo.
 
Um die Fehlermeldungen richtig zu deuten, muss man sich schon etwas auskennen. Das ist in dem Fall in der Tat irreführend.

Aber Du könntest es Dir auch einfach machen und die Eclipse Template-Funktion nutzen. Damit kann man ganz einfach die anonyme Klasse erstellen. Gib "new IOp" ein und drücke Strg+Enter...

Erstellen kannst Du den Ausdruck mit der anonymen Klasse, wo Du möchtest. Entweder direkt in der Klasse oder in einer Methode.
 
@Rossie
Bekomme keine Templates vorgeschlagen, wenn ich new IOperation oder so versuche. Ich zeig dir mal wie meine Klasse aktuell aussieht:

Java:
public class IOperation {

    
    interface MathOperation {
          int operation(int a, int b);
    }
    
    
     public static void main(String[] args) {
        
         MathOperation addition = (int a, int b) -> a + b;
         MathOperation multiTest = (a,b) -> a * b;
         System.out.println(addition.operation(2, 2));
         System.out.println(multiTest.operation(6, 2));
        
        
     }

    
}
 
Interfaces fangen (per Konvention) oft mit einem "I" an. Deswegen bin ich davon ausgegangen, dass dies auch bei Dir so ist. Wenn das Interface "MathOperation" heißt, müsstet Du natürlich dafür die anonyme Klasse erstellen....
 
So hab ich nun zwar keine Fehler, aber das war es auch. Ist bestimmt auch nicht das Richtige. Von MathOperation kann ich gar nichts erstellen.

Ich weiß nun gar nicht wie ich das aufrufen kann.
Java:
public class IOperation {

   
    interface MathOperation {
          int operation(int a, int b);
    }
   
    IOperation anonym = new IOperation() {
        public int operation(int a, int b) {
            return a+b;
        }
    };
   
     public static void main(String[] args) {
       
         MathOperation addition = (int a, int b) -> a + b;
         MathOperation multiTest = (a,b) -> a * b;
         System.out.println(addition.operation(2, 2));
         System.out.println(multiTest.operation(6, 2));
       
     }
}
 
Zurück
Oben