Gibt es eine Möglichkeit zu vergleichen lambdas?

Sagen, ich habe eine Liste von Objekten definiert wurden lambda-Ausdrücke (closures). Gibt es eine Möglichkeit, diese zu überprüfen, so dass Sie verglichen werden kann?

Den code, ich bin am meisten interessiert, ist

    List<Strategy> strategies = getStrategies();
    Strategy a = (Strategy) this::a;
    if (strategies.contains(a)) { //...

Den vollständigen code

import java.util.Arrays;
import java.util.List;

public class ClosureEqualsMain {
    interface Strategy {
        void invoke(/*args*/);
        default boolean equals(Object o) { //doesn't compile
            return Closures.equals(this, o);
        }
    }

    public void a() { }
    public void b() { }
    public void c() { }

    public List<Strategy> getStrategies() {
        return Arrays.asList(this::a, this::b, this::c);
    }

    private void testStrategies() {
        List<Strategy> strategies = getStrategies();
        System.out.println(strategies);
        Strategy a = (Strategy) this::a;
        //prints false
        System.out.println("strategies.contains(this::a) is " + strategies.contains(a));
    }

    public static void main(String... ignored) {
        new ClosureEqualsMain().testStrategies();
    }

    enum Closures {;
        public static <Closure> boolean equals(Closure c1, Closure c2) {
            //This doesn't compare the contents 
            //like others immutables e.g. String
            return c1.equals(c2);
        }

        public static <Closure> int hashCode(Closure c) {
            return //a hashCode which can detect duplicates for a Set<Strategy>
        }

        public static <Closure> String asString(Closure c) {
            return //something better than Object.toString();
        }
    }    

    public String toString() {
        return "my-ClosureEqualsMain";
    }
}

Scheint es die einzige Lösung ist, definieren Sie die einzelnen lambda als ein Feld, und verwenden Sie nur diese Felder. Wenn Sie möchten, drucken Sie die Methode aufgerufen haben, sind Sie besser dran mit Method. Gibt es eine bessere Möglichkeit mit lambda-Ausdrücken?

Außerdem ist es möglich zu drucken, eine lambda und etwas lesbarer? Wenn Sie drucken this::a statt

ClosureEqualsMain$$Lambda$1/821270929@3f99bd52

etwas wie

ClosureEqualsMain.a()

oder sogar this.toString und die Methode.

my-ClosureEqualsMain.a();
Sie können festlegen, toString, equals und hashhCode Methoden in Schließung.
Können Sie ein Beispiel geben, das kompiliert?
Da toString definiert ist Object ich denke, definieren Sie eine Schnittstelle, die liefert eine default-Implementierung von toString ohne Verletzung der -Methode Voraussetzung für die Schnittstellen funktional sein. Ich habe nicht geprüft, obwohl dies.
Das ist falsch. Klassen Erben nicht ein Standard-Objekt deklarierten Methoden in Schnittstellen; siehe stackoverflow.com/questions/24016962/... für die Erklärung.
Danke für den Zeiger.

InformationsquelleAutor Peter Lawrey | 2014-06-07

Schreibe einen Kommentar