List<String> names = Arrays.asList("Jamie", "Cersei", "Tyrion", "Littlefinger");
// old style
Collections.sort(names, new Comparator<String>() {
@Override
public int compare (String a, String b) {
return a.compareTo(b);
}
});
// comparator as lambda expression
Collections.sort(names, (String a, String b) -> {return a.compareTo(b);});
// shorter without parenthesis and return statement
Collections.sort(names, (String a, String b) -> a.compareTo(b));
// even shorter without parameter types
Collections.sort(names, (a, b) -> a.compareTo(b)); // type inference
final String prefix = "pre"; // can user final vars
String postfix = "post"; // lambdas can use non-final vars
name = "Tywin Lannister"; // lambdas can use instance and class vars
Callable<String> job = () -> prefix + name + postfix;
String concatName = job.call();
// only 1 abstract method ==> compile error if more
@FunctionalInterface
public interface Callable<T> {
public T call();
}
// implementation of functional interface
Predicate<Integer> isOdd = i -> i % 2 == 1;
// call
isOdd.test(5); // true
// create new predicates from predicates
Predicate<Integer> isEven = isOdd.negate();
isEven(5); // false
// new function
Function<Integer,Integer> square = i -> i * i;
square.apply(8); // 64
// other functional interfaces
// Callable.call(), Comparator.compare(), Runnable.run()
// Consumer.accept(), Supplier.get()
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
List<Integer> squaresOfEvenElements =
numbers.stream() // create stream from collection
.filter(p -> isEven(p))
.map(i -> i * i) // intermediate function
.collect(Collectors.toList()); // terminal function
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
public void findSumOfOddSquares() {
Predicate<Integer> isOdd = i -> i % 2 == 1;
Function<Integer,Integer> square = i -> i * i;
Integer sumOfOddSquares =
numbers.stream()
.map(square::apply)
.filter(isOdd::test) // method reference
.reduce(0, (x, y) -> x + y); // terminal function
}
public <T, R> R mapFilterAndReduce
(List<T> elements, Function<T, R> function,
Predicate<R> checker, BinaryOperator<R> accumulator,
R initial)
{
R result = elements.stream()
.map(function::apply)
.filter(checker::test)
.reduce(initial, accumulator);
return result;
}
Integer sumOfOddSquares = mapFilterAndReduce(numbers, i -> i * i, isOdd, (x, y) -> x + y, 0);
int max = 1000000 // one million
List<String> values = = new ArrayList<>(max);
// fill values with strings....
// sequential processing
long count = values.stream().sorted().count();
// parallel processing
long count = values.parallelStream().sorted().count();
public Optional<Integer> calculate(Integer x) {
Optional<Integer> result = Optional.of(x);
return result;
}
Optional<Integer> result = calculate(5);
// avoid null pointer
result.ifPresent(System.out::println);
// add new functionality to existing interfaces without breaking code
// Comparator interface has new methods, e.g. "reversed()"
public interface MyInterface {
// default method
default long sum(long a, long b) {
return a + b;
}
// default static method
// avoid util classes
static int square(int x) {
return x * x;
}
public long multiply(long x, long y);
}
// lambda return a lambda
Function<Integer, Function<Integer, Integer>> multiplier = a -> b -> a * b;
Function<Integer, Integer> times100 = multiplier.apply(100);
// b -> 100 * b
Integer result = times100.apply(3); // 300
/