本文中所有的函数式接口均位于(java.util.function) 包下。
目录
四大内置核心函数式接口
基于四大内置核心函数式接口的其它衍生接口
四大核心内置函数式接口详解与使用示例
一:Consumer<T>
这是一个函数式接口,被@FunctionalInterface 注解所申明的。该接口表示接受单个输入参数且不返回任何结果的操作。与大多数其它的功能不同的是,这个接口本身带有副作用,他可能修改所接收的参数(引用是不可变的,但是引用的对象中的数据是有可能被更改的)。它的函数式方法名字叫做 accept。
public class DemoConsumer {
public static void main(String[] args) {
DemoConsumer demoConsumer = new DemoConsumer();
demoConsumer.consumerDemoMethod("123", string -> System.out.println(string));
// 无论做什么操作, 只要不返回值, 哪怕是没有任何的主体都可以
demoConsumer.consumerDemoMethod("123", string -> {
});
// Consumer 在 jdk 中广泛应用于各大集合的 foreach 方法:
new ArrayList<String>().forEach(t -> System.out.println(t));
new ConcurrentHashMap<String, String>().forEach((key, value) -> System.out.println(key +", " + value));
}
public void consumerDemoMethod(String t, Consumer<String> par) {
par.accept(t);
}
}
二:Supplier<T>
这是一个函数式接口, 其函数式方法为 get,表示结果的提供者。它并不要求每一次的返回都是新的,也就是说只要有任意的返回都可以。它是不接收任何参数并返回一个任意的结果。
public class DemoSupplier {
public static void main(String[] args) {
Supplier<String> stringSupplier = new Supplier<String>() {
@Override
public String get() {
return "aa";
}
};
// 上方代码等价于
stringSupplier = () -> "aa";
System.out.println(stringSupplier.get());
}
}
三:Function<T, R> 与 BiFunction<T, U, R>
Function 代表一个函数,这个函数接收一个参数并且生成一个结果。这是一个函数式接口,其接口中的函数式方法为 apply(T t),而 BiFunction 与 Function 类似,只是它(BiFunction )接收两个参数,而只返回一个结果。
function 传递行为的demo
public class DemoFunction {
public static void main(String[] args) {
System.out.println(compute(1, integer -> 2 * integer));
System.out.println(compute(1, integer -> {return (2 + integer);}));
}
public static int compute(int req, Function<Integer, Integer> function) {
return function.apply(req);
}
}
多个 function 的串联操作
多个 function 的串联操作实际上是利用 function 接口内部提供的两个静态方法 compose 和 andThen(BiFunction 里面只有andThen),它们比较难以理解,示例代码如下
public class DemoFunction {
public static void main(String[] args) {
System.out.println(testCompose("输入 ", result -> result + " function1 的返回值", result -> result + " function2 的返回值"));
System.out.println(testCompose("输入 ", result -> result + " function1 的返回值", result -> result + " function2 的返回值",
result -> result + " function3 的返回值"));
System.out.println(testAndThen("输入 ", result -> result + " function1 的返回值", result -> result + " function2 的返回值"));
}
/**
* 多个 function 的串联操作, compose方法是当前的this.function对象接收一个新的new function对象,并且
* 新的 new function 对象的操作会在 this.function 对象执行之前执行,也就是说 function2 会在 function1
* 之前进行执行.
*/
public static String testCompose(String req, Function<String, String> function1, Function<String, String> function2) {
return function1.compose(function2).apply(req);
}
public static String testCompose(String req, Function<String, String> function1, Function<String, String> function2, Function<String, String> function3) {
return function1.compose(function2).compose(function3).apply(req);
}
/**
* 多个 function 的串联操作, andThen 方法理解成为compose相反操作即可.
*/
public static String testAndThen(String req, Function<String, String> function1, Function<String, String> function2) {
return function1.andThen(function2).apply(req);
}
public static String testAndThen(String req, Function<String, String> function1, Function<String, String> function2, Function<String, String> function3) {
return function1.andThen(function2).apply(req);
}
}
四:Predicate<T>
函数式接口,表示一个参数的谓词(判断)。是一个 布尔值的接口,其函数式方法是 test。
public class DemoPredicate {
public static void main(String[] args) {
// 构建一个谓词,用来判断条件是否满足
Predicate<String> predicate = p -> p.length() > 5;
// 调用test方法之后,判断值的长度是否大于5
System.out.println(predicate.test("一个参数"));
}
}
与操作,或操作,非操作
与或非三个操作实际上是使用了 Predicate 接口中提供的三个静态方法(与,and;或,or;非,negate).
public class DemoPredicate {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
Predicate<Integer> a = i -> i > 5;
Predicate<Integer> b = i -> i % 2 == 0;
// 逻辑与操作, 只有当 a 和 b 都为true的时候, 值才输出
list.stream().filter(a.and(b)).forEach(System.out::println);
System.out.println("--------------------------------------");
// 逻辑或操作, 当 a 和 b 任意值为true的时候, 值会输出
list.stream().filter(a.or(b)).forEach(System.out::println);
System.out.println("--------------------------------------");
// 逻辑非操作, 也就是取反, 当值为true的时候, 输出false
list.stream().filter(a.negate()).forEach(System.out::println);
}
}
方法引用
内置函数式接口通用的核心只有这四个,其余的都是基于它们的衍生(比如上文中的 Function 与 BiFunction),接下来需要看的是方法引用。