1、函数式接口 -------------------------> 理解
2、常用函数式接口 ---------------------> 重点格式
A. Supplier "只出不进"
B. Consumer "只进不出"
C. Predicate "条件判断"
D. Function "类型转换"
A. 函数式接口是在Java语言当中"有且只有一个抽象方法的接口"
B. 如果方法的参数是 函数式接口,那么在传递参数的时候,就可以写 Lambda 表达式
@FunctionalInterface //注解,用于校验是否是函数式接口
public interface 接口名称 {
public abstract 返回值类型 方法名称(参数列表);
}
我们可以把 Lambda 表达式看做匿名内部类的简化版本。专业术语叫做"语法糖" --->理解
但是Lambda和匿名内部类不同的地方在于: Lambda的性能比匿名内部类要高,主要是有延迟执行的效果。
A.无参无返回
方法名称(()->{以前抽象方法当中需要执行的代码});
B.有参有返回
方法名称((参数列表可省略类型)->{以前抽象方法当中需要执行的代码 return 返回值});
@FunctionalInterface
public interface Supplier<T> {
T get();
}
特点: "只出不进",生产型接口
使用: 如果想要得到某个结果,不用传入参数,就可以使用接口Supplier 作为方法的参数
//采用函数式接口 Supplier 完成数组求最小值操作
public class Test01 {
//写一个方法,方法的参数是函数式接口(就可以使用Lambda)
public static int getMin(Supplier<Integer> sup){
return sup.get();
}
//主方法
public static void main(String[] args) {
//定义数组
int[] arr = {
22,54,12,7,88
};
//调用方法,参数是函数式接口,就可以写Lambda
int min = getMin(()->{
int minValue = arr[0];
for (int num : arr) {
if(num<minValue){
minValue = num;
}
}
return minValue;
});
System.out.println("min = " + min); //min = 7
}
}
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
特点: "只进不出" 消费型接口
使用: 如果想要对某个数据进行处理,不需要得到结果,这里就可以使用 消费型接口 Consumer<T>
注意: 可以连续消费的,连续消费使用的是 andThen()
public static void main(String[] args) {
//定义一个字符串类型的数组
String[] arr = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男"};
printData(arr, s1 -> System.out.print("姓名:" + s1.split(",")[0]), s2 -> System.out.println(",性别" + s2.split(",")[1]));
//===========================
//姓名:迪丽热巴,性别女
//姓名:古力娜扎,性别女
//姓名:马尔扎哈,性别男
}
//定义一个方法,方法的参数是函数式接口 Consumer
public static void printData(String[] array, Consumer<String> con1, Consumer<String> con2) {
//循环遍历字符串
for (String s : array) {
//消费
con1.andThen(con2).accept(s);
}
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
特点: "条件判断" 判断型接口
使用: 如果我们想要对某个逻辑进行判断,可以把接口写在方法参数上面,返回值写 boolean
注意: 可以提升逼格。 and() 与 or() 或 negate() 非
//筛选 性别是女,并且姓名的长度是4的数据,保存在集合当中
public static void main(String[] args) {
//定义一个储存字符串的数组
String[] array = { "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "赵丽颖,女" };
//调用方法
List<String> list = getData(array,s1->s1.split(",")[1].equals("女"),s2->s2.split(",")[0].length()==4);
//打印输出
System.out.println("list = " + list); //list = [迪丽热巴,女, 古力娜扎,女]
}
//定义方法,参数是函数式接口.Predicate
public static List<String> getData(String[] arr, Predicate<String> p1,Predicate<String> p2){
//创建集合的对象
List<String> mList = new ArrayList<>();
//我们需要对数组的元素进行判断,所以需要遍历数组
for (String s : arr) {
//判断,具体的判断业务,需要使用Lambda
boolean bb = p1.and(p2).test(s);
if(bb){
mList.add(s);
}
}
//返回结果
return mList;
}
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
特点: "类型转换" 类型转换接口
使用: 如果我们想要把一个数据类型,转换成为另一个数据类型,需要使用接口。作为方法的参数
注意: 连续转换 andThen()
//1.获取年龄字符串
//2.将字符串转换成为int类型
//3.把转换的int类型加上100
public static void main(String[] args) {
String str = "赵丽颖,20";
//调用方法
int number = getData(str, str1 -> str1.split(",")[1], str2 -> Integer.parseInt(str2), num1 -> num1 + 100);
System.out.println("number = " + number);
}
//定义方法,方法的参数是函数式接口 Function
public static int getData(String str, Function<String, String> fun1, Function<String, Integer> fun2, Function<Integer, Integer> fun3) {
int num = fun1.andThen(fun2).andThen(fun3).apply(str);
return num;
}