1. 程式人生 > >Java之函數式接口

Java之函數式接口

func 條件判斷 根據 each 可選 類型轉換函數 可選參數 util rri

函數式接口

概述:接口中只有一個抽象方法

下面介紹的可能很抽象,理解不了,至少在我看來單獨的這幾個借口是沒有用的,跟最下面說的 Stream流一起用才會有效果

  • 函數式接口,即適用於函數式編程場景的接口。而Java中的函數式編程體現就是Lambda,所以函數式接口就是可
    以適用於Lambda使用的接口。只有確保接口中有且僅有一個抽象方法,Java中的Lambda才能順利地進行推導。

    備註:“語法糖”是指使用更加方便,但是原理不變的代碼語法。例如在遍歷集合時使用的for-each語法,其實
    底層的實現原理仍然是叠代器,這便是“語法糖”。從應用層面來講,Java中的Lambda可以被當做是匿名內部
    類的“語法糖”,但是二者在原理上是不同的。

  • 格式:
    1. 只要確保接口中有且僅有一個抽象方法即可:

       修飾符 interface 接口名稱 {
          public abstract 返回值類型 方法名稱(可選參數信息);
          // 其他非抽象方法內容
       }
    2. @FunctionalInterface註解

      與@Override 註解的作用類似,Java 8中專門為函數式接口引入了一個新的註解: @FunctionalInterface 。該註
      解可用於一個接口的定義上,一旦使用該註解來定義接口,編譯器將會強制檢查該接口是否確實有且僅有一個抽象方法,否則將會報錯。需要註
      意的是,即使不使用該註解,只要滿足函數式接口的定義,這仍然是一個函數式接口,使用起來都一樣。

    3. 自定義函數式接口(前面已經寫過,這就不重復寫了)

      package com.wzlove.function;

      /**
      • 自定義函數式接口
      • 使用@FunctionalInterface可以說明該接口是函數式接口,但是不加,如果接口中只有一個抽象方法,這個接口也是函數式接口
      • 也就是說函數式接口不以註解的存在而存在
        */
        @FunctionalInterface
        public interface MyFunctionalInterface {

        public abstract void show();
        }

lambda表達式: (參數列表)->{代碼}

lambda表達式(前面有篇文章說過,不詳細說明)

有參數,有返回值的自定義函數式接口

    @FunctionalInterface
    public interface Sumable {
        int sum(int a, int b);
    }

JDK1.8之後的某些函數式接口

supplier生產數據函數式接口

目的是生產數據.

目前好像看不出來有什麽用,但是好像和jdk8的Stream流有關.,舉個小例子

    package com.wzlove.supplier;
    
    import java.util.function.Supplier;
    
    /**
     * 使用supplier函數式接口求數組的最大值
     */
    public class ArrMaxValue {
    
        public static int getMaxValue(Supplier<Integer> sup){
            return sup.get();
        }
    
        public static void main(String[] args) {
            // 創建數組
            int[] arr = {100,20,50,30,99,101,-50};
    
            int maxValue = getMaxValue(()->{
                int max = arr[0];
                for (int i : arr) {
                    if(i > max){
                        max = i;
                    }
                }
                return max;
            });
    
            System.out.println("數組中的最大值為:" + maxValue);
        }
    
    }

Consumer消費數據函數式接口

這個方法是用來消費數據的,如何消費,消費規則自己定義.

java.util.function.Supplier

package com.wzlove.comsumer;

import java.util.function.Consumer;

/**
 * 使用Consumer函數式接口實現格式化輸出
 */
public class ConsumerDemo2 {

    public static void printInfo(String[] strArr, Consumer<String> con1, Consumer<String> con2){

        for (int i = 0; i < strArr.length; i++) {
            con1.andThen(con2).accept(strArr[i]);
        }

    }

    public static void main(String[] args) {
        String[] strArr = {"迪麗熱巴,女","鄭爽,女","楊紫,女"};
        printInfo(strArr,(message)->{
            System.out.print("姓名:" + message.split(",")[0] + "。  ");
        },(message)->{
            System.out.println("性別:" + message.split(",")[1] + "。");

        });
    }
}

Predicate判斷函數式接口

Predicate 接口中包含一個抽象方法: boolean test(T t) 。用於條件判斷的場景

默認方法:

  • default Predicate
  • default Predicate
  • default Predicate

    package com.wzlove.functionalinterface.predicate;

    import java.util.ArrayList;
    import java.util.function.Predicate;

    /**
    • */
      public class PredicateDemo2 {

      /**
      • 檢查數組中的元素是否符合要求,滿足要求加入List中並返回
      • @param arr 需要判斷的數組
      • @param pre1 判斷接口1,判斷性別是否為女
      • @param pre2 判斷接口2,判斷姓名長度是否大於2
      • @return 集合
        */
        public static ArrayList

      public static void main(String[] args) {
      // 創建數組
      String[] arr = {"迪麗熱巴,女","楊洋,男","李溪芮,女","鄭爽,女"};

        // 調用方法(Lambda表達式可以簡化)
        ArrayList<String> list = checkStar(arr,(str)->{
            return str.split(",")[1].equals("女");
        },(str)->{
            return str.split(",")[0].length() > 2;
        });
      
        // 遍歷集合
        for (String elem : list) {
            System.out.print(elem + "   ");
        }

      }

    }

Function類型轉換函數式接口

Function 接口中最主要的抽象方法為: R apply(T t) ,根據類型T的參數獲取類型R的結果。

Function 接口中有一個默認的andThen 方法,用來進行組合操作。

package com.wzlove.functionalinterface.function;

import java.util.function.Function;

/**
 *
 */
public class FunctionDemo2 {

    /**
     * 將String分割,獲得第二個元素,將數據轉化為int,int數據加100,再將int轉化為String
     * @param str    轉化的數據
     * @param fun1   String -> String
     * @param fun2   String -> Integer
     * @param fun3   Integer -> String
     * @return       最後的String
     */
    public static String convert(String str,
                              Function<String,String> fun1,
                              Function<String, Integer> fun2,
                              Function<Integer,String> fun3){

        return fun1.andThen(fun2).andThen(fun3).apply(str);

    }

    public static void main(String[] args) {
        String str = convert("迪麗熱巴,23",(s)->{
            return s.split(",")[1];
        },(s)->{
            return Integer.parseInt(s) + 100;
        },(s)->{
            return String.valueOf(s);
        });
        System.out.println(str);
    }
}

Java之函數式接口