Java8 新特性 - 函数式接口

Posted by Vito on October 31, 2017

函数式接口

  • 函数式接口(Functional Interface)就是有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
  • Java 8中允许接口实现方法, 而不是简单的声明, 这些方法叫做默认方法,使用特殊的关键字 default 。
  • 默认方法不是抽象方法,不影响我们判断一个接口是否是函数式接口。
  • Java8 之前已经存在一些只有一个抽象方法的接口,如:Runnable 。
  • Java8 新增的函数式接口位于 java.util.function 包中。
  • 通常在接口定义上使用 @FunctionalInterface 注解来表明该接口是函数式接口。
  • 函数式接口通常用作其他方法的输入参数;调用方法时只需要将函数式接口的抽象方法通过Lambda表达式或方法引用的形式作为参数传入即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

public class FunctionTR {

    /**
     * 对列表中的每个元素应用指定的函数转换,并返回转换后的新列表
     *
     * @param <T>         输入列表元素的类型
     * @param <R>         转换后列表元素的类型
     * @param convertList 待转换的元素列表
     * @param convertFun  用于转换元素的函数
     * @return 包含转换后元素的新列表
     * <p>
     * <T, R> 是泛型参数声明,它的位置必须紧跟在访问修饰符(如 public、static)之后,返回值类型之前,这个声明定义了该方法中使用的泛型参数
     * Function<T, R> 是 Java8 中新增的函数式接口,作用是接收一个 T 类型的参数,返回一个 R 类型的对象
     */
    public static <T, R> List<R> map(List<T> convertList, Function<T, R> convertFun) {
        List<R> result = new ArrayList<>();
        for (T s : convertList) {
            result.add(convertFun.apply(s));
        }
        return result;
    }

    public static void main(String[] args) {
        List<String> convertList = Arrays.asList("Lambda", "in", "action");
        List<Integer> iList = map(convertList, s -> s.length());
        System.out.println(iList); //[6, 2, 6]
        
        /* 传入map方法的第二个参数就是函数式接口的抽象方法的实现,可以理解为:
        Function<String, Integer> convertFun = new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return s.length();
            }
        };
        List<Integer> iList = map(convertList, convertFun);
        */
    }
}