06. 函数式接口 Consumer\Supplier\Function\Predicate
package com.lambda.fun;
/**
* @Author:kaiyang.cui
* @Package:com.lambda.fun
* @Project:jdk8
* @name:Demo01Fun
* @Date:2023/4/2 下午8:33
* @Filename:Demo01Fun
* @Description:填写功能描述
* @Version:1.0
*/
public class Demo01Fun {
public static void main(String[] args) {
fun1((arr)->{
int sum = 0;
for (int i : arr) {
sum += i;
}
return sum;
});
}
public static void fun1(Operator operator){
int[] arr = {1,2,3,4,5};
int sum = operator.getSum(arr);
System.out.println("sum = " + sum);
}
}
@FunctionalInterface
interface Operator{
int getSum(int[] arr);
}
函数式接口的由来
我们知道使用lambda表达式的前提是需要有函数式接口,而lambda表达式使用时不关心接口名,抽象方法名,只关心抽象方法的参数列表和返回值类型。
因此为了让我们使用lambda表达式更加的方便,在JDK中提供了大量常用的函数式接口。
函数式接口的常用接口
函数式接口介绍
在JDK中帮我们提供函数式接口,主要在java.util.function
Consumer
有参无返回值的接口 【消费数据才会无返回值】
使用的时候需要指定泛型来定义参数类型。
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
}
public static void fun2(Consumer<String> consumer){
consumer.accept("HELLO WORLD");
}
@Test
@DisplayName("Consumer 函数式接口的使用")
public void test2(){
fun2((str)->{
System.out.println(str + "->转换为小写" + str.toLowerCase());
});
}
【默认方法】andThen
public static void fun3(Consumer<String> c1, Consumer<String> c2) {
String str = "Hello World";
// c1.accept(str); // 转小写
// c2.accept(str); // 转大写
c1.andThen(c2).accept(str); // 先转小写再转大写
c2.andThen(c1).accept(str); // 先转大写再转小写
}
@Test
@DisplayName("Consumer 函数式接口的使用")
public void test3(){
fun3((str)->{
System.out.println(str + "->转为小写" + str.toLowerCase());
},(str)->{
System.out.println(str + "->转为大写" + str.toUpperCase());
});
}
【案例】:将输入的数据统一转换为小写
Supplier
无参有返回值的接口【生产数据才会有返回值】
相应的lambda:对应的lambda表达式需要提供一个返回数据的类型。
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
为什么要使用下面的方式去找出一个数组中的最大值呢?
因为我们要使用lambda表达式,我们没有必要自己去声明一个接口!!!!
用java.util.function
自带的就可以啦!!!!
package com.lzh;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.function.Supplier;
/**
* @Author:kaiyang.cui
* @Package:com.lzh
* @Project:jdk8
* @name:MyTest
* @Date:2023/4/2 下午9:07
* @Filename:MyTest
* @Description:MyTest
* @Version:1.0
*/
@Slf4j
public class MyTest {
public static void fun1(Supplier<Integer> supplier){
Integer max = supplier.get();
System.out.println("最大值"+ max);
}
@Test
@DisplayName("Supplier 函数式接口的使用")
public void test1(){
fun1(()->{
int arr[] = {22,33,44,23,4,5};
Arrays.sort(arr);
return arr[arr.length-1];
});
}
}
Function
有参且有返回值的接口
【Function接口】:根据一个类型的数据得到另一个类型的数据。
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
【案例】:传递进去一个字符串返回一个数字
public static void fun4(Function<String, Integer> function){
Integer apply = function.apply("666");
System.out.println("apply = " + apply);
}
@Test
@DisplayName("Function 函数式接口的使用")
public void test4() {
fun4(msg ->{
return Integer.parseInt(msg);
});
}
【默认方法】:andThen,也是用来组合操作。
public static void fun5(Function<String, Integer> f1,Function<Integer, Integer> f2){
// Integer i1 = f1.apply("666");
// Integer i2 = f2.apply(i1);
Integer apply = f1.andThen(f2).apply("666");
System.out.println("i2 = " + apply);
}
@Test
@DisplayName("Function 函数式接口的使用")
public void test5() {
fun5(msg ->{
return Integer.parseInt(msg);
},(msg2)->{
return msg2 * 2;
});
}
- 默认的compose方法的作用顺序和andThen方法刚好相反
- 而静态方法identity,则是输入什么参数就返回什么结果
Predicate
有参且返回值为Boolean的接口
根据我们传入的数据进行判断,给出一个boolean类型的true或false
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
【案例】:传入一个字符串判断长度
public static void fun6(Predicate<String> predicate,String msg){
boolean b = predicate.test(msg);
System.out.println("b = " + b);
}
@Test
@DisplayName("Predicate 函数式接口的使用")
public void test6() {
fun6(msg ->{
return msg.length() > 3;
},"Hello World");
}
在Predicate中的默认方法提供了逻辑关系操作
- and
- or
- negate
- isEquals
public static void fun7(Predicate<String> p1,Predicate<String> p2){
// p1 包含H 同时p2 包含H
boolean b1 = p1.and(p2).test("Hello");
// p1 包含H 或者p2包含w
boolean b2 = p1.or(p2).test("Hello");
//p1 不包含H
boolean b3 = p1.negate().test("Hello");
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
}
@Test
@DisplayName("Predicate 函数式接口的使用")
public void test7() {
fun7(msg ->{
return msg.contains("H");
},msg2->{
return msg2.contains("w");
});
}
Command + option + O 搜索类: