1. 程式人生 > >Java基礎進階Day12

Java基礎進階Day12

Java基礎進階Day12

課程大綱

1、函式式介面 -------------------------> 理解
2、常用函式式介面 ---------------------> 重點格式
        A. Supplier 	"只出不進"		
        B. Consumer 	"只進不出"
        C. Predicate	"條件判斷"
        D. Function		"型別轉換"

第一章 函式式介面

1、含義
A. 函式式介面是在Java語言當中"有且只有一個抽象方法的介面"
B. 如果方法的引數是 函式式介面,
那麼在傳遞引數的時候,就可以寫 Lambda 表示式
2、格式
@FunctionalInterface   	//註解,用於校驗是否是函式式介面
public interface 介面名稱 {
	public abstract 返回值型別 方法名稱(引數列表);    
}
3、對比Lambda和匿名內部類
我們可以把 Lambda 表示式看做匿名內部類的簡化版本。專業術語叫做"語法糖"  --->理解
但是Lambda和匿名內部類不同的地方在於: Lambda的效能比匿名內部類要高,主要是有延遲執行的效果。
4、兩類抽象方法(Lambda表示式)
A.無參無返回
	 方法名稱(
()->{以前抽象方法當中需要執行的程式碼}); B.有參有返回 方法名稱((引數列表可省略型別)->{以前抽象方法當中需要執行的程式碼 return 返回值});

第二章 常用的函式式介面

1、Supplier 函式式介面
A. JDK原始碼
@FunctionalInterface
public interface Supplier<T> {
	T get();
}
B. 介面特點
特點: "只出不進",生產型介面
使用: 如果想要得到某個結果,不用傳入引數,就可以使用介面Supplier 作為方法的引數
C.案例程式碼
//採用函式式介面  Supplier<T> 完成陣列求最小值操作
public class Test01 {

    //寫一個方法,方法的引數是函式式介面(就可以使用Lambda)
    public static int getMin(Supplier<Integer> sup){
        return sup.get();
    }

    //主方法
    public static void main(String[] args) {
        //定義陣列
        int[] arr = {
                22,54,12,7,88
        };
        //呼叫方法,引數是函式式介面,就可以寫Lambda
        int min = getMin(()->{
            int minValue = arr[0];
            for (int num : arr) {
                if(num<minValue){
                    minValue = num;
                }
            }
            return minValue;
        });
        System.out.println("min = " + min); //min = 7
    }
}
2、Consumer 函式式介面
A. JDK原始碼
@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}
B.介面特點
特點: "只進不出" 消費型介面
使用: 如果想要對某個資料進行處理,不需要得到結果,這裡就可以使用 消費型介面 Consumer<T>
注意: 可以連續消費的,連續消費使用的是 andThen()
C.案例程式碼
public static void main(String[] args) {
   //定義一個字串型別的陣列
   String[] arr = {"迪麗熱巴,女", "古力娜扎,女", "馬爾扎哈,男"};
   printData(arr, s1 -> System.out.print("姓名:" + s1.split(",")[0]), s2 -> System.out.println(",性別" + s2.split(",")[1]));
   //===========================
   //姓名:迪麗熱巴,性別女
   //姓名:古力娜扎,性別女
   //姓名:馬爾扎哈,性別男
}

//定義一個方法,方法的引數是函式式介面 Consumer<T>
public static void printData(String[] array, Consumer<String> con1, Consumer<String> con2) {
	//迴圈遍歷字串
	for (String s : array) {
		//消費
		con1.andThen(con2).accept(s);
	}
}
3、Predicate 函式式介面
A. JDK原始碼
@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }


    default Predicate<T> negate() {
        return (t) -> !test(t);
    }


    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }


    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}
B.介面特點
特點: "條件判斷" 判斷型介面
使用: 如果我們想要對某個邏輯進行判斷,可以把介面寫在方法引數上面,返回值寫 boolean
注意: 可以提升逼格。 and()or()negate()
C. 案例程式碼
//篩選 性別是女,並且姓名的長度是4的資料,儲存在集合當中
public static void main(String[] args) {

    //定義一個儲存字串的陣列
    String[] array = { "迪麗熱巴,女", "古力娜扎,女", "馬爾扎哈,男", "趙麗穎,女" };
    //呼叫方法
    List<String> list = getData(array,s1->s1.split(",")[1].equals("女"),s2->s2.split(",")[0].length()==4);
    //列印輸出
    System.out.println("list = " + list); //list = [迪麗熱巴,女, 古力娜扎,女]
}

//定義方法,引數是函式式介面.Predicate<T>
public static List<String> getData(String[] arr, Predicate<String> p1,Predicate<String> p2){
    //建立集合的物件
    List<String> mList = new ArrayList<>();
    //我們需要對陣列的元素進行判斷,所以需要遍歷陣列
    for (String s : arr) {
        //判斷,具體的判斷業務,需要使用Lambda
        boolean bb = p1.and(p2).test(s);
        if(bb){
            mList.add(s);
        }
    }
    //返回結果
    return mList;
}
4、Function 函式式介面
A.JDK原始碼
@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}
B.介面特點
特點: "型別轉換" 型別轉換介面
使用: 如果我們想要把一個數據型別,轉換成為另一個數據型別,需要使用介面。作為方法的引數
注意: 連續轉換 andThen()
C.案例程式碼
//1.獲取年齡字串
//2.將字串轉換成為int型別
//3.把轉換的int型別加上100
public static void main(String[] args) {
	String str = "趙麗穎,20";
	//呼叫方法
	int number = getData(str, str1 -> str1.split(",")[1], str2 -> Integer.parseInt(str2), num1 -> num1 + 100);
	System.out.println("number = " + number);
}

//定義方法,方法的引數是函式式介面 Function<T, R>
public static int getData(String str, Function<String, String> fun1, Function<String, Integer> fun2, Function<Integer, Integer> fun3) {
	int num = fun1.andThen(fun2).andThen(fun3).apply(str);
	return num;
}