美文网首页
JAVA8新特性之函数式接口使用与学习

JAVA8新特性之函数式接口使用与学习

作者: 先生zeng | 来源:发表于2020-11-12 01:38 被阅读0次

    函数式接口

    函数式接口是Java8引用的一个新特性,是一种特殊的接口 SAM类型的接口(Single Abstract Method)。但是它还是一个接口,只是有些特殊罢了。函数式接口的出现主要是为了配合Java8的另一个新特性Lamdba表达式来使用。

    接口中只有一个抽象方法
    接口中面可以加一个注解@FunctionalInterface来检查接口中的方法是不是只有一个抽象方法
    在接口里面可以加入 默认方法 和 静态方法
    函数式接口也可以继承,但是继承的时候,抽象方法必须一样
    函数式接口重写父类的的方法,并不会计入到自己的抽象方法中。

    在JAV8中提供了几种函数式接口,同时,我们自己也可以自定义函数式接口,只要满足他的定义。示例如下:

    //加入这个注解是为了检测接口中是否符合函数式接口的要求
    @FunctionalInterface
    public interface MyFunctionInterction {
        //唯一的抽象方法
        void absoluMethod();
    
        //重写Object的方法
        @Override
        String toString();
    
        //默认方法
        default void defaultMethod() {
            System.out.println("默认方法");
        }
    
        //静态方法
        static void stativMethod() {
            System.out.println("静态方法");
        }
    }
    

    使用例子:

    public class TestFunctionIntection {
        public static void main(String[] args) {
            TestFunctionIntection testFunctionIntection = 
                    new TestFunctionIntection();
            testFunctionIntection.test(
                    //Lamdba表达式的简单使用
                    () -> System.out.println("函数式接口里面的抽象方法"));   // 里面会去调用自己自定义的那个抽象方法。
        }
    
        /**
         * 自己定义的一个方法,并使用自定义的一个消费类型的函数式接口
         * @param myFunctionInterction
         */
        public void test(MyFunctionInterction 
                                 myFunctionInterction) {
    
            //函数式接口里面的抽象方法
            myFunctionInterction.absoluMethod();
    
            //默认方法
            myFunctionInterction.defaultMethod();
    
            //静态方法
            MyFunctionInterction.stativMethod();
        }
    }
    

    JAVA8提供的4个比较核心的函数式接口

    这么说可能不太明白,可以看下具体的代码示例以及说明:

    1.Consumer 消费型函数接口(没有返回值)

    package com.java8.test.demo;
    
    public class TestFunctionInterface {
    
        //Consumer<T> 消费型接口 实例一
        @Test
        public void test1() {
            Consumer<String> consumer = (x) -> System.out.println(x);
            consumer.accept("消费型接口,没有返回值!");
        }
        //输出:消费型接口,没有返回值!
    
    //Consumer<T> 消费型接口  实例二
        @Test
        public void test2() {
            //定义一个消费型接口,只输出输入的内容
            Consumer<String> consumer = (x) -> System.out.println(x);
            //在输入的内容后面加上·--加上了默认方法·
            Consumer<String> consumer2 = (x) -> System.out.println(x + "--加上了默认方法");
            //执行顺序  先执行 accept 后面执行 addThen(然后) 
            consumer.andThen(consumer2).accept("消费型接口,没有返回值!");
        }
        //输出:消费型接口,没有返回值                     (accept输出的值) 
        //输出:消费型接口,没有返回值 !--加上了默认方法 (addThen输出的值)
    

    有一个问题哈,为什么addThen会先执行accept(T)后再执行addThen呢,我们可以看andThen()方法的源码

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

    2.Supplier 供给型函数接口(主要应用于new 新对象)

       //供给型接口
        @Test
        public void test2() {
            Supplier<String> supplier = () -> "主要的作用就是创建对象!";
            String s = supplier.get();
            System.out.println(s);
        }
        //输出:主要的作用就是创建对象!
    

    看下面代碼示例:

    //供给型接口,这个方法可以用在工厂方法中
        @Test
        public void test2() {
            //跟据一个字符串创建对象
            Supplier<String> supplier = () -> "主要的作用就是创建对象!";
            //获取一个对象
            String s = supplier.get();
            //获取两个以象
            String s1 = supplier.get();
            //两个对象内容一样
            System.out.println(s.equals(s1));
            System.out.println(s);
            //用方法引用的方式创建一个对象
            Supplier<SupplierTest> testSupplier = SupplierTest::new;
            //用new的方式创建一个对象
            Supplier<SupplierTest> supplierTestSupplier = () -> new SupplierTest("张三");
            //可以通过supplierTestSupplier 来获取一个对象,并且可以调用里面的方法
            String name = supplierTestSupplier.get().getName();
            System.out.println(name);
        }
        //输出:true
        //输出:主要的作用就是创建对象!
        //输出:张三
    

    Supplier< T >接口类型只有一个方法签名。T get()方法,没有默认方法。

    3.Function 函数型函数接口(Function<T,R> T 接收的参数,R 返回值类型)

    //函数型接口
    //Function<T,R> T 接收的参数,R 返回值类型
    
        @Test
        public void test3() {
            Function<Integer, String> function = (x) -> x + ":为String类型";
            String apply = function.apply(7);
            System.out.println(apply);
        }
        //输出:7:为String类型
    
    //默认主方法addThen
    //函数型接口
        //Function<T,R> T 接收的参数,R 返回值类型
        @Test
        public void test3() {
            Function<String, String> f1 = (x) -> x +"+ ";
            Function<String, String> f2 = (x) -> x + "- ";
            //addThen(然后的意思)执行顺序先执行f1,并且把执行后的结果作为f2的输入参数
            String apply = f1.andThen(f2).apply("1");
            System.out.println(apply);
        }
        //输出:1+ -
    

    4.Predicate 函数型函数接口(断言是否满足条件的)

        //断言型接口
        @Test
        public void test4() {
            Predicate<Integer> predicate = (x) -> x > 10;
            boolean test = predicate.test(11);
            System.out.println(test);
        }
        //输出:true
    }
    }
    
    //断言型接口
        //默认方法 or 和 and
        @Test
        public void test4() {
            Predicate<Integer> p1 = (x) -> x > 10;
            Predicate<Integer> p2 = (x) -> x < 5;
            //默认方法 or 或
            boolean test = p1.or(p2).test(3);
            //默认方法 and 且
            boolean test2 = p1.and(p2).test(3);
    
            System.out.println(test);
            System.out.println(test2);
        }
        //输出:true
        //输出:false
    

    后面的文章我会进一步分享这个函数式接口存在的一些意义以及lambda表达式的关系。

    參考自:
    《java8实战 in Action》
    函数式接口

    相关文章

      网友评论

          本文标题:JAVA8新特性之函数式接口使用与学习

          本文链接:https://www.haomeiwen.com/subject/zqajbktx.html