lambda
函数式接口
函数式接口是只定义了一个方法的接口,可以被lambda 匿名函数表达: 函数式接口的抽象方法签名被称为函数描述符
public interface Comparator<T> { ←---- java.util.Comparatorint compare(T o1, T o2);}public interface Runnable { ←---- java.lang.Runnablevoid run();}public interface ActionListener extends EventListener { ←---- java.awt.event.ActionListenervoid actionPerformed(ActionEvent e);}public interface Callable<V> { ←---- java.util.concurrent.CallableV call() throws Exception;}public interface PrivilegedAction<T> { ←---- java.security.PrivilegedActionT run();}
@FunctionalInterface
这个标注用于表示该接口会设计成一个函数式接口,因此对文档来说非常有用。此外,如果你用 @FunctionalInterface 定义了一个接口,而它不是函数式接口的话,编译器将返回一个提示原因的错误。例如,错误消息可能是 “Multiple non-overriding abstract methods found in interface Foo”,表明存在多个抽象方法。请注意,@FunctionalInterface 不是必需的,但对于为此设计的接口而言,使用它是比较好的做法。它就像是 @Override 标注表示方法被重写了。
函数式接口类型
predicate
java.util.function.Predicate
@FunctionalInterfacepublic interface Predicate<T> {boolean test(T t);}public <T> List<T> filter(List<T> list, Predicate<T> p) {List<T> results = new ArrayList<>();for(T t: list) {if(p.test(t)) {results.add(t);}}return results;}Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);
Consumer
java.util.function.Consumer
@FunctionalInterfacepublic interface Consumer<T>{void accept(T t);}public <T> void forEach(List<T> list, Consumer<T> c){for(T i: list){c.accept(i);}}forEach(Arrays.asList(1,2,3,4,5),(Integer i) -> System.out.println(i) ←---- Lambda 是Consumer中accept方法的实现);
Function
java.util.function.Function
@FunctionalInterfacepublic interface Function<T, R> {R apply(T t);}public <T, R> List<R> map(List<T> list, Function<T, R> f) {List<R> result = new ArrayList<>();for(T t: list) {result.add(f.apply(t));}return result;}// [7, 2, 6]List<Integer> l = map(Arrays.asList(" Lambda s", "in", "action"),(String s) -> s.length() ←---- Lambda 是Function接口的apply方法的实现);
注: Java 类型要么是引用类型(比如 Byte、Integer、Object、 List ),要么是基本类型(比如 int 、double、byte、char)。但是泛型(比如 Consumer
常用的函数式接口
类型检查
java 会自动检查lambda 的上下文从而判断lambda 应该继承哪一个函数式接口
类型判断
Comparator<Apple> c =(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()); ←---- 没有类型推断Comparator<Apple> c =(a1, a2) -> a1.getWeight().compareTo(a2.getWeight()); ←---- 有类型推断

