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

      最近刚好有空给大家整理下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

  • 相关阅读:
    Oracle基础知识整理
    linux下yum安装redis以及使用
    mybatis 学习四 源码分析 mybatis如何执行的一条sql
    mybatis 学习三 mapper xml 配置信息
    mybatis 学习二 conf xml 配置信息
    mybatis 学习一 总体概述
    oracle sql 语句 示例
    jdbc 新认识
    eclipse tomcat 无法加载导入的web项目,There are no resources that can be added or removed from the server. .
    一些常用算法(持续更新)
  • 原文地址:https://www.cnblogs.com/dengpengbo/p/15146478.html
Copyright © 2011-2022 走看看