Java学习笔记(五十七)—— 函数式接口

概述
  • 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
  • 函数式接口适用于函数式编程的场景,Java中的函数式百年城体现就是Lambda,所以函数式接口就是适用于Lambda使用的接口。Java中的Lambda可以被当中匿名内部类的语法糖
  • 语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
格式
  • 只要确保接口中有且仅有一个抽象方法即可
    @FunctionalInterface   // 这个注解检测这个接口是否式函数式接口
    修饰符 interface 接口名称 {
    	public abstract 返回值类型 方法名称(可选参数信息)
    	// 其他非抽象方法
    }
    
    // 接口中的抽象方法的public abstract可省略
    修饰符 interface 接口名称 {
    	返回值类型 方法名称(可选参数信息)
    	// 其他非抽象方法
    }
    
使用
  • 函数式接口作为方法的参数

    public static void main(String[] args) {
        show(new MyFunctionalInterface() {
            @Override
            public void method() {
                System.out.println("world");
            }
        });
        // Lambda表达式
        show(()->{
            System.out.println("nihao");
        });
    }
    public static void show(MyFunctionalInterface myInter){
        myInter.method();
    }
    
  • 使用Lambda作为方法的参数和返回值

        public static void startThread(Runnable  run){
            // 开启多线程
            new Thread(run).start();
        }
    
        public static void main(String[] args) {
            startThread(()->{
                System.out.println("开启多线程:"+Thread.currentThread().getName());
            });
        }
    
        public static Comparator<String> getComparator(){
            /*return new Comparator<String>() {
                @Override
                public int compare(String s1, String s2) {
                    return s2.length()-s1.length();
                }
            };*/
            /*return (String s1,String s2)->{
               return s2.length()-s1.length();
            };*/
            return (s1,s2)->s2.length()-s1.length();
        }
    
        public static void main(String[] args) {
            String[] sArr ={"aaa","b","cccda","da"};
            getComparator();
            Arrays.sort(sArr,getComparator());
            System.out.println(Arrays.toString(sArr));
        }
    
常用的函数式接口
  • Supplier接口
  1. public interface Supplier<T>,接口仅包含一个无参的构造方法:T get​()。用来获取一个泛型参数指定类型的对象数据

  2. 被称为生产型接口

    public static void main(String[] args) {
       String s= getString(() ->{
          return "helloworld";
        });
        System.out.println(s); // helloworld
    }
    public static String getString(Supplier<String> sup){
        return sup.get();
    }
    
    // 求数组元素的最大值
    public static int getMax(Supplier<Integer> sup){
        return sup.get();
    }
    public static void main(String[] args) {
        int[] arrInt={100,12,56,430,160,32};
        int result= getMax(()->{
            int max=arrInt[0];
            for (int val : arrInt) {
                if(val>max){
                    max=val;
                }
            }
            return max;
        });
        System.out.println(result);
    }
    
  • Consumer接口
  1. public interface Consumer<T>表示接受单个输入参数并且不返回结果的操作。 与大多数其他功能接口不同, Consumer预期通过副作用进行操作。

  2. 是一个消费型接口,泛型执行什么类型,就可以使用accpet方法消费什么类型的数据

  3. 方法:void accept​(T t) 对给定的参数执行此操作。

    public static void method(String name, Consumer<String> con){
        con.accept(name);
    }
    public static void main(String[] args) {
        method("hello",(name)->{
            System.out.println(name); // hello
            String reName=new StringBuilder(name).reverse().toString();
            System.out.println(reName); // olleh
        });
    }
    
  4. default Consumer<T> andThen​(Consumer<? super T> after) 返回一个组成的 Consumer ,依次执行此操作,然后执行 after操作。

    public static void method(String s, Consumer<String> con1,Consumer<String> con2){
        con1.andThen(con2).accept(s);
    }
    public static void main(String[] args) {
        method("hello",(s)->{
            System.out.println(s.toUpperCase()); // HELLO
        },(s)->{
            System.out.println(s+"world"); // helloworld
            System.out.println(s.toLowerCase()); // hello
        });
    }
    
    public static void main(String[] args) {
        String[] arrStr={"迪丽热巴,18","古力娜扎,98","马尔扎哈,67"};
        /*
        	打印结果:
    			姓名:迪丽热巴 年龄:18
    			姓名:古力娜扎 年龄:98
    			姓名:马尔扎哈 年龄:67
    	*/
        printInfo(arrStr,(s)->{
            String name= s.split(",")[0];
            System.out.print("姓名:"+name);
        },(s)->{
            String age= s.split(",")[1];
            System.out.println(" 年龄:"+age);
        });
    }
    public static void printInfo(String[] arr, Consumer<String> con1,Consumer<String> con2){
        for (String s : arr) {
            con1.andThen(con2).accept(s);
        }
    }
    
  • Predicate接口
  1. 我们需要对某种类型的数据进行判断,从而得到一个Boolean值的结果。这时可以用public interface Predicate<T>接口1. 我们需要对某种类型的数据进行判断,从而得到一个Boolean值的结果。这时可以用public interface Predicate<T>接口

  2. 抽象方法:boolean test​(T t) ,在给定的参数上评估这个谓词。

    public static boolean checkString(String s, Predicate<String> pre){
        return pre.test(s);
    }
    
    public static void main(String[] args) {
        String str="abcde";
        boolean b=checkString(str,(s)->{
           return  str.length()>4;
        });
        System.out.println(b);
    }
    
  3. 默认方法:
    3.1 and

    default Predicate<T> and​(Predicate<? super T> other) 
    	返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑AND。 
    
    public static boolean checkString(String s, Predicate<String> pre1,Predicate<String> pre2){
       return pre1.and(pre2).test(s);
    }
    
    public static void main(String[] args) {
        boolean b=checkString("abcd",(s)->{
            return s.length()>3;
        },(s)->{
            // return s.indexOf("a") !=-1;
            return s.contains("a");
        });
        System.out.println(b); // true
    }
    

    3.2 or

    default Predicate<T> or​(Predicate<? super T> other) 
    	返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑或。  
    
    public static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2){
        return pre1.or(pre2).test(s);
    }
    
    public static void main(String[] args) {
        boolean b=checkString("abcd",(s)->{
            return s.length()>6;
        },(s)->{
    
            return s.contains("a"); // 是否包含a
        });
        System.out.println(b); // true
    }
    

    3.3 negate

    default Predicate<T> negate​() 返回表示此谓词的逻辑否定的谓词。
    
    public static boolean checkString(String s, Predicate<String> pre){
        return pre.negate().test(s);
    }
    public static void main(String[] args) {
        boolean b=checkString("abcd",(s)->{
            return s.length()>3;
        });
        System.out.println(b); // false
    }
    

    3.4 例:集合信息筛选

    public static void main(String[] args) {
        String[] arrStr={"迪丽热巴,女","古力娜扎,女","马尔扎哈,男","赵薇,女"};
         ArrayList<String> list=filter(arrStr,(s)->{
            return s.split(",")[0].length()==4;
        },(s)->{
            return s.split(",")[1].equals("女");
        });
        System.out.println(list); // [迪丽热巴,女, 古力娜扎,女]
    }
    public static ArrayList<String> filter(String[] arr, Predicate<String> pre1,Predicate<String> pre2){
        ArrayList<String> list=new ArrayList<>();
        for (String s : arr) {
            boolean b=pre1.and(pre2).test(s);
            if(b){
                list.add(s);
            }
        }
        return list;
    }
    
  • Function接口
  1. public interface Function<T,R>,该接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后缀称为后置条件

  2. 抽象方法:R apply​(T t) ,将此函数应用于给定的参数。 根据T类型获取到类型R的结果

    public static void main(String[] args) {
        change("12",(s)->{
            return Integer.parseInt(s); // 将字符串类型数字转换为Integer类型
        });
    }
    public static void change(String s, Function<String,Integer> fun){
        Integer in=fun.apply(s);
        System.out.println(in); // 12
    }
    
  3. 默认方法:

    default <V> Function<T,V> andThen​(Function<? super R,? extends V> after) 
    	返回一个组合函数,首先将该函数应用于其输入,然后将 after函数应用于结果。  
    
    public static void main(String[] args) {
        change("123",(s)->{
            Integer i=Integer.parseInt(s)+10;
            return i;
        },(i)->{
            return i+"";
        });
    }
    public static void change(String s, Function<String,Integer> fun1,Function<Integer,String> fun2){
        String result=fun1.andThen(fun2).apply(s);
        System.out.println(result);
    }
    
  4. 练习
    4.1 自定义函数模型拼接

    public static void main(String[] args) {
        String s="zhaosan,20";
        int i=change(s,(s1)->{
           return s1.split(",")[1];
        },(s2)->{
            return Integer.parseInt(s2);
        },(in)->{
            return in+100;
        });
        System.out.println(i);
    }
    public static int change(String s,
                             Function<String,String> fun1,
                             Function<String,Integer> fun2,
                             Function<Integer,Integer> fun3){
        return fun1.andThen(fun2).andThen(fun3).apply(s);
    }
    
发布了113 篇原创文章 · 获赞 1 · 访问量 950

猜你喜欢

转载自blog.csdn.net/weixin_44876003/article/details/103371873