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);
        }
    
    
    }
    

     

  • 相关阅读:
    最大子数组问题(分治策略实现)
    Solving the Detached Many-to-Many Problem with the Entity Framework
    Working With Entity Framework Detached Objects
    Attaching detached POCO to EF DbContext
    如何获取qq空间最近访问人列表
    Health Monitoring in ASP.NET 2.0
    problem with displaying the markers on Google maps
    WebMatrix Database.Open… Close() and Dispose()
    Accessing and Updating Data in ASP.NET: Retrieving XML Data with XmlDataSource Control
    Create web setup project that has crystal reports and sql script run manually on client system
  • 原文地址:https://www.cnblogs.com/lsswudi/p/11449151.html
Copyright © 2011-2022 走看看