Postanowiłem się im przyjrzeć i mam mieszane uczucia ;-)
Lambdy nie są do końca tym czego się spodziewałem. Zakładałem, że będą bardzo podobne do tego co jest w JavaScript.... aż tak dobrze jednak nie będzie ;-)
Nie przypiszemy sobie (albo ja nie umiem) ciała metody do zmiennej i nie wywołamy później, o np. tak:
Mathod doSth = () -> { System.out.println("Toster"); };
doSth();
Runnable r = () -> { System.out.println("Toster"); };
r.run();
To zadziała.
Ciekawe jest to, że w ciele takiego lambodwej metody możemy używać wartości zmiennych (z zewnątrz), które są efektywnie finalne ;-)
Z klasami anonimowymi było tak:
final int i = 7; // i musi być finalne by móc go użyć dalej
new Thread(new Runnable() {
public void run() {
System.out.println(i);
}
}).run();
int i = 7;
new Thread(() -> { System.out.println(i); }).start();
pod warunkiem jednak, że i nigdzie dalej nie ulegnie zmianie ;-) nie może też ulec tej zmianie wcześniej ;-)
Faktem jest jednak, że taki kod jest krótszy i chyba jednak bardziej czytelny.
Lambdów można używać też kolekcjami i to jest naprawdę miłe.
Kiedyś (znaczy teraz też, od 2013 roku już nie będzie trzeba ;-)) by z listy wybrać tylko parzyste liczby trzeba było walnąć kod:
List<Integer> list = Arrays.asList(75,22,3,55,22,11,7,35);
List<Integer> result = new ArrayList<Integer>();
for (int num:list) {
if (num%2==0) result.add(num);
}
Teraz wystarczy:
List<Integer> list = Arrays.asList(75,22,3,55,22,11,7,35);
List<Integer> result = list.filter(e -> e%2==0).into(new ArrayList<Integer>());
List<Integer> list = Arrays.asList(75,22,3,55,22,11,7,35).filter(e -> e%2==0).into(new ArrayList<Integer>());
Co trzeba przyznać wygląda na krótsze ;-) i chyba czytelniejsze.
W Java 8 ma pojawić się też możliwość definiowania domyślnej implementacji kodu dla interfejsów....
W swoim życiu spotkałem się chyba z 1 sytuacją gdy to byłoby potrzebne, bez tego musieliśmy mieć w interfejsie klasę Adaptera do tego i jej używaliśmy tam gdzie to implementowaliśmy......
To taka furtka do wielodziedziczenia jest.
Wygląda to tak:
public interface I1 {
void doSth() default {
System.out.println("from I1");
}
}
Jeśli napiszemy własną to tamta zniknie (można się do niej dostać chyba przez I1.super()).
Zabawniej się robi jak są 2 interfejsy z tą samą metodą i domyślnymi implementacjami :-)
public interface I1 {
void doSth() default {
System.out.println("from I1");
}
}
public interface I2 {
void doSth() default {
System.out.println("from I2");
}
}
public class Test implements I1, I2 {
}
public class Test implements I1, I2 {
public void doSth() {
System.out.println("from Test");
}
}
Ogólnie przydatne mogą być lambdy w operacjach na kolekcjach. Do składni się trzeba przyzwyczaić, ale później pozwalają dużo czasu na pisaniu zaoszczędzić.... inna sprawa, że nie jestem pewien jak później się przekładają na maintanance ;-)
Ogólnie mam mieszane uczucia, ale bardzo możliwe, że przemawia przeze mnie konserwatyzm ;-)
Podobne postybeta
Ile to jest 1+1 w Java'ie?
Który kod (nie kot! ;-)) lepszy?
Sztuczki tropiciela błędów, part 4
Nie lubię Sparka ;-)
Sztuczki tropiciela błędów, part 3 - hackujemy klasy finalne ;-)