Upload
tomasz-kowalczewski
View
951
Download
0
Embed Size (px)
DESCRIPTION
Java 8 jest tuż za rogiem czyli programowanie funkcyjne na żywo i w przykładach
Citation preview
Java 8 jest tuż za rogiem
czyli programowanie funkcyjne na żywo i w przykładach
Co jest złego w klasach anonimowych?
List<Person> list = ...
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
});
Spróbujmy tak...
Collections.sort(list, (Person p1, Person p2) ->
p1.getName().compareTo(p2.getName())
);
... albo tak
Collections.sort(list, (p1, p2) ->
p1.getName().compareTo(p2.getName())
);
Składnia
(int i) -> { System.out.println(i+1); }
(String s, int offset) -> {
return s.charAt(offset); }
<T> (T i) -> { }
i -> { System.out.println(i+1); }
(s, offset) -> s.charAt(offset);
() -> {}
To się nie skompiluje
(final x) -> {}
(int x, y) -> 3.14
() -> { 3.14; }
i, j -> i*j // bo nie wiadomo co to: foo(i, j -> i *j)
-> "foo"
list.sort(_.getSize()); // No placeholder syntax (wunderbars)
Kontekst• Przypisania
IntConsumer c = i -> { System.out.println(i); };
• Wywołania:
SwingUtilities.invokeLater(() -> button.setEnabled(false));
• Rzutowania:
Object o = (Callable<Integer>) () -> 42;
• Zwracania:
public static <T> Function<T, T> identity() {
return t -> t;
}
Kod jako obiekty
interface Runnable { void run(); }
interface Callable<T> { T call(); }
interface ActionListener {
void actionPerformed(ActionEvent a);
}
interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
Odwołania do zmiennych z poza zakresu...
int getAdultCount(List<Person> people, int threshold) {
return Collections.filter(people, p -> p.getAge() > threshold).size();
}
void registerNotifier(JButton button, JLabel label) {
button.addActionListener(e -> label.setText("Ok"));
}
Zmiennie lokalne, które nie są zmieniane otrzmują modyfikator final.
... mogą myć niebezpieczne
int accumulatedExperience = 0;
people.forEach(p -> {
accumulatedExperience += p.getEmploymentYears();
});
błąd kompilacji
... mogą myć niebezpieczne
/* final */ int[] accumulatedExperience = { 0 };
people.forEach(p -> {
accumulatedExperience[0] += p.getEmploymentYears();
});
Nie próbujcie tego w domu
(ani na produkcji)
... mogą myć niebezpieczne
/* final */ AtomicInteger accumulatedExperience = new AtomicInteger();
people.forEach(p -> { accumulatedExperience.addAndGet(p.getEmploymentYears());
});
Działa! Ale lepiej tak:
people.stream().map(Person::getEmploymentYears).reduce(0, Integer::sum)
Referencje do metod
class Math {
public static int max(int a, int b) { ... }
}
interface Operator<T> {
T eval(T left, T right);
}
Operator<Integer> lambda = (a, b) -> Math.max(a, b);
Operator<Integer> methodRef = Math::max;
...statycznych
class Reducer {
public <T> static reduce(T base, BinaryOperator<T> op, T... items) {
for(T item : items) {
base = op.apply(base, item);
}
}
}
// result is 9
Reducer.reduce(0, Math::max, 1, 6, 9, 8);
// result is 24
Reducer.reduce(0, Integer::sum, 1, 6, 9, 8);
...istancji i konstruktorów
interface Function {
U apply(T t);
}
Function<String, Integer> getLength = s -> s.length;
Function<String, Integer> getLength = String::length;
getLength.apply("4Developers") == 11
Function<Integer, int[]> factory = int[]::new;
Supplier<ArrayList<Person>> supplier = ArrayList<Person>::new;
Strumienie
• Ewolucja kolekcji
• Dostarczają operacje do grupowego (bulk) przetwarzania elementów kolekcji
• Jednorazowego użytku – elementy są niedostępne po ich odczytaniu
• Łatwe przejście w tryb przetwarzania wielowątkowego
• Wspierają funkcjonalny styl programowania
• Idee zadoptowane w pozostałych częściach JDK