zoukankan      html  css  js  c++  java
  • 函数式接口

    1.1函数式接口概述
    函数式接口:有且仅有一个抽象方法的接口
    Java中的函数式编程体现就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口
    只有确保接口中有且仅有一个抽象方法, Java中的L ambda才能顺利地进行推导

    如何检测一个接口是不是函数式接口呢?
    @Functionallnterface放在接口定义的上方:

    如果接口是函数式接口,编译通过;如果不是,编译失败


    注意
    ●我们自己定义 函数式接口的时候,@Functionallnterface是可选的, 就算我不写这个注解,只要保证满足函数式接口定
    义的条件,也照样是函数式接口。但是,建议加上该注解



    1.2函数式接口作为方法的参数
    需求
    ● 定义一个类(RunnableDemo),在类中提供两个方法
    一个方法是: startThread(Runnable r)方法参数Runnable是一 个函数式接口
    一个方法是主方法,在主方法中调用startThread方法
    如果方法的参数是一个函数式接口, 我们可以使用 ambda表达式作为参数传递
    ●startThread(0 -> System.out.println(Thread.currentThread0.getName0 + "线程启动了));

    package com.Test01;
    /*
        定义一个类(RunnableDemo),在类中提供两个方法
        一个方法是: startThread(Runnable r) 方法参数Runnable是一 个函数式接口
        一个方法是主方法,在主方法中调用startThread方法
    
     */
    
    public class RunnableDemo {
        public static void main(String[] args) {
            //在主方法中调用startThread方法
    
            //采用匿名内部类的方式
            startThread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "线程启动了");
                    
    
                }
            });
          startThread (() -> System.out.println(Thread.currentThread().getName() + "线程启动了"));
      } private static void startThread(Runnable r) { // Thread t = new Thread(r); // t.start(); new Thread(r).start(); } }

    1.3函数式接口作为方法的返回值
    需求●定义一个类(ComparatorDemo), 在类中提供两个方法
    一个方法是: Comparator <String> getComparator()方法返回值C omparator是一个函数式接口
    一个方法是主方法,在主方法中调用getComparator方法


    如果方法的返回值是一个函数式接口,我们可以使用L ambda表达式作为结果返回
    ●private static Comparator <String> getComparator({
    return (s1, s2) -> s1.length( - s2.length0;
    }

    package com.Test01;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    
    public class CommparatorDemo {
        public static void main(String[] args) {
            //构造使用场景
    
            //定义集合 存储字符串元素
            ArrayList<String> array = new ArrayList<String>();
            array.add("cccc");
            array.add("aaa");
            array.add("dd");
            array.add("b");
            System.out.println("排序前:" + array);
            Collections.sort(array, getComparator());
            System.out.println("排序后:" + array);
    
    
        }
    
        public static Comparator<String> getComparator() {
            //返回该接口的实现类对象
            //首先采用匿名内部类的方式
    //        Comparator<String> comp = new Comparator<String>() {
    //            @Override
    //            public int compare(String s1, String s2) {
    //                return s1.length()-s2.length();
    //            }
    //        };
    //        return comp;
    //        return new Comparator<String>() {
    ////            @Override
    ////            public int compare(String s1, String s2) {
    ////                return s1.length() - s2.length();
    ////            }
    ////        };
    //        return (String s1,String s2) ->{
    //            return s1.length()-s2.length();
    //        };
            return (s1, s2) -> s1.length() - s2.length();
    
        }
    }

    常用的4个函数式接口

    Java 8在java.util.function包下预定义了大量的函数式接口供我们使用
    我们重点来学习下面的4个接口
    ●Supplier接口
    ●Consumer接口
    ●Predicate接口、
    ●Function接口


    1,Supplier接口

    @FunctionalInterface
    public interface Supplier<T>
    代表结果供应商。

    没有要求每次调用供应商时都会返回新的或不同的结果。

    这是一个functional interface的功能方法是get()

    package com.Test01;
    /*
    Supplier<T>:包含一个无参的方法
    T get ():获得结果
    该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
    Supplier<T>接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供使用
    
     */
    
    import java.util.function.Supplier;
    
    public class SupplierDemo {
        public static void main(String[] args) {
    //        String s = getString(() -> {
    //            return "林青霞";
    //        });
            String s = getString(() -> "林青霞");
            System.out.println(s);
    
        }
        private static String getString(Supplier<String> sup) {
            return sup.get();
        }
    }

    package com.Test01;
    
    import java.util.function.Supplier;
    
    public class SupplierTest {
        public static void main(String[] args) {
            //定义一个数组
            int[] arr = {15, 20, 3, 65, 45, 6};
    
            int x = getMax(() -> {
                int Max = arr[0];
                for (int i = 0; i < arr.length; i++) {
                    if (Max < arr[i]) {
                        Max = arr[i];
                    }
    
                }
                return Max;
            });
            System.out.println(x);  
        }
    
        private static int getMax(Supplier<Integer> sup) {
            return sup.get();
        }
    }

    ,2,Consumer接口

    @FunctionalInterface
    public interface Consumer<T>
    表示接受单个输入参数并且不返回结果的操作

    1.6 Consumer接口
      Consumer<T>:包含两个方法
    void accept(T t): 对给定的参数执行此操作
    default Consumer <T> andThen(Consumer after):返回一个组合的Consumer,依次执行此操作,然后执行after操作
    ●Consumer<T>接口也被称为消费型接口,它消费的数据的数据类型由泛型指定

    package com.Test01;
    /*
    Consumer<T>:包含两个方法
    void accept (T t): 对给定的参数执行此操作
    default Consumer<T> andThen (Consumer after): 返回一个组合的Consumer, 依次执行此操作,然后执行after操作
    Consumer<T>接口也被称为消费型接口,它消费的数据的数据类型由泛型指定
    /
    
     */
    
    import java.util.function.Consumer;
    
    public class ConsumerDemo {
        public static void main(String[] args) {
    //        Lamada表达式
    //        OperatorString("林青霞",(s) -> {
    //            System.out.println(s);
    //        });
    
    //        OperatorString("林青霞", (s) -> System.out.println(s));
            //方法引用
            OperatorString("林青霞", System.out::println);
        }
    
        //定义一个方法,消费一个字符串数据
        private static void OperatorString(String name, Consumer<String> con) {
            con.accept(name);
        }
    }
    Consumer练习
    String[] strArray = {"林青霞, 30",”张曼玉,35", ”王祖贤, 33"}; 字符串数组中有多条信息,请按照格式: "姓名: Xx,年龄: xX"的格式将信息打印出来 要求: 把打印姓名的动作作为第- -个Consumer接口的L ambdo实例 把打印年龄的动作作为第二个Consumer接口的L ambda实例 将两个Consumer接口按照顺序组合到一起使用




    package com.Test01;
    /**/
    
    import java.util.function.Consumer;
    
    public class ConsumerDemo02 {
        public static void main(String[] args) {
            String[] strArray = {"林青霞,30", "张曼玉,35", "王祖贤,33"};
            printString(strArray, (String str) -> {
                String name = str.split(",")[0];
                System.out.print("姓名:" + name);
            }, (String str) -> {
                int age = Integer.parseInt(str.split(",")[1]);
                System.out.println(",年龄:" + age);
            });
    
        }
    
        private static void printString(String[] strArray, Consumer<String> con1, Consumer<String> con2) {
            for (String s : strArray) {
                con1.andThen(con2).accept(s);
            }
        }
    }

    3, Predicate接口

    @FunctionalInterface
    public interface Predicate<T>
    表示一个参数的谓词(布尔值函数)。


    Predicate<T>:常用的四个方法
    ●boolean test(T t):对给定的参数进行判断(判断逻辑由L ambda表达式实现),返回一个布尔值
    ●default Predicate<T> negate():返回-一个逻辑的否定,对应逻辑非
    ●default Predicate<T> and(Predicate other):返回一个组合判断,对应短路与
    ●default Predicate<T> or(Predicate other):返回一个组合判断,对应短路或

    -----------   - --  - - - - - - - - -- - - - - - - - - - - - - -- - -   -- - - - - - --

    Predicate<T>接口通常用于判断参数是否满足指定的条件


    ●boolean test(T t):对给定的参数进行判断(判断逻辑由L ambda表达式实现),返回一个布尔值
    ●default Predicate<T> negate():返回-一个逻辑的否定,对应逻辑非

    如下演示

    package com.Test01;
    /*
    Predicate<T>:常用的四个方法
    boolean test (T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
    default Predicate<T> negate (): 返回一个逻辑的否定,对应逻辑非
    Predicate<T>接口通常用于判断参数是否满足指定的条件
    
     */
    
    
    import java.util.function.Predicate;
    
    public class PredicateDemo01 {
        public static void main(String[] args) {
    //        boolean b = checkString("hello", (String s) -> {
    //            return s.length() > 8;
    //        });
            boolean b = checkString("hello", s -> s.length() > 8);
            System.out.println(b);
    
        }
    
        //判断给定的字符串是否满足要求
        private static boolean checkString(String s, Predicate<String> pre) {
    //        return pre.test(s);
    //        return !pre.test(s);//不是标准非
            return pre.negate().test(s);//接口提供的逻辑非的操作
    
        }
    }

    ●default Predicate<T> and(Predicate other):返回一个组合判断,对应短路与
    ●default Predicate<T> or(Predicate other):返回一个组合判断,对应短路或

    如下演示

    package com.Test01;
    /*
    /*
    Predicate<T>:
    default Predicate<T> and (Predicate other): 返回一个组合判断,对应短路与
    default Predicate<T> or (Predicate other): 返回-一个组合判断,对应短路或
    
     */
    
    import java.util.function.Predicate;
    
    public class PredicateDemo02 {
        public static void main(String[] args) {
            boolean b1 = checkString("hello", s -> s.length() > 8);
            //System.out.println(b1);
            boolean b2 = checkString("helloworld", s -> s.length() > 8);
            //System.out.println(b2);
            boolean b3 = checkStringandor("helloworld", s -> s.length() > 11, s -> s.length() < 15);
            System.out.println(b3);
        }
    
        //同一个字符串给出两个不同的判断条件,最后把这两个判断的结果做逻辑与运算的结果作为最终的结果
        private static boolean checkStringandor(String s, Predicate<String> pre1, Predicate<String> pre2) {
    //        boolean b1 = pre1.test(s);
    ////        boolean b2 = pre2.test(s);
    ////        boolean b = b1 || b2;
    ////        return b;
            return pre1.or(pre2).test(s);//return pre1.and(pre2).test(s);
        }
    
        private static boolean checkString(String s, Predicate<String> pre) {
            //判定给定的字符串是否满足要求
            return pre.test(s);
    //
    
        }
    
    }

     Predicate练习
    String[ strArray= {"林青霞30", "柳岩,34", "张曼玉,35",“貂蝉,31", "王祖贤,33"};
    ●字符串数组中有多条信息, 请通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,并遍历ArrayList集合
    ●同时满足如下要求:姓名长度大于2;年龄大于33

    分析
    有两个判断条件,所以需要使用两个Predicate接口,对条件进行判断
    必须同时满足两个条件,所以可以使用and方法连接两个判断条件

    package com.Test01;
    /*
    String[] strArray = {"林青霞,30”,“柳岩,34", "张曼玉,35", "貂蝉,31","王祖贤,33"};
    字符串数组中有多条信息,请通过Predicate接口的拼装将符合要求的字符串筛选到集合Arraylist中,并遍历Arraylist集合
    要求:同时满足如下要求
    1:姓名长度大于2
    2:年龄大于33
    分析:
    1:有两个判断条件,所以需要使用两个Predicate接口,对条件进行判断
    2:必须同时满足两个条件,所以可以使用and方法连接两个判断条件
    
     */
    
    import java.util.ArrayList;
    import java.util.function.Predicate;
    
    public class PredicateTest {
        public static void main(String[] args) {
            String[] strArray = {"林青霞,30", "柳岩,34", "张曼玉,35", "貂蝉,31", "王祖贤,33"};
            ArrayList<String> stringArrayList = myfilter(strArray, s -> s.split(",")[0].length() > 2, s -> Integer.parseInt(s.split(",")[1]) > 33);
            for (String s : stringArrayList) {
                System.out.println(s);
            }
        }
    
        //    请通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,
        private static ArrayList<String> myfilter(String[] arr, Predicate<String> pre1, Predicate<String> pre2) {
            //定义一个集合
            ArrayList<String> array = new ArrayList<String>();
            for (String s : arr) {
                String name = s.split(",")[0];
                int age = Integer.parseInt(s.split(",")[1]);
                if (pre1.and(pre2).test(s)) {
                    array.add(s);
                }
            }
    
            return array;
    
        }
    
    }

    4, Function接口

    @FunctionalInterface
    public interface Function<T,R>
    表示接受一个参数并产生结果的函数


    Function<T,R>:常用的两个方法
    R apply(Tt):将此函数应用于给定的参数
    default <V> Function andThen(Function after):返回-个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
    Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值

    package com.Test01;
    /*
    Function<T,R>:常用的两个方法
    R apply (T t):将此函数应用于给定的参数
    default <V> Function andThen (Function after): 返回一个组合函数,首先将该函数应用于输入,然后将ofter函数应用于结果
    Function<T, R>接口通常用于对参数进行处理,转换(处理逻辑由L ambda表达式实现),然后返回一一个新的值
    
     */
    
    import java.util.function.Function;
    
    public class FunctionDemo {
    
        public static void main(String[] args) {
    //        Convert("100", (String s) -> {
    //            return Integer.parseInt(s);
    //        });
            Convert("100", s -> Integer.parseInt(s));
            Convert("100", Integer::parseInt);
            Convert(100, i-> String.valueOf(i+566));
            Convert("300",s->Integer.parseInt(s),i->String.valueOf(i+300));
    
        }
    
        //定义一个方法,把一个字符串转换int类型,在控制台输出
        private static void Convert(String s, Function<String, Integer> fun) {
    //        Integer i = fun.apply(s);
            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(s);
        }
    
        //定义一个方法,把一个字符串转换int类型,把int类型的数据加上一一个整数之后,
        // 转为字符串在控制台输出
        private static void Convert(String s,Function<String,Integer> fun1,Function<Integer,String> fun2) {
    //        Integer i = fun1.apply(s);
    //        String s1 = fun2.apply(i);
    //        System.out.println(s1);
            String s1 = fun1.andThen(fun2).apply(s);
            System.out.println(s1);
        }
    
    
    }

    练习

    package com.Test01;
    /*
    ●Strings = "林青霞30";
    ●请按照我指定的要求进行操作:
    1:将字符串截取得到数字年龄部分string
    2:将上一步的年龄字符串转换成为int类型的数据int
    3:将上一步的int数据加70,得到个int结果,在控制台输出
    ●请通过Function接口来实现函数拼接
    */
    
    import java.util.function.Function;
    
    public class FunctionDemo02 {
        public static void main(String[] args) {
            Convert("林青霞30",s->  Integer.parseInt(s.substring(3,5))+70);  //也可以按照题目的要求一步一步来
    
        }
    
        private static void Convert(String s, Function<String, Integer> fun) {
            Integer i = fun.apply(s);
            System.out.println(i);
        }
    
    
    }
    

     

  • 相关阅读:
    解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)
    解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译)
    解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)
    解剖SQLSERVER 第十五篇 SQLSERVER存储过程的源文本存放在哪里?(译)
    解剖SQLSERVER 第七篇 OrcaMDF 特性概述(译)
    解剖SQLSERVER 第八篇 OrcaMDF 现在支持多数据文件的数据库(译)
    解剖SQLSERVER 第九篇 OrcaMDF现在能通过系统DMVs显示元数据(译)
    解剖SQLSERVER 第十篇 OrcaMDF Studio 发布+ 特性重温(译)
    解剖SQLSERVER 第十一篇 对SQLSERVER的多个版本进行自动化测试(译)
    解剖SQLSERVER 第三篇 数据类型的实现(译)
  • 原文地址:https://www.cnblogs.com/lsswudi/p/11449151.html
Copyright © 2011-2022 走看看