天天看点

【Java基础学习笔记】19、函数式接口和Lambda表达式函数式接口Lambda表达式使用Lambda表达式简化函数式接口

文章目录

  • 函数式接口
    • 常用的函数式接口 - JDK8之后
      • Supplier:生产者
      • Consumer:消费者
      • Predicate:判断
      • Function:转换
  • Lambda表达式
    • 作用
    • 使用方法
    • 方法引用
  • 使用Lambda表达式简化函数式接口
    • Supplier接口
    • Consumer接口
    • Predicate接口
    • Function接口

函数式接口

 @FunctionalInterface - 只有一个抽象方法的接口。

常用的函数式接口 - JDK8之后

Supplier:生产者

 T get(); - 返回一个设定泛型的值。

Consumer:消费者

 void accept(T t); - 获得一个泛型值并消费。

 Consumer1.andThen(Consumer2)

 先Consumer1消费,再Consumer2消费

Predicate:判断

 boolean(T t); - 获得一个泛型值并进行判断,返回一个布尔值。

 常用API:

  and():pre1.and(pre2).test(t) 与

  or():pre1.or(pre2).test(t) 或

  negate():pre1.negate().test(t) 取反

Function:转换

 用来做类型转换。

  R apply(T t) - 将T类型转化为R类型。

 常用API:

  compose(Function fun)

 如:fun1.compose(fun2).apply(t) - 先执行fun2,再执行fun1

  andThen(Function fun)

 如:fun1.andThen(fun2).apply(t) - 先执行fun1,再执行fun2

Lambda表达式

作用

 匿名内部类的简化。

 匿名内部类是实现函数式接口的时候,可以使用Lambda简化。

使用方法

 原则:可推导,可省略。

 1、要使用的接口和接口的方法是确定的,可以省略,保留方法参数和方法体。

 2、方法参数类型可以省略。

 3、前提:方法体中只有一句话,省略return关键字、分号、方法体的大括号,要省一起省。

注意!:Lambda表达式能取代匿名内部类,但是Lambda表达式不是类。

方法引用

当:

 1、lambda表达式中只有一句代码 - 调用方法。

 2、lambda表达式的参数就是代码中调用方法的参数。

 方法引用 -> ::

使用方法引用的几种情况:

 对象::实例方法名

 类::静态方法名

 类::new

 类::实例方法名

 this::本类方法名

 super::父类方法名

 Type::new 如:int[n]::new -创建新数组

上个this::本类方法名的例子

@FunctionalInterface
interface Richable{
    void buy(String name);
}

public class this_demo {
    //用来放将函数式接口作为参数的实例方法
    public void buy(String name,Richable richable){
        richable.buy(name);
    }
    //用来让this调用的实例方法
    public void marry(String name){
        System.out.println(name+"买房了");
    }
    //用来调用buy方法的实例方法
    public void show(){
        String name="lucy";
        buy(name,this::marry);
    }

    public static void main(String[] args) {
        //调用show方法输出,方便观察
        new this_demo().show();
    }
}
           

结果如下:

【Java基础学习笔记】19、函数式接口和Lambda表达式函数式接口Lambda表达式使用Lambda表达式简化函数式接口

使用Lambda表达式简化函数式接口

Supplier接口

public class MySupplier {
    /*Supplier 是一个函数式接口
      可使用lambda简化,前提是使用Supplier作为方法参数
     */
    public static Integer[] getSorted(Integer[] arr,Supplier<Integer[]> sup){
        return sup.get();
    }

    public static void main(String[] args) {
        Integer[] arr = {9,55,25,35,8};
        System.out.println(Arrays.toString(getSorted(arr, () -> {
                for (int i = 0; i < arr.length-1; i++) {
                    int max=i;
                    for (int j = i+1; j < arr.length; j++) {
                        if(arr[j]>arr[max]){
                            max=j;
                        }
                    }
                    if(i!=max) {
                        int temp = arr[max];
                        arr[max] = arr[i];
                        arr[i] = temp;
                    }
                }
                return arr;
        })));
    }
}
           

结果如下:

【Java基础学习笔记】19、函数式接口和Lambda表达式函数式接口Lambda表达式使用Lambda表达式简化函数式接口

Consumer接口

public class MyConsumer {
    public static void changName(String[] str, Consumer<String> con,Consumer<String> com){
        for (String string: str) {
            con.andThen(com).accept(string);
        }
    }

    public static void main(String[] args) {
        String str =  "迪丽热巴,女;古力娜扎,女;马尔扎哈,男";
        String[] ss = str.split(";");
        changName(ss, s ->{
                String[] strings = s.split(",");
                System.out.println("姓名:"+strings[0]+",性别:"+strings[1]);
            }, System.out::println);
    }
}
           

结果如下:

【Java基础学习笔记】19、函数式接口和Lambda表达式函数式接口Lambda表达式使用Lambda表达式简化函数式接口

Predicate接口

public class MyPredicate {
    public static boolean judge(String str, Predicate<String> pre){
        //判断名字长度
        return pre.test(str);
    }

    public static boolean select(String str,Predicate<String> selectName,Predicate<String> selectGender){
        //筛选
        return selectName.and(selectGender).test(str);
    }


    public static void main(String[] args) {
        String name = "泰达米尔";
        System.out.println(judge(name,s -> s.length()<=3));

        String[] array = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男","赵丽颖,女","胡歌,男"};
        for (String str:array
             ) {
            boolean keep = select(str,s -> {
                return str.split(",")[0].length()==4;
            },s -> {
                return str.split(",")[1].equals("女");
            });
            if(keep){
                System.out.println(str);
            }
        }
    }
}
           
【Java基础学习笔记】19、函数式接口和Lambda表达式函数式接口Lambda表达式使用Lambda表达式简化函数式接口

Function接口

public class MyFunction {
    /*
1. 将字符串截取数字年龄部分,得到字符串;
2. 将上⼀步的字符串转换成为int类型的数字;
3. 将上⼀步的int数字累加100,得到结果int数字。
     */
    public static int getNum(String str, Function<String,String> fun1,Function<String,Integer> fun2,Function<Integer,Integer> fun3){
        return fun3.compose(fun2).compose(fun1).apply(str);
        //先执行fun1,再执行fun2,最后执行fun3
    }

    public static void main(String[] args) {
        String str = "周杰伦,42";
        int num = getNum(str,s-> str.split(",")[1],s -> Integer.valueOf(s),i -> i+100);
        //分别做了字符串分割,类型准换和数值相加
        System.out.println(num);
    }
}
           

结果如下:

【Java基础学习笔记】19、函数式接口和Lambda表达式函数式接口Lambda表达式使用Lambda表达式简化函数式接口