函数式接口

函数式接口

函数式接口:有且仅有一个抽象方法得接口

java中的函数式编程体现就是lamada表达式,所以函数式接口就是可以适用于lamada使用得接口,只有确保接口中有且仅有一个抽象方法,java中得lamada才能顺利进行推导

在接口中加上注释:@FunctionalInterface,如果接口时函数式接口,编译通过,如果不是,编译失败

函数式接口作为方法的参数

定义一个类RunnableDemo,在类中提供两个方法

一个方法是,startThread(Runnable r),方法参数Runnable是一个函数式接口

另一个方法是主方法,在主方法中调用startThread方法

public class RunnableDemo {
    //ctrl b跟进看源码
    public static void startThread(Runnable r){
        Thread t = new Thread(r);
        t.start();
    }
    public static void main(String[] args){
//        匿名内部类 Runnable是一个函数式接口
        startThread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"启动");
            }
        });
        startThread(()-> System.out.println(Thread.currentThread().getName()));
    }

}

如果方法的参数是一个函数式接口,我们可以使用lamada表达式作为参数传递

函数式接口作为方法的返回值

定义一个类(ComparatorDemo),在类中提供两个方法

一个方法是:Comparator getCommparator() 方法返回值Comparator是一个函数式接口

一个方法是主方法,在主方法中调用getComparator方法

public class ComparatorDemo {
    private static Comparator<String> getCommparator(){
        //匿名内部类的方式实现
//        Comparator<String> comp = new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.length()-o2.length();
//            }
//        }

//        return new Comparator<String>() {
//            @Override
//            //按照长度排序
//            public int compare(String o1, String o2) {
//                return o1.length()-o2.length();
//            }
//        };

        //lamada表达式
//        return ((String o1,String o2) ->{
//            return o1.length()-o2.length();
//        });

        return (o1,o2) -> o1.length()-o2.length();


    }
    public static void main(String[] args){
        //构造使用场景
        //定义集合,存储字符串元素
        ArrayList<String> array = new ArrayList<String>();
        array.add("sss");
        array.add("b");
        System.out.println(array);
        Collections.sort(array,getCommparator());
        System.out.println(array);

    }
}

如果方法的返回值是一个函数式接口,我们可以使用lamada表达式作为结果返回

常用的函数式接口

java.util.function包下与定义了大量的皆苦

supplier接口

Supplier:包含一个无参的方法

T get():获得结果

该方法不需要参数,它会按照某种实现逻辑(有lamada表达式实现)返回一个数据

Supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会产生什么类型的数据供我们使用

练习

定义一个类(SupplierTest),在类中提供两个方法

一个方法是int getMax(Supplier sup)用于返回int数组中的最大值

一个方法是主方法,在主方法中调用getMax方法

public class SupplierTest {
    private static int getMax(Supplier<Integer> sup){
        return sup.get();
    }
    public static void main(String[] args){
        //定义一i个int数组
        int[] arr = {19,23,4,5,78};
        int maxValue = getMax(()->{
            int max = arr[0];
            for(int i=1; i<arr.length; i++){
                if(arr[i] > max){
                    max = arr[i];
                }
            }
            return max;
        });
        System.out.println(maxValue);
    }
}

Consumer接口

    • Modifier and Type方法描述
      voidaccept(T t)对给定的参数执行此操作。
      default Consumer<T>andThen(Consumer<? super T> after)返回一个组成的 Consumer ,依次执行此操作,然后执行 after操作。

Comsumer接口也被称为消费型接口,它消费的数据的数据类型有泛型指定

public class ComsumerDemo {
    public static void main(String[] args){
//        opertorString("嗡嗡嗡",(String s)->{
//            System.out.println(s);
//        });
        opertorString("嗡嗡嗡",s->System.out.println(s));
        //方法引用
        opertorString("嗡嗡嗡",System.out::println);

        opertorString("w嗡嗡嗡",s->{
            System.out.println(new StringBuilder(s).reverse().toString());
        });
        opertorString("日日日",s-> System.out.println(new StringBuilder(s).reverse().toString()));
        opertorString("小问题",s->System.out.println(s),s-> {
            System.out.println(new StringBuilder(s).reverse().toString());
        });
    }
    //用不同的方式消费同一个字符串数据两次
    private static void opertorString(String name,Consumer<String> con1,Consumer<String> con2){
//        con1.accept(name);
//        con2.accept(name);
//andThen相当于执行了两次after操作
        con1.andThen(con2).accept(name);
    }
    //消费一个字符串数据
    private static void opertorString(String name, Consumer<String> con){
        con.accept(name);
    }

}
练习

String[] strArray = {“小甘,80”,“小棠,56”,“小米,88”};

字符串数组中有多条信息,按照格式将信息打印出来

把打印姓名的动作作为第一个Consumer接口的lamada实例

把打印年龄的动作作为第二个consumer接口的lamada实例

将两个consumer接口按照顺序组合到一起使用

public class ConsumerDemo2 {
    public static void main(String[] args){
        String[] strArray = {"小甘,80", "小棠,56", "小米,88"};
        printInfo(strArray,str->{
            String name = str.split(",")[0];
            System.out.println(name);
        },str->{
            int age = Integer.parseInt(str.split(",")[1]);
            System.out.println(age);
        });

    }
    private static void printInfo(String[] strArray , Consumer<String> con1,Consumer<String> con2){
        for(String str:strArray){
            con1.andThen(con2).accept(str);
        }
    }

}

Predicate接口
    • Modifier and Type方法描述
      default Predicate<T>and(Predicate<? super T> other)返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑AND。
      static <T> Predicate<T>isEqual(Object targetRef)返回一个谓词,根据 Objects.equals(Object, Object)测试两个参数是否相等。
      default Predicate<T>negate()返回表示此谓词的逻辑否定的谓词。
      default Predicate<T>or(Predicate<? super T> other)返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑或。
      booleantest(T t)在给定的参数上评估这个谓词。
  • public interface Predicate<T>
    

    表示一个参数的谓词(布尔值函数)。

public class PredicateDemo2 {
    public static void main(String[] args){
        boolean b1 = checkString("hello",s->s.length() > 8);
        System.out.println(b1);
        boolean b2 = checkString("helloyutrew",s->s.length() > 8);
        System.out.println(b2);
        boolean b3 = checkString("hello",s->s.length() > 8,s->s.length()<15);
        System.out.println(b3);


    }
    //同一个字符串给出两种不同的判断条件按,最后把这两个判断的结果做逻辑与运算作为最后的结果
    private static boolean checkString(String s,Predicate<String> pre1,Predicate<String> pre2){
//        return pre1.test(s)&&pre2.test(s);
//        return pre1.and(pre2).test(s);
        //或运算
        return pre1.or(pre2).test(s);
    }
    //判断字符串是否满足要求
    private static boolean checkString(String s, Predicate<String> pre){
        return pre.test(s);
    }
}

练习

String[] strArray = {“小甘,80”,“小棠,56”,“小米,88”};

字符串数组中有多条信息,请通过Predicate接口的拼装将符合要求的字符除按筛选到集合ArrayList中,并遍历ArrayList集合要求,同时满足下列要求:姓名长度大于2,年龄大于33

public class PredicateTest {
    public static void main(String[] args){
        String[] strArray = {"小甘,80","小棠,56","小米,88"};
        ArrayList<String> array=myFilter(strArray,s-> s.split(",")[0].length() > 1,s->Integer.parseInt(s.split(",")[1]) > 33);
        for(String str:array){
            System.out.println(str);
        }
    }
    //通过Predicate接口的拼装将符合要求的字符除按筛选到集合ArrayList中
    private static ArrayList<String> myFilter(String[] strArray, Predicate<String> pre1, Predicate<String> pre2){
        //定义一个集合
        ArrayList<String> array = new ArrayList<String>();
        //遍历数组
        for(String str:strArray){
            if(pre1.and(pre2).test(str)){
                array.add(str);
            }
        }
        return array;
    }
}

Function接口

    • Modifier and Type方法描述
      default <V> Function<T,V>andThen(Function<? super R,? extends V> after)返回一个组合函数,首先将该函数应用于其输入,然后将 after函数应用于结果。
      Rapply(T t)将此函数应用于给定的参数。
      default <V> Function<V,R>compose(Function<? super V,? extends T> before)返回一个组合函数,首先将 before函数应用于其输入,然后将此函数应用于结果。
      static <T> Function<T,T>identity()返回一个总是返回其输入参数的函数。
  • @FunctionalInterface
    public interface Function<T,R>
    

    表示接受一个参数并产生结果的函数。

public class FunctionDemo {
    public static void main(String[] args){
        convert("100",s->Integer.parseInt(s));
        //方法调用
        convert("100",Integer::parseInt);
        convert(100,i->String.valueOf(i + 556));
        convert("100",s->Integer.parseInt(s),i->String.valueOf(i+988));
    }
    //定义一个方法,把一个字符串转换int类型,在控制台输出
    private static void convert(String s, Function<String,Integer> fun){
        int i = fun.apply(s);
        System.out.println(i);
    }
    //定义一个方法,把一个int类型的数据加上一个整数以后,转为字符串在控制台输出
    private static void convert(int i,Function<Integer,String> fun){
        String s = fun.apply(i);
        System.out.println(i);
    }

    //定义一个方法,把一个字符串转换int类型,把int类型的数据加上一个整数以后,转为字符串在控制台输出
    private static void convert(String s,Function<String,Integer> fun1,Function<Integer,String> fun2){
//        Integer i = fun1.apply(s);
//        String ss = fun2.apply(i);
//        System.out.println(ss);
        //把第一个函数的结果当作第二个函数的参数
        String ss =fun1.andThen(fun2).apply(s);
        System.out.println(ss);
    }

}

练习

String = “林夏琳,30”

将字符串截取得到数字年龄部分

将上一步的年龄字符串转换成为int类型的数据

将上一步的int数据加70,得到一个int结果,在控制台输出

通过哦function接口实现函数拼接

public class FunctionDemo2 {
//    String = "林夏琳,30"
//
//    将字符串截取得到数字年龄部分
//
//            将上一步的年龄字符串转换成为int类型的数据
//
//    将上一步的int数据加70,得到一个int结果,在控制台输出
//
//            通过哦function接口实现函数拼接
    public static void main(String[] args){
        String s = "林夏琳,30";
        convert(s,ss-> s.split(",")[1],
        ss->Integer.parseInt(ss)
        ,i-> i+70);
    }
    private static void convert(String s, Function<String,String> fun1,Function<String,Integer> fun2,Function<Integer,Integer> fun3){
        int i = fun1.andThen(fun2).andThen(fun3).apply(s);
        System.out.println(i);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值