函数式接口

参考文章:深度解析之Java8-函数式接口 - 知乎 (zhihu.com)微信公众平台 (qq.com)

定义

函数式接口:有且只有一个抽象方法的接口。

@FunctionalInterface注解

Java 8中为函数式接口引入了一个新的注解:@FunctionalInterface 。该注解可用于一个接口的定义上,在接口上使用该注解,编译器将会强制检查该接口是否有且仅有一个抽象方法。但是该注解不是必须的,只要符合函数式接口的定义,那么这个接口就是函数式接口。

原生函数式接口

Function: 函数型接口

Function接口是一个转换类型的接口,用来根据一个类型的数据得到另一个类型的数据,T称为前置条件,R称为后置条件(即有入参,有返回,其中T是入参,R是返回)。

1
2
3
4
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}

Predicate: 断言型接口

Predicate接口是一个判断型接口,可以看做Function接口的特例(即有入参,有返回,凡是返回的类型固定为boolean)。

1
2
3
4
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}

Consumer: 消费型接口

Consumer接口是一个消费型接口,主要负责消费数据(即有入参,无返回)。

1
2
3
4
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}

Supplier: 供给型接口

Supplier接口是一个获取型接口,与Consumer接口相反,主要负责产生数据(即无入参,有返回)。

1
2
3
4
@FunctionalInterface
public interface Supplier<T> {
T get();
}

示例

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
public class Main {
public static void main(String[] args) {
/** 函数型接口 */
Function<String,Integer> function = s->{
return s.length();
};
/** 断言型接口 */
Predicate<String> predicate = s->{
return s.length() <= Byte.MAX_VALUE;
};
/** 消费型接口 */
Consumer<String> consumer = s -> {
System.out.println(s);
};
/** 供给型接口 */
Supplier<String> supplier = ()->{
return "PigwantAcat";
};

System.out.println(function.apply("PigwantAcat"));
System.out.println(predicate.test("PigwantAcat"));
consumer.accept("PigwantAcat");
System.out.println(supplier.get());
}
}

// 控制台输出如下:
// 11
// true
// PigwantAcat
// PigwantAcat

默认方法和静态方法

Java 8中允许接口有静态方法和默认方法。

自定义的函数式接口

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
/**
* 函数式接口中只能有一个抽象方法,可以有默认方法和静态方法
*/
@FunctionalInterface
interface MyFunctionInterface{

/**
* 可以有常量,默认是【pubic static final】
*/
String NAME="测试";

/**
* 测试函数式接口
*/
void myTest();

/**
* 测试默认方法
*/
default void myDefaultTest(){
System.out.println("可以有默认方法");
}

/**
* 测试静态方法
*/
static void myStaticTest(){
System.out.println("可以有静态方法");
}

/**
* 获取name的值
* @return java.lang.String
*/
static String getName(){
return NAME;
}
}

测试

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
public class Main {
public static void main(String[] args) {
// MyFunctionInterface myFunctionInterface = new MyFunctionInterface() {
// @Override
// public void myTest() {
// System.out.println("测试:函数式接口 重写");
// }
// };
MyFunctionInterface mfi = ()->{
System.out.println("测试:函数式接口 lambda简化");
};
mfi.myTest();
mfi.myDefaultTest();

MyFunctionInterface.myStaticTest();
System.out.println(MyFunctionInterface.NAME);
System.out.println(MyFunctionInterface.getName());
}
}

// 控制台输出如下:
// 测试:函数式接口 lambda简化
// 可以有默认方法
// 可以有静态方法
// 测试
// 测试