函數式接口

1.1函數式接口概述
函數式接口:有且僅有一個抽象方法的接口
Java中的函數式編程體現就是Lambda表達式,因此函數式接口就是能夠適用於Lambda使用的接口
只有確保接口中有且僅有一個抽象方法, Java中的L ambda才能順利地進行推導

html

如何檢測一個接口是否是函數式接口呢?
@Functionallnterface放在接口定義的上方:java

若是接口是函數式接口,編譯經過;若是不是,編譯失敗編程


注意
●咱們本身定義 函數式接口的時候,@Functionallnterface是可選的, 就算我不寫這個註解,只要保證知足函數式接口定
義的條件,也照樣是函數式接口。可是,建議加上該註解數組



1.2函數式接口做爲方法的參數
需求
● 定義一個類(RunnableDemo),在類中提供兩個方法
一個方法是: startThread(Runnable r)方法參數Runnable是一 個函數式接口
一個方法是主方法,在主方法中調用startThread方法
若是方法的參數是一個函數式接口, 咱們可使用 ambda表達式做爲參數傳遞
●startThread(0 -> System.out.println(Thread.currentThread0.getName0 + "線程啓動了));app

package com.Test01;
/*
    定義一個類(RunnableDemo),在類中提供兩個方法
    一個方法是: startThread(Runnable r) 方法參數Runnable是一 個函數式接口
    一個方法是主方法,在主方法中調用startThread方法

 */

public class RunnableDemo {
    public static void main(String[] args) {
        //在主方法中調用startThread方法

        //採用匿名內部類的方式
        startThread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "線程啓動了");
                

            }
        });
      startThread (() -> System.out.println(Thread.currentThread().getName() + "線程啓動了"));
  } private static void startThread(Runnable r) { // Thread t = new Thread(r); // t.start(); new Thread(r).start(); } }

1.3函數式接口做爲方法的返回值
需求●定義一個類(ComparatorDemo), 在類中提供兩個方法
一個方法是: Comparator <String> getComparator()方法返回值C omparator是一個函數式接口
一個方法是主方法,在主方法中調用getComparator方法ide


若是方法的返回值是一個函數式接口,咱們可使用L ambda表達式做爲結果返回
●private static Comparator <String> getComparator({
return (s1, s2) -> s1.length( - s2.length0;
}

函數式編程

package com.Test01;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class CommparatorDemo {
    public static void main(String[] args) {
        //構造使用場景

        //定義集合 存儲字符串元素
        ArrayList<String> array = new ArrayList<String>();
        array.add("cccc");
        array.add("aaa");
        array.add("dd");
        array.add("b");
        System.out.println("排序前:" + array);
        Collections.sort(array, getComparator());
        System.out.println("排序後:" + array);


    }

    public static Comparator<String> getComparator() {
        //返回該接口的實現類對象
        //首先採用匿名內部類的方式
//        Comparator<String> comp = new Comparator<String>() {
//            @Override
//            public int compare(String s1, String s2) {
//                return s1.length()-s2.length();
//            }
//        };
//        return comp;
//        return new Comparator<String>() {
////            @Override
////            public int compare(String s1, String s2) {
////                return s1.length() - s2.length();
////            }
////        };
//        return (String s1,String s2) ->{
//            return s1.length()-s2.length();
//        };
        return (s1, s2) -> s1.length() - s2.length();

    }
}

 


經常使用的4個函數式接口函數

Java 8在java.util.function包下預約義了大量的函數式接口供咱們使用
咱們重點來學習下面的4個接口
●Supplier接口
●Consumer接口
●Predicate接口、
●Function接口

學習

 


 

1,Supplier接口spa

 

@FunctionalInterface
public interface Supplier<T>

 

表明結果供應商。

沒有要求每次調用供應商時都會返回新的或不一樣的結果。

這是一個functional interface的功能方法是get()

 

 

package com.Test01;
/*
Supplier<T>:包含一個無參的方法
T get ():得到結果
該方法不須要參數,它會按照某種實現邏輯(由Lambda表達式實現)返回一個數據
Supplier<T>接口也被稱爲生產型接口,若是咱們指定了接口的泛型是什麼類型,那麼接口中的get方法就會生產什麼類型的數據供使用

 */

import java.util.function.Supplier;

public class SupplierDemo {
    public static void main(String[] args) {
//        String s = getString(() -> {
//            return "林青霞";
//        });
        String s = getString(() -> "林青霞");
        System.out.println(s);

    }
    private static String getString(Supplier<String> sup) {
        return sup.get();
    }
}

 

 

 

 

 

 

package com.Test01;

import java.util.function.Supplier;

public class SupplierTest {
    public static void main(String[] args) {
        //定義一個數組
        int[] arr = {15, 20, 3, 65, 45, 6};

        int x = getMax(() -> {
            int Max = arr[0];
            for (int i = 0; i < arr.length; i++) {
                if (Max < arr[i]) {
                    Max = arr[i];
                }

            }
            return Max;
        });
        System.out.println(x);  
    }

    private static int getMax(Supplier<Integer> sup) {
        return sup.get();
    }
}

 


,2,Consumer接口

 

@FunctionalInterface
public interface Consumer<T>

 

表示接受單個輸入參數而且不返回結果的操做

 

1.6 Consumer接口
  Consumer<T>:包含兩個方法
void accept(T t): 對給定的參數執行此操做
default Consumer <T> andThen(Consumer after):返回一個組合的Consumer,依次執行此操做,而後執行after操做
●Consumer<T>接口也被稱爲消費型接口,它消費的數據的數據類型由泛型指定

 

 

 

package com.Test01;
/*
Consumer<T>:包含兩個方法
void accept (T t): 對給定的參數執行此操做
default Consumer<T> andThen (Consumer after): 返回一個組合的Consumer, 依次執行此操做,而後執行after操做
Consumer<T>接口也被稱爲消費型接口,它消費的數據的數據類型由泛型指定
/

 */

import java.util.function.Consumer;

public class ConsumerDemo {
    public static void main(String[] args) {
//        Lamada表達式
//        OperatorString("林青霞",(s) -> {
//            System.out.println(s);
//        });

//        OperatorString("林青霞", (s) -> System.out.println(s));
        //方法引用
        OperatorString("林青霞", System.out::println);
    }

    //定義一個方法,消費一個字符串數據
    private static void OperatorString(String name, Consumer<String> con) {
        con.accept(name);
    }
}

 

Consumer練習
String[] strArray = {"林青霞, 30",」張曼玉,35", 」王祖賢, 33"}; 字符串數組中有多條信息,請按照格式: "姓名: Xx,年齡: xX"的格式將信息打印出來 要求: 把打印姓名的動做做爲第- -個Consumer接口的L ambdo實例 把打印年齡的動做做爲第二個Consumer接口的L ambda實例 將兩個Consumer接口按照順序組合到一塊兒使用




package com.Test01;
/**/

import java.util.function.Consumer;

public class ConsumerDemo02 {
    public static void main(String[] args) {
        String[] strArray = {"林青霞,30", "張曼玉,35", "王祖賢,33"};
        printString(strArray, (String str) -> {
            String name = str.split(",")[0];
            System.out.print("姓名:" + name);
        }, (String str) -> {
            int age = Integer.parseInt(str.split(",")[1]);
            System.out.println(",年齡:" + age);
        });

    }

    private static void printString(String[] strArray, Consumer<String> con1, Consumer<String> con2) {
        for (String s : strArray) {
            con1.andThen(con2).accept(s);
        }
    }
}

 

3, Predicate接口

@FunctionalInterface
public interface Predicate<T>
表示一個參數的謂詞(布爾值函數)。


Predicate<T>:經常使用的四個方法
●boolean test(T t):對給定的參數進行判斷(判斷邏輯由L ambda表達式實現),返回一個布爾值
●default Predicate<T> negate():返回-一個邏輯的否認,對應邏輯非
●default Predicate<T> and(Predicate other):返回一個組合判斷,對應短路與
●default Predicate<T> or(Predicate other):返回一個組合判斷,對應短路或

-----------   - --  - - - - - - - - -- - - - - - - - - - - - - -- - -   -- - - - - - --

Predicate<T>接口一般用於判斷參數是否知足指定的條件


 

●boolean test(T t):對給定的參數進行判斷(判斷邏輯由L ambda表達式實現),返回一個布爾值
●default Predicate<T> negate():返回-一個邏輯的否認,對應邏輯非

以下演示

package com.Test01;
/*
Predicate<T>:經常使用的四個方法
boolean test (T t):對給定的參數進行判斷(判斷邏輯由Lambda表達式實現),返回一個布爾值
default Predicate<T> negate (): 返回一個邏輯的否認,對應邏輯非
Predicate<T>接口一般用於判斷參數是否知足指定的條件

 */


import java.util.function.Predicate;

public class PredicateDemo01 {
    public static void main(String[] args) {
//        boolean b = checkString("hello", (String s) -> {
//            return s.length() > 8;
//        });
        boolean b = checkString("hello", s -> s.length() > 8);
        System.out.println(b);

    }

    //判斷給定的字符串是否知足要求
    private static boolean checkString(String s, Predicate<String> pre) {
//        return pre.test(s);
//        return !pre.test(s);//不是標準非
        return pre.negate().test(s);//接口提供的邏輯非的操做

    }
}

 

●default Predicate<T> and(Predicate other):返回一個組合判斷,對應短路與
●default Predicate<T> or(Predicate other):返回一個組合判斷,對應短路或

以下演示

package com.Test01;
/*
/*
Predicate<T>:
default Predicate<T> and (Predicate other): 返回一個組合判斷,對應短路與
default Predicate<T> or (Predicate other): 返回-一個組合判斷,對應短路或

 */

import java.util.function.Predicate;

public class PredicateDemo02 {
    public static void main(String[] args) {
        boolean b1 = checkString("hello", s -> s.length() > 8);
        //System.out.println(b1);
        boolean b2 = checkString("helloworld", s -> s.length() > 8);
        //System.out.println(b2);
        boolean b3 = checkStringandor("helloworld", s -> s.length() > 11, s -> s.length() < 15);
        System.out.println(b3);
    }

    //同一個字符串給出兩個不一樣的判斷條件,最後把這兩個判斷的結果作邏輯與運算的結果做爲最終的結果
    private static boolean checkStringandor(String s, Predicate<String> pre1, Predicate<String> pre2) {
//        boolean b1 = pre1.test(s);
////        boolean b2 = pre2.test(s);
////        boolean b = b1 || b2;
////        return b;
        return pre1.or(pre2).test(s);//return pre1.and(pre2).test(s);
    }

    private static boolean checkString(String s, Predicate<String> pre) {
        //斷定給定的字符串是否知足要求
        return pre.test(s);
//

    }

}

 Predicate練習
String[ strArray= {"林青霞30", "柳巖,34", "張曼玉,35",「貂蟬,31", "王祖賢,33"};
●字符串數組中有多條信息, 請經過Predicate接口的拼裝將符合要求的字符串篩選到集合ArrayList中,並遍歷ArrayList集合
●同時知足以下要求:姓名長度大於2;年齡大於33

分析
有兩個判斷條件,因此須要使用兩個Predicate接口,對條件進行判斷
必須同時知足兩個條件,因此可使用and方法鏈接兩個判斷條件

package com.Test01;
/*
String[] strArray = {"林青霞,30」,「柳巖,34", "張曼玉,35", "貂蟬,31","王祖賢,33"};
字符串數組中有多條信息,請經過Predicate接口的拼裝將符合要求的字符串篩選到集合Arraylist中,並遍歷Arraylist集合
要求:同時知足以下要求
1:姓名長度大於2
2:年齡大於33
分析:
1:有兩個判斷條件,因此須要使用兩個Predicate接口,對條件進行判斷
2:必須同時知足兩個條件,因此可使用and方法鏈接兩個判斷條件

 */

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

public class PredicateTest {
    public static void main(String[] args) {
        String[] strArray = {"林青霞,30", "柳巖,34", "張曼玉,35", "貂蟬,31", "王祖賢,33"};
        ArrayList<String> stringArrayList = myfilter(strArray, s -> s.split(",")[0].length() > 2, s -> Integer.parseInt(s.split(",")[1]) > 33);
        for (String s : stringArrayList) {
            System.out.println(s);
        }
    }

    //    請經過Predicate接口的拼裝將符合要求的字符串篩選到集合ArrayList中,
    private static ArrayList<String> myfilter(String[] arr, Predicate<String> pre1, Predicate<String> pre2) {
        //定義一個集合
        ArrayList<String> array = new ArrayList<String>();
        for (String s : arr) {
            String name = s.split(",")[0];
            int age = Integer.parseInt(s.split(",")[1]);
            if (pre1.and(pre2).test(s)) {
                array.add(s);
            }
        }

        return array;

    }

}

4, Function接口

@FunctionalInterface
public interface Function<T,R>
表示接受一個參數併產生結果的函數


Function<T,R>:經常使用的兩個方法
R apply(Tt):將此函數應用於給定的參數
default <V> Function andThen(Function after):返回-個組合函數,首先將該函數應用於輸入,而後將after函數應用於結果
Function<T,R>接口一般用於對參數進行處理,轉換(處理邏輯由Lambda表達式實現),而後返回一個新的值

package com.Test01;
/*
Function<T,R>:經常使用的兩個方法
R apply (T t):將此函數應用於給定的參數
default <V> Function andThen (Function after): 返回一個組合函數,首先將該函數應用於輸入,而後將ofter函數應用於結果
Function<T, R>接口一般用於對參數進行處理,轉換(處理邏輯由L ambda表達式實現),而後返回一一個新的值

 */

import java.util.function.Function;

public class FunctionDemo {

    public static void main(String[] args) {
//        Convert("100", (String s) -> {
//            return Integer.parseInt(s);
//        });
        Convert("100", s -> Integer.parseInt(s));
        Convert("100", Integer::parseInt);
        Convert(100, i-> String.valueOf(i+566));
        Convert("300",s->Integer.parseInt(s),i->String.valueOf(i+300));

    }

    //定義一個方法,把一個字符串轉換int類型,在控制檯輸出
    private static void Convert(String s, Function<String, Integer> fun) {
//        Integer i = fun.apply(s);
        int i = fun.apply(s);
        System.out.println(i);
    }


    //定義一個方法,把一個int類型的數據加上一個整數以後,轉爲字符串在控制檯輸出
    private static void Convert(int i, Function<Integer, String> fun) {
        String s = fun.apply(i);
        System.out.println(s);
    }

    //定義一個方法,把一個字符串轉換int類型,把int類型的數據加上一一個整數以後,
    // 轉爲字符串在控制檯輸出
    private static void Convert(String s,Function<String,Integer> fun1,Function<Integer,String> fun2) {
//        Integer i = fun1.apply(s);
//        String s1 = fun2.apply(i);
//        System.out.println(s1);
        String s1 = fun1.andThen(fun2).apply(s);
        System.out.println(s1);
    }


}

練習

package com.Test01;
/*
●Strings = "林青霞30";
●請按照我指定的要求進行操做:
1:將字符串截取獲得數字年齡部分string
2:將上一步的年齡字符串轉換成爲int類型的數據int
3:將上一步的int數據加70,獲得個int結果,在控制檯輸出
●請經過Function接口來實現函數拼接
*/

import java.util.function.Function;

public class FunctionDemo02 {
    public static void main(String[] args) {
        Convert("林青霞30",s->  Integer.parseInt(s.substring(3,5))+70);  //也能夠按照題目的要求一步一步來

    }

    private static void Convert(String s, Function<String, Integer> fun) {
        Integer i = fun.apply(s);
        System.out.println(i);
    }


}

 

相關文章
相關標籤/搜索