函数式接口:有且只有一个抽象方法的接口。用来表示Lambda表达式的类型。
函数作为一等公民
- 可以被定义
- 可以作为参数
- 可以作为返回值
Java8新增了注解@FunctionalInterface,用于标识一个接口为函数式接口。
接口新特性
- 接口支持默认方法
支持default关键字
1 @FunctionalInterface 2 public interface Consumer<T> { 3 4 void accept(T t); 5 6 default Consumer<T> andThen(Consumer<? super T> after) { 7 Objects.requireNonNull(after); 8 return (T t) -> { accept(t); after.accept(t); }; 9 } 10 }
- 接口支持静态方法
支持static修饰方法体
1 @FunctionalInterface 2 public interface UnaryOperator<T> extends Function<T, T> { 3 4 static <T> UnaryOperator<T> identity() { 5 return t -> t; 6 } 7 }
Lambda表达式语法:
- 参数
- 箭头符号
- 主体
Lambda表达式形式
Runnable noArguments = () -> System.out.println("Hello World"); | 无参数,无返回值。 |
ActionListener oneArgument = event -> System.out.println("button clicked"); |
有参数,无返回值。只有一个参数可以省略参数括号 |
Runnable multiStatement = () -> { System.out.println("Hello"); System.out.println(" World"); } |
无参数,无返回值。有多个表达式语句,用大括号括起来。 |
BinaryOperator<Long> add = (x, y) -> x +y; |
多个参数,有返回值。参数无显式类型。 |
BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y; |
参数显式声明。 |
Java8新增函数式接口
接口 | 参数 | 返回类型 |
Predicate<T> | T | boolean |
Consumer<T> | T | void |
Function<T, R> | T | R |
Supplier<T> | None | T |
UnaryOperator<T> | T | T |
BinaryOperator<T> | (T, T) | T |
其他内置函数式接口
接口 | 参数 | 返回类型 |
Runnable | None | void |
Callable<V> | None | V |
Comparator<T> | T | int |
FileFilter | File | boolean |
Comparable<T> | T | int |
数据和行为分离
复合Lambda表达式
- 比较器复合
逆序
1 Comparator.comparing(String::length).reversed();
比较器链
1 Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder());
- 谓词复合
包含三个方法:negate、and、or。
1 Predicate<Person> isMale = Person::isMale; 2 3 Predicate<Person> notMale = isMale.negate(); 4 Predicate<Person> isMaleAndIsChildren = isMale.and(Person::isChildren); 5 Predicate<Person> isMaleOrIsChildren = isMale.or(Person::isChildren);
- 函数复合
andThen、compose
1 UnaryOperator<Integer> u1 = x -> x + 1; 2 UnaryOperator<Integer> u2 = x -> x * 2; 3 4 // 先执行u1,再执行u2 5 Function<Integer, Integer> f1 = u1.andThen(u2); 6 // 先执行u2,再执行u1 7 Function<Integer, Integer> f2 = u1.compose(u2); 8 9 f1.apply(1); // (1 + 1) * 2 = 4 10 11 f2.apply(1); // (1 * 2) + 1 = 3