Java基础进阶Day12

Java基础进阶Day12

课程大纲

1、函数式接口 -------------------------> 理解
2、常用函数式接口 ---------------------> 重点格式
        A. Supplier 	"只出不进"		
        B. Consumer 	"只进不出"
        C. Predicate	"条件判断"
        D. Function		"类型转换"

第一章 函数式接口

1、含义
A. 函数式接口是在Java语言当中"有且只有一个抽象方法的接口"
B. 如果方法的参数是 函数式接口,那么在传递参数的时候,就可以写 Lambda 表达式
2、格式
@FunctionalInterface   	//注解,用于校验是否是函数式接口
public interface 接口名称 {
	public abstract 返回值类型 方法名称(参数列表);    
}
3、对比Lambda和匿名内部类
我们可以把 Lambda 表达式看做匿名内部类的简化版本。专业术语叫做"语法糖"  --->理解
但是Lambda和匿名内部类不同的地方在于: Lambda的性能比匿名内部类要高,主要是有延迟执行的效果。
4、两类抽象方法(Lambda表达式)
A.无参无返回
	 方法名称(()->{以前抽象方法当中需要执行的代码});
	 
B.有参有返回
	 方法名称((参数列表可省略类型)->{以前抽象方法当中需要执行的代码 return 返回值});

第二章 常用的函数式接口

1、Supplier 函数式接口
A. JDK源码
@FunctionalInterface
public interface Supplier<T> {
	T get();
}
B. 接口特点
特点: "只出不进",生产型接口
使用: 如果想要得到某个结果,不用传入参数,就可以使用接口Supplier 作为方法的参数
C.案例代码
//采用函数式接口  Supplier<T> 完成数组求最小值操作
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
    }
}
2、Consumer 函数式接口
A. JDK源码
@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); };
    }
}
B.接口特点
特点: "只进不出" 消费型接口
使用: 如果想要对某个数据进行处理,不需要得到结果,这里就可以使用 消费型接口 Consumer<T>
注意: 可以连续消费的,连续消费使用的是 andThen()
C.案例代码
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<T>
public static void printData(String[] array, Consumer<String> con1, Consumer<String> con2) {
	//循环遍历字符串
	for (String s : array) {
		//消费
		con1.andThen(con2).accept(s);
	}
}
3、Predicate 函数式接口
A. JDK源码
@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);
    }
}
B.接口特点
特点: "条件判断" 判断型接口
使用: 如果我们想要对某个逻辑进行判断,可以把接口写在方法参数上面,返回值写 boolean
注意: 可以提升逼格。 and()or()negate()
C. 案例代码
//筛选 性别是女,并且姓名的长度是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<T>
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;
}
4、Function 函数式接口
A.JDK源码
@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;
    }
}
B.接口特点
特点: "类型转换" 类型转换接口
使用: 如果我们想要把一个数据类型,转换成为另一个数据类型,需要使用接口。作为方法的参数
注意: 连续转换 andThen()
C.案例代码
//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<T, R>
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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43904518/article/details/85175698