引言
Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。java8 新特性非常多,上一节介绍了Java8新特性中的方法引用,本小节继续讲解Java8的新特性之三:函数式接口用。
java8新特性
- jdk8新特性之一Lambda表达式
- jdk8新特性之二方法引用
- jdk8新特性之三函数式接口
- jdk8新特性之四默认方法
- jdk8新特性之五Stream API
- jdk8新特性之六Optional类
- jdk8新特性之七Nashorn JavaScript
- jdk8新特性之八日期时间API
- jdk8新特性之九Base64
函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。
函数式接口可以用**@FunctionalInterface**注解标识。
@FunctionalInterface注解是对函数式接口的标识,他的作用是对接口进行编译级别的检查,如果一个接口使用了这个注解,但是写了两个抽象方法,会出现编译错误。
定义了一个函数式接口如下:
@FunctionalInterface
interface testService
{
void toMessage(String mes);
}
那么就可以使用Lambda表达式来表示该接口的一个实现(注:JAVA 8 之前一般是用匿名类实现的):
TestService testService = message -> System.out.println("Hello " + message);
testService.toMessage("我是测试");
java.util.function
java.util.function 它包含了很多类,用来支持 Java的 函数式编程,该包中的函数式接口有:
序号 | 接口 | 描述 |
---|---|---|
1 | BiConsumer<T,U> | 代表了一个接受两个输入参数的操作,并且不返回任何结果 |
2 | BiFunction<T,U,R> | 代表了一个接受两个输入参数的方法,并且返回一个结果 |
3 | BinaryOperator | 代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果 |
4 | BiPredicate<T,U> | 代表了一个两个参数的boolean值方法 |
5 | BooleanSupplier | 代表了boolean值结果的提供方 |
6 | Consumer | 代表了接受一个输入参数并且无返回的操作 |
7 | DoubleBinaryOperator | 代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。 |
8 | DoubleConsumer | 代表一个接受double值参数的操作,并且不返回结果。 |
9 | DoubleFunction | 代表接受一个double值参数的方法,并且返回结果 |
10 | DoublePredicate | 代表一个拥有double值参数的boolean值方法 |
11 | DoubleSupplier | 代表一个double值结构的提供方 |
12 | DoubleToIntFunction | 接受一个double类型输入,返回一个int类型结果。 |
13 | DoubleToLongFunction | 接受一个double类型输入,返回一个long类型结果 |
14 | DoubleUnaryOperator | 接受一个参数同为类型double,返回值类型也为double 。 |
15 | Function<T,R> | 接受一个输入参数,返回一个结果。 |
16 | IntBinaryOperator | 接受两个参数同为类型int,返回值类型也为int 。 |
17 | IntConsumer | 接受一个int类型的输入参数,无返回值 。 |
18 | IntFunction | 接受一个int类型输入参数,返回一个结果 。 |
19 | IntPredicate | 接受一个int输入参数,返回一个布尔值的结果。 |
20 | IntSupplier | 无参数,返回一个int类型结果。 |
21 | IntToDoubleFunction | 接受一个int类型输入,返回一个double类型结果 。 |
22 | IntToLongFunction | 接受一个int类型输入,返回一个long类型结果。 |
23 | IntUnaryOperator | 接受一个参数同为类型int,返回值类型也为int 。 |
24 | LongBinaryOperator | 接受两个参数同为类型long,返回值类型也为long。 |
25 | LongConsumer | 接受一个long类型的输入参数,无返回值。 |
26 | LongFunction | 接受一个long类型输入参数,返回一个结果。 |
27 | LongPredicate | R接受一个long输入参数,返回一个布尔值类型结果。 |
28 | LongSupplier | 无参数,返回一个结果long类型的值。 |
29 | LongToDoubleFunction | 接受一个long类型输入,返回一个double类型结果。 |
30 | LongToIntFunction | 接受一个long类型输入,返回一个int类型结果。 |
31 | LongUnaryOperator | 接受一个参数同为类型long,返回值类型也为long。 |
32 | ObjDoubleConsumer | 接受一个object类型和一个double类型的输入参数,无返回值。 |
33 | ObjIntConsumer | 接受一个object类型和一个int类型的输入参数,无返回值。 |
34 | ObjLongConsumer | 接受一个object类型和一个long类型的输入参数,无返回值。 |
35 | Predicate | 接受一个输入参数,返回一个布尔值结果。 |
36 | Supplier | 无参数,返回一个结果。 |
37 | ToDoubleBiFunction<T,U> | 接受两个输入参数,返回一个double类型结果 |
38 | ToDoubleFunction | 接受一个输入参数,返回一个double类型结果 |
39 | ToIntBiFunction<T,U> | 接受两个输入参数,返回一个int类型结果。 |
40 | ToIntFunction | 接受一个输入参数,返回一个int类型结果。 |
41 | ToLongBiFunction<T,U> | 接受两个输入参数,返回一个long类型结果。 |
42 | ToLongFunction | 接受一个输入参数,返回一个long类型结果。 |
43 | UnaryOperator | 接受一个参数为类型T,返回值类型也为T。 |
函数式接口实例
Consumer
接口唯一的抽象方法是:`void accept(T t);
这是一个单参数,无返回值的方法,参数是泛型类。这个接口被称为消费型接口,因为没有返回值,接口里面干了什么和调用方没什么关系。
这种单参数无返回值的接口我们可以这么用Lambda表达式:
Consumer consumer=(par)->System.out.println(par);
consumer.accept("我是来测试Consumer");
输出结果是:
我是来测试Consumer
Supplier
接口唯一的抽象方法是:T get();
这是一个无参数,有返回值的方法,返回值类型是泛型类。这个接口被称作供给型接口。
这种无参数有返回值的方法我们可以这么用:
//供给型接口
Supplier<String> supplier=()-> new String("我是来测试Supplier");
String str=supplier.get();
System.out.println(str);
输出结果是:
我是来测试Supplier
ToIntFunction
接口唯一的抽象方法是:int applyAsInt(T value);
这是一个单参数,返回值为int的方法,参数类型是泛型类。
ToIntFunction<String> toIntFunction=(a) -> Integer.parseInt(a);
int i=toIntFunction.applyAsInt("123");
System.out.println("测试ToIntFunction,返回整数是:"+i);
输出结果是:
测试ToIntFunction,返回整数是:123
Predicate
接口唯一的抽象方法是:boolean test(java.lang.Object arg0);
package com.adanblog.demo;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* java8新特性之三函数接口
* @author www.adanblog.com
*
*/
public class FunctionTest2 {
public static void main(String[] args) {
List<Integer> list=Arrays.asList(1,2,3,4,5,6,7,8,9);
// Predicate<Integer> predicate = n -> true
// n 是一个参数传递到 Predicate 接口的 test 方法
// n 如果存在则 test 方法返回 true
System.out.println("输出所有数据:");
eval(list,n -> true);
// 如果 n%2 为 0 test 方法返回 true
System.out.println("输出所有偶数:");
eval(list, n -> n%2 == 0);
//如果 n 大于 3 test 方法返回 true
System.out.println("输出所有大于3的数字:");
eval(list, n -> n>3);
}
public static void eval(List<Integer> list,Predicate<Integer> predicate) {
for (Integer n : list) {
if(predicate.test(n)) {
System.out.println(n+" ");
}
}
}
}
输出结果是:
输出所有数据:
1
2
3
4
5
6
7
8
9
输出所有偶数:
2
4
6
8
输出所有大于3的数字:
4
5
6
7
8
9
关于阿丹博客
以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现 bug 或者有更好的 >建议,欢迎留言批评指正,不吝感激。
下面阿丹的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛。GitHub:https://github.com/adanblog/