Java8 新特性之函数式编程
一、函数接口
函数接口 @FunctionalInterface 是只有一个抽象方法的接口,用作Lambda表达式的类型。
特点
- 接口有且仅有一个抽象方法
- 允许定义静态方法
- 允许定义默认方法
- 允许java.lang.Object中的public方法
- 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错
Java8中常用函数接口
java 8中已经为我们定义了很多常用的函数式接口它们都放在java.util.function包下面,一般有以下常用的四大核心接口:
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer(消费型接口) | T | void | 对类型为T的对象应用操作。void accept(T t) |
Supplier(供给型接口) | 无 | T | 返回类型为T的对象。 T get(); |
Function<T, R>(函数型接口) | T | R | 对类型为T的对象应用操作并返回R类型的对象。R apply(T t); |
Predicate(断言型接口) | T | boolean | 确定类型为T的对象是否满足约束。boolean test(T t); |
二、Lambda表达式
表达式语法
java 8 中Lambda 表达式由三个部分组成:
第一部分为一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数:(int a, int b)
第二部分为一个箭头符号: ->
第三部分为方法体,可以是表达式和代码块(如果存在多行代码 需要使用{}包裹)
String[] arr = {"zs", "23333", "haha", "a", "996ICU", "Saber"};
Arrays.sort(arr, (String a, String b) -> Integer.compare(a.length(), b.length()));
参数类型可以推断
如果参数的类型可以根据上下文推断出来,则可以省略掉类型。
在上面的代码中,参数 a与 参数 b 可以推测出来是String类型,所以可以省略。这样会让代码变得更加简洁,也更符合一个lambda表达式。
Arrays.sort(arr, (a, b) -> Integer.compare(a.length(), b.length()));
存在多行代码
如果存在多行代码 需要使用{}包裹,若只有一行则可省略。
Arrays.sort(arr, (a, b) -> {
if (a.length() < b.length())
return 0;
else
return -1;
});
单个参数
单个参数可以省略括号()
Stream.of(1,2,3,4).forEach(e-> System.out.println(e));
没有参数
当一个参数都没有的时候,仍然可以使用lambda表达式,需要一个()
() -> System.out.println("无参数的表达") ;
方法引用
我们可以通过方法引用来简化Lambda表达式
lambda写法:
person -> person.getName;
方法引用:
Person :: getName;
语法结构为
引用类型 | 引用示例 |
---|---|
构造方法 | $ClassName::new |
实例方法 | i n s t a n c e : : instance:: instance::methodName |
类任意对象实例 | C l a s s N a m e : : ClassName:: ClassName::methodName |
类静态方法 | C l a s s N a m e : : ClassName:: ClassName::staticMethodName |
需要注意的是:必须给出一个无参构造函数才能使用‘构造引用’
Person :: new