Predicate Java 8 - jak to działa

0
interface Secret {
    String magic(double d);
}

class MySecret implements Secret {


    public static void main(String[] args) {

    }

    @Override
    public String magic(double d) {
        return "tekst";
    }
}

Czy można to zamienić na lambdę? Jak powinno to wyglądać?

1
interface Secret {
    String magic(double d);
}
 
class MySecret {
 
 
    public static void main(String[] args) {
        Secret s = d -> "tekst";
    }
 }
0

No można ale tylko jeśli nie pchasz tam jakiegoś maina.


interface Secret {
    String magic(double d);
}

class Worker{
    public void method(Secret s){
        System.out.println(s.magic(1.0));
    }
}

class Test {
    public static void main(String[] args) {
        Worker worker = new Worker();
        worker.method(d -> String.valueOf(d)+"cośtam"); //lambda zamiast anonimowego Secreta
    }
}
0

@Shalom dlaczego jeśli nie pcham maina?

To co wysłał użytkownik nad Tobą. Kompiluje się.

Zastanawiam się tylko dlaczego tę lambdę mógł przypisać do "Secret", a nie Predicate<String> (czy coś podobnego).

W zasadzie tak jak w Twoim kodzie (zmodyfikowałem lekko):

interface Secret {
    String magic(double d);
}

class Worker{
    public void method(Secret s){
        System.out.println(s.magic(1.0));
    }
}

class MySecret {
    public static void main(String[] args) {
        Worker worker = new Worker();
        Secret secret = d -> String.valueOf(d) + " cośtam";
        worker.method(secret); //lambda zamiast anonimowego Secreta
    }
}

A w takim przypadku przypisuje do Predykatu. To nie jest tak, że lambda jest jakby tym predykatem?

        List<String> list = new ArrayList<>();
        Predicate<String> stringPredicate = a -> a.isEmpty();

        list.removeIf(stringPredicate);
0

Predicate to interfejs. Mozesz go zaimplementowac pisząc lambdę. Na wejściu dostaje jakiś typ i zwraca boolean.
Secret to interfejs. Mozesz go zaimplementowac pisząc lambdę. Na wejściu dostaje double i zwraca String.

Tak poprzez analogię.

0

Nie bardzo rozumiem o co ty pytasz. Przecież Predicate to jest konkretny interfejs, taki jak ten twój Secret. One nie maja ze sobą nic wspólnego wiec to oczywiste że jednego do drugiego nie przypiszesz. Ale jednocześnie oba mają tylko jedną metodę więc zarówno jeden jak i drugi może być przez javę automatycznie zwinięty do lambdy bazujac na podstawie typu zwracanego.
To:

Predicate<String> stringPredicate = a -> a.isEmpty();

jest tylko skróconym zapisem tego:

        Predicate<String> stringPredicate = new Predicate<String>() {
            @Override
            public boolean test(String a) {
                return a.isEmpty();
            }
        };
0

Ok. Ma to sens.

A czemu działa to bez @FunctionalInterface? Kiedy to jest wymagane?

0

Wymagane? Nigdy. Niemniej jest wygodne, żeby kompilator automatycznie sprawdzał czy twój interfejs spełnia pewne warunki do bycia poprawnym interfejsem dla lambd. Chroni to przed przypadkowym refaktoringiem który mógłby coś popsuć.

0

Ok. Właśnie przetestowałem to. Jak dopisuję drugą metodę do inerfejsu z adnotacją to podkreśla mi, że jest ich za dużo ;)

Kurde. Wydaje się, że ma to potężną moc. Muszę zacząć kodzić coś na boku z java 8.

1 użytkowników online, w tym zalogowanych: 0, gości: 1