一、Lambda表达式需要“函数式接口”的支持
Lambda 的设计者们为了让现有的功能与 Lambda 表达式良好兼容,考虑了很多方法,于是产生了函数接口这个概念。
函数接口指的是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,这样的接口可以隐式转换为 Lambda 表达式。
但是在实践中,函数式接口非常脆弱,只要某个开发者在该接口中添加一个函数,则该接口就不再是函数式接口进而导致编译失败。为了克服这种代码层面的脆弱性,并显式说明某个接口是函数式接口,Java 8 提供了一个特殊的注解@FunctionalInterface,举个简单的函数式接口的定义:
@FunctionalInterfacepublic interface GreetingService {void sayMessage(String message);}
Java7 只能通过匿名内部类进行编程,例如:
GreetingService greetService = new GreetingService() {@Overridepublic void sayMessage(String message) {System.out.println("Hello " + message);}};greetService.sayMessage("world");
Java8 可以采用 Lambda 表达方进行编程,例如:
GreetingService greetService = message -> System.out.println("Hello " + message);greetService.sayMessage("world");
目前 Java 库中的所有相关接口都已经带有这个注解了,实践上java.lang.Runnable和java.util.concurrent.Callable是函数式接口的最佳例子!
- 函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。
可以使用注解
@FunctionalInterface添加在该接口类上进行修饰,可以检查是否是函数式接口A.定义函数式接口
```java /**
- Fun
- encoding:UTF-8 *
@author Fcant 下午 14:51:50 2020/2/19/0019 */ @FunctionalInterface public interface Fun
{ Integer getValue(T t);
}
<a name="2hMiL"></a>### B.函数式接口的使用```java// 函数式接口使用@Testpublic void funTest() {Integer op = op(1000, (x) -> x * x);System.out.println(op);}public Integer op(Integer in, Fun<Integer> fun) {return fun.getValue(in);}
二、Java四大内置核心函数式接口
| 函数式接口 | 参数类型 | 返回值类型 | 包含的方法 | 用途 |
|---|---|---|---|---|
Consumer<T>消费型接口 |
T |
void |
void accept(T t); |
对类型为T的对象应用操作 |
Supplier<T>供给型接口 |
无 | T |
T get(); |
返回类型为T的对象 |
Function<T, R>函数型接口 |
T |
R |
R apply(T t); |
对类型为T的对象应用操作,并返回R类型的结果 |
Predicte<T>断定型接口 |
T |
boolean |
boolean test(T t); |
确定类型为T的对象是否满足某约束,并返回boolean值 |
1、四大核心内置接口
A.Consumer:消费型接口
void accept(T t);
// 1.Consumer<T> :消费型接口public void happyTest(double money, Consumer<Double> consumer) {consumer.accept(money);}@Testpublic void consumerTest() {happyTest(1000d, (x) -> System.out.println("本次消费:" + x + "元"));}
B.Supplier:供给型接口
T get();
// 2.Supplier<T> :供给型接口public List<Integer> getNumList(int n, Supplier<Integer> supplier) {List<Integer> list = new ArrayList<>();for (int i = 0; i < n; i++) {Integer num = supplier.get();list.add(num);}return list;}@Testpublic void supplierTest() {getNumList(10, () -> (int)(Math.random() * 100)).forEach(System.out::println);}
C.Function<T, R>:函数型接口
R apply(T t);
// 3.Function<T, R> :函数型接口public String strHandler(String s, Function<String, String> function) {return function.apply(s);}@Testpublic void strTest() {System.out.println(strHandler("gh", (s) -> s.toUpperCase()));}
D.Predicate:断言型接口
boolean test(T t);
// 4.Predicate<T> :断言型接口public List<String> filterStr(List<String> list, Predicate<String> predicate) {List<String> strings = new ArrayList<>();for (String s : list) {if (predicate.test(s)) {strings.add(s);}}return strings;}@Testpublic void strFilterTest() {List<String> stringList = Arrays.asList("Hello", "Fcant", "Lambda", "ww", "ok");filterStr(stringList, (s) -> s.length() > 3).forEach(System.out::println);}
2、其他接口
| 函数式接口 | 参数类型 | 返回值类型 | 包含的方法 | 用途 |
|---|---|---|---|---|
BiFunction<T, U, R> |
T,U | R | R apply(T t, U u); |
对类型为T的对象应用操作 |
UnaryOperator<T>(Function子接口) |
T | T | T apply(T t); |
返回类型为T的对象 |
BinaryOperator<T>(BiFunction子接口) |
T, T | T | T apply(T t1, T t2); |
对类型为T的对象应用操作,并返回R类型的结果 |
BiConsumer<T, U> |
T, U | void | void accept(T t, U u); |
确定类型为T的对象是否满足某约束,并返回boolean值 |
ToIntFunction<T>ToLongFunction<T>ToDoubleFunction<T> |
T | int long double |
分别计算int,long,double、值的函数 | |
IntFunction<R>LongFunction<R>DoubleFunction<R> |
int long double |
R | 参数分别为int,long,double类型的函数 |
