• 隔壁老王都熟练使用函数式接口了,你还在等什么?(快来收藏)


      最近刚好有空给大家整理下JDK8的特性,这个在实际开发中的作用也是越来越重了,本文重点讲解下函数式接口内容。一起来进阶提升吧:463257262

    函数式接口

    1.函数式接口的由来

      我们知道使用Lambda表达式的前提是需要有函数式接口,而Lambda表达式使用时不关心接口名,抽象方法名。只关心抽象方法的参数列表和返回值类型。因此为了让我们使用Lambda表达式更加的方法,在JDK中提供了大量常用的函数式接口

    package com.bobo.jdk.fun;
    
    public class Demo01Fun {
    
        public static void main(String[] args) {
            fun1((arr)->{
                int sum = 0 ;
                for (int i : arr) {
                    sum += i;
                }
                return sum;
            });
        }
    
        public static void fun1(Operator operator){
            int[] arr = {1,2,3,4};
            int sum = operator.getSum(arr);
            System.out.println("sum = " + sum);
        }
    }
    
    /**
     * 函数式接口
     */
    @FunctionalInterface
    interface Operator{
    
        int getSum(int[] arr);
    }
    
    

    2. 函数式接口介绍

      在JDK中帮我们提供的有函数式接口,主要是在 java.util.function 包中。

    2.1 Supplier

      无参有返回值的接口,对于的Lambda表达式需要提供一个返回数据的类型。

    @FunctionalInterface
    public interface Supplier<T> {
    
        /**
         * Gets a result.
         *
         * @return a result
         */
        T get();
    }
    

    使用:

    /**
     * Supplier 函数式接口的使用
     */
    public class SupplierTest {
    
        public static void main(String[] args) {
            fun1(()->{
                int arr[] = {22,33,55,66,44,99,10};
                // 计算出数组中的最大值
                Arrays.sort(arr);
                return arr[arr.length-1];
            });
        }
    
        private static void fun1(Supplier<Integer> supplier){
            // get() 是一个无参的有返回值的 抽象方法
            Integer max = supplier.get();
            System.out.println("max = " + max);
    
        }
    }
    

    2.2 Consumer

      有参无返回值得接口,前面介绍的Supplier接口是用来生产数据的,而Consumer接口是用来消费数据的,使用的时候需要指定一个泛型来定义参数类型

    @FunctionalInterface
    public interface Consumer<T> {
    
        /**
         * Performs this operation on the given argument.
         *
         * @param t the input argument
         */
        void accept(T t);
    }
    

    使用:将输入的数据统一转换为小写输出

    public class ConsumerTest {
    
        public static void main(String[] args) {
            test(msg -> {
                System.out.println(msg + "-> 转换为小写:" + msg.toLowerCase());
            });
        }
    
        public static void test(Consumer<String> consumer){
            consumer.accept("Hello World");
        }
    }
    

    默认方法:andThen

      如果一个方法的参数和返回值全部是Consumer类型,那么就可以实现效果,消费一个数据的时候,首先做一个操作,然后再做一个操作,实现组合,而这个方法就是Consumer接口中的default方法 andThen方法

        default Consumer<T> andThen(Consumer<? super T> after) {
            Objects.requireNonNull(after);
            return (T t) -> { accept(t); after.accept(t); };
        }
    

    具体的操作

    public class ConsumerAndThenTest {
    
        public static void main(String[] args) {
            test2(msg1->{
                System.out.println(msg1 + "-> 转换为小写:" + msg1.toLowerCase());
            },msg2->{
                System.out.println(msg2 + "-> 转换为大写:" + msg2.toUpperCase());
            });
        }
    
    
        public static void test2(Consumer<String> c1,Consumer<String> c2){
            String str = "Hello World";
            //c1.accept(str); // 转小写
            //c2.accept(str); // 转大写
            //c1.andThen(c2).accept(str);
            c2.andThen(c1).accept(str);
        }
    }
    

    2.3 Function

      有参有返回值的接口,Function接口是根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。有参数有返回值。

    @FunctionalInterface
    public interface Function<T, R> {
    
        /**
         * Applies this function to the given argument.
         *
         * @param t the function argument
         * @return the function result
         */
        R apply(T t);
    }
    

    使用:传递进入一个字符串返回一个数字

    public class FunctionTest {
    
        public static void main(String[] args) {
            test(msg ->{
                return Integer.parseInt(msg);
            });
        }
    
        public static void test(Function<String,Integer> function){
            Integer apply = function.apply("666");
            System.out.println("apply = " + apply);
        }
    }
    

    默认方法:andThen,也是用来进行组合操作,

        default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
            Objects.requireNonNull(after);
            return (T t) -> after.apply(apply(t));
        }
    
    public class FunctionAndThenTest {
    
        public static void main(String[] args) {
            test(msg ->{
                return Integer.parseInt(msg);
            },msg2->{
                return msg2 * 10;
            });
        }
    
        public static void test(Function<String,Integer> f1,Function<Integer,Integer> f2){
            /*Integer i1 = f1.apply("666");
            Integer i2 = f2.apply(i1);*/
            Integer i2 = f1.andThen(f2).apply("666");
            System.out.println("i2:" + i2);
    
        }
    }
    

      默认的compose方法的作用顺序和andThen方法刚好相反

      而静态方法identity则是,输入什么参数就返回什么参数

    2.4 Predicate

      有参且返回值为Boolean的接口

    @FunctionalInterface
    public interface Predicate<T> {
    
        /**
         * Evaluates this predicate on the given argument.
         *
         * @param t the input argument
         * @return {@code true} if the input argument matches the predicate,
         * otherwise {@code false}
         */
        boolean test(T t);
    }
    

    使用:

    public class PredicateTest {
    
        public static void main(String[] args) {
            test(msg -> {
                return msg.length() > 3;
            },"HelloWorld");
        }
    
        private static void test(Predicate<String> predicate,String msg){
            boolean b = predicate.test(msg);
            System.out.println("b:" + b);
        }
    }
    

      在Predicate中的默认方法提供了逻辑关系操作 and or negate isEquals方法

    package com.bobo.jdk.fun;
    
    import java.util.function.Predicate;
    
    public class PredicateDefaultTest {
    
        public static void main(String[] args) {
            test(msg1 -> {
                return msg1.contains("H");
            },msg2 -> {
                return msg2.contains("W");
            });
        }
    
        private static void test(Predicate<String> p1,Predicate<String> p2){
            /*boolean b1 = predicate.test(msg);
            boolean b2 = predicate.test("Hello");*/
            // b1 包含H b2 包含W
            // p1 包含H 同时 p2 包含W
            boolean bb1 = p1.and(p2).test("Hello");
            // p1 包含H 或者 p2 包含W
            boolean bb2 = p1.or(p2).test("Hello");
            // p1 不包含H
            boolean bb3 = p1.negate().test("Hello");
            System.out.println(bb1); // FALSE
            System.out.println(bb2); // TRUE
            System.out.println(bb3); // FALSE
        }
    }
    
    

    ~好了,函数式接口的内容就介绍到这儿,如果对你有帮助,欢迎点赞关注加收藏哦 V_V

  • 相关阅读:
    Wannafly挑战赛14 F.细胞
    D 勤奋的杨老师(二)(最小割)
    三分算法求最值
    初识最大流
    初识数据结构
    决策型DP
    哈希表
    【BZOJ】1878: [SDOI2009]HH的项链 (主席树)
    【HDU】1520 Anniversary party(树形dp)
    【UVa】1606 Amphiphilic Carbon Molecules(计算几何)
  • 原文地址:https://www.cnblogs.com/dengpengbo/p/15146478.html
Copyright © 2020-2023  润新知