Java8學習筆記(一)—— 函數式編程的四個基本接口

一、基本函式數接口

基本的函數式接口主要有四個:

① Supplier<T> 生產者:無輸入,生產一個T類型的值;

② Consumer<T> 消費者:輸入一個T類型的值,無輸出;

③ Function<T,R> 函數:輸入一個T類型的值,返回一個R類型的值;

④ Predicate<T> 斷言:輸入一個T類型的值,返回true/false

二、基本函數式接口使用示例

下面來看一下這四個基本函數式接口的使用示例:

/**
     * 接口:interface Supplier<T> 提供者
     * 定義一個Lambda表達式,無輸入,生產(返回)一個T類型的值
     */
    @Test
    public void example1(){
        //返回Integer類型的值
        Supplier<Integer> supplier = () -> 10;
        System.out.println(supplier.get()); //打印:10

        //返回異常類的對象
        Supplier<Exception> exceptionSupplier = () -> new Exception("異常");
        System.out.println(exceptionSupplier.get().getMessage()); //打印:異常
    }

    /**
     * 接口:interface Consumer<T> 消費者
     * 定義一個Lambda表達式,消費(輸入)一個T類型的值,無返回
     */
    @Test
    public void example2(){
        //accept 接收參數並調用接口的方法
        Consumer<Integer> consumer = x -> System.out.println(x);
        consumer.accept(15); //打印:15

        //andThen 先調用原Consumer,再調用andThen方法中指定的Consumer
        Consumer<Integer> secondConsumer = y -> System.out.println(y + y);
        consumer.andThen(secondConsumer).accept(10); //打印: 10 20
    }

    /**
     * 接口:interface Function<T,R> 函數
     * 定義一個Lambda表達式,輸入一個T類型的參數,返回一個R類型的值
     */
    @Test
    public void example3(){
        //apply 傳入一個T類型的值,返回一個R類型的值
        Function<Integer, Double> function = x -> x + 10.5;
        System.out.println(function.apply(10)); //打印:20.5

        //兩個Function
        Function<String, String> fun1 = str1 -> {
            System.out.println("fun1");
            return str1 + "1";
        };
        Function<String, String> fun2 = str2 -> {
            System.out.println("fun2");
            return str2 + "2";
        };

        //compose 先執行compose中的函數,再把返回值當作參數執行原函數
        String str1 = fun1.compose(fun2).apply("張三");
        System.out.println(str1); //打印:fun2 fun1 張三21

        //andThen 先執行原函數,再把原函數的返回值當作參數執行andThen中的函數
        String str2 = fun1.andThen(fun2).apply("張三");
        System.out.println(str2); //打印: fun1 fun2 張三12
    }

    /**
     * 接口:interface Predicate<T> 斷言
     * 定義一個Lambda表達式,輸入一個T類型的參數,返回一個true/false
     */
    @Test
    public void example4(){
        //test 測試輸入的參數是否滿足定義的lambda表達式
        Predicate<String> pre1 = s -> "test".equals(s);
        System.out.println(pre1.test("test")); //打印:true
        System.out.println(pre1.test("test_")); //打印:false

        //and 原Predicate接口和and方法中指定的Predicate接口要同時爲true,結果才爲true,同邏輯運算符&&一樣
        Predicate<String> pre2 = s -> s.length() == 4;
        System.out.println(pre1.and(pre2).test("test")); //打印:true
        System.out.println(pre1.and(pre2).test("ssss")); //打印:false

        //or 原Predicate接口和or方法中指定的Predicate接口有一個爲true,結果就爲true,同邏輯運算符||一樣
        System.out.println(pre1.or(pre2).test("ssss")); //打印:true

        //negate 對結果取反再輸出
        System.out.println(pre1.negate().test("test")); //打印:false
    }

三、擴展的基本函數式接口

擴展接口主要包括:

① 基本數據類型的函數式接口

如:DoubleSupplier、DoubleConsumer、DoubleFunction、DoublePredicate等;

② 一元函數式接口

如:UnaryOperator<T>(引用類型的一元函數式接口)、IntUnaryOperator(基本類型的一元函數式接口);

③ 用於類型轉換的一元函數式接口

如:ToIntFunction<T>(引用類型轉基本類型)、IntToDoubleFunction(基本類型轉其他基本類型);

④ 同類型輸入參數的二元函數式接口

如:BinaryOperator<T>(引用類型)、IntBinaryOperator(基本類型)

⑤ 混合類型輸入參數的二元函數式接口

如:ObjIntConsumer<T>

⑥ 用於類型轉換的二元函數式接口

如:ToIntBiFunction<T,R>(引用類型轉基本類型)

下面看一下擴展接口的使用示例:

/**
     * 基本數據類型的函數式接口:double int long boolean
     * double int long都有四個接口,boolean只有一個BooleanSupplier
     */
    @Test
    public void example5(){
        //生產一個double類型的返回值
        DoubleSupplier doubleSupplier = () -> {
          return 10.5 + 'a'; //a的ascii編碼爲97
        };
        System.out.println(doubleSupplier.getAsDouble()); //打印:107.5

        //消費一個double類型的值
        DoubleConsumer doubleConsumer = x -> {
            System.out.println(x + "000");
        };
        doubleConsumer.accept(10); //打印:10.0000 double類型默認小數點後面有一位

        //消費一個double類型的值再返回一個T類型的值
        DoubleFunction<String> doubleFunction = x -> {
            return x + "000";
        };
        System.out.println(doubleFunction.apply(10)); //打印:10.0000

        //消費一個double類型的值進行斷言
        DoublePredicate doublePredicate = x -> {
            return x>1;
        };
        System.out.println(doublePredicate.test(10)); //打印:true
    }

    //內部類
    class Student{
        private String name;
        private Integer age;
        public Student(){}

        public Student(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }
    }

    /**
     * 一元函數式接口
     */
    @Test
    public void example6(){
        //引用類型的一元函數式接口
        UnaryOperator<Student> unaryOperator = x -> {
            return new Student(x.getName(),20);
        };
        Student stu = unaryOperator.apply(new Student("張三", 15));
        System.out.println(stu.getName() + "今年" + stu.getAge() + "歲"); //打印:張三今年20歲

        //基本類型的一元函數式接口:int long double
        IntUnaryOperator intUnaryOperator = x -> {
            return x * x;
        };
        System.out.println(intUnaryOperator.applyAsInt(10)); //打印:100
    }

    /**
     * 用於類型轉換的一元函數式接口
     */
    @Test
    public void example7(){
        //引用數據類型轉基本數據類型
        ToIntFunction<Student> toIntFunction = x -> {
            return x.getAge();
        };
        System.out.println(toIntFunction.applyAsInt(new Student("張三",15))); //打印:15

        //基本數據類型轉其他基本數據類型:int long double
        IntToDoubleFunction intToDoubleFunction = x -> {
            return x;
        };
        System.out.println(intToDoubleFunction.applyAsDouble(10));//打印:10.0
    }

    /**
     * 同類型輸入參數的二元函數式接口
     */
    @Test
    public void example8(){
        //引用類型
        BinaryOperator<Student> binaryOperator = (x,y) -> {
            return new Student(x.getName(),y.getAge());
        };
        Student stu = binaryOperator.apply(new Student("張三", 15), new Student("李四", 20));
        System.out.println(stu.getName() + "今年" + stu.getAge() + "歲"); //打印:張三今年20歲

        //基本數據類型:int double long
        IntBinaryOperator intBinaryOperator = (x,y) -> {
            return Math.max(x,y);
        };
        System.out.println(intBinaryOperator.applyAsInt(10,20)); //打印:20
    }

    /**
     * 混合類型輸入參數的二元函數式接口
     */
    @Test
    public void example9(){
        ObjIntConsumer<Student> objIntConsumer = (x,y) ->{
            System.out.println(x.getName() + "今年" + y + "歲"); //打印:張三今年20歲
        };
        objIntConsumer.accept(new Student("張三",20),30);
    }

    /**
     * 用於類型轉換的二元函數式接口
     */
    @Test
    public void example10(){
        //引用數據類型到基本數據類型
        ToIntBiFunction<Student, Integer> toIntBiFunction = (x,y) -> {
            return x.getAge() + y;
        };
        Student stu = new Student("張三", 20);
        int age = toIntBiFunction.applyAsInt(stu, 10);
        System.out.println(stu.getName() + "10年後" + age + "歲"); //打印:張三10年後30歲
    }

參考:

1、java8 -函數式編程之四個基本接口

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章