Java8 函數式接口 @FunctionalInterface以及常用Consumer、Supplier、Function、Predicate總結

首先看看什麼是Lambda 表達式

Lambda是一個匿名函數,我們可以把Lambda表達式理解為一段可以傳遞的代碼(將代碼像數據一樣傳遞);最簡單的Lambda表達式可由逗號分隔的參數列表、->符號和語句塊組成,例如:

Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );

如果 ->後面的語句塊有多句就使用 { } 例如:

        Arrays.asList("a", "b", "d").forEach(i -> {
            if ("a".equals(i)) {
                System.out.println(i);
            }
        });

@FunctionalInterface 註解 標識是一個函數式接口

1、該註解只能標記在”有且僅有一個抽象方法”的接口上。
2、JDK8接口中的靜態方法和默認方法,都不算是抽象方法。
3、接口默認繼承java.lang.Object,所以如果接口顯示聲明覆蓋了Object中方法,那麼也不算抽象方法。
4、該註解不是必須的,如果一個接口符合”函數式接口”定義,那麼加不加該註解都沒有影響。加上該註解能夠更好地讓編譯器進行檢查。如果編寫的不是函數式接口,但是加上了@FunctionInterface,那麼編譯器會報錯。

函數式接口創建三種方式

1、lambda表達式
2、方法引用
3、構造方法引用

Java8中強制申明的常用函數式接口

Runnable、Callable、Comparator、Consumer、Supplier、Function<T, R>、Predicate

java.util.function包中常用接口

2fcfcc5f3de2692318f04235ea51f79.png

Function<T, R>接口

Function 接口是一個功能型接口,是一個轉換數據的作用。接收一個T參數,返回一個R結果
Function 接口實現 apply 方法來做轉換。
Stream 類的 map 方法了,map 方法傳入一個 Function 接口,返回一個轉換後的 Stream類

    public static void main(String[] args) {
        //使用map方法,泛型的第一個參數是轉換前的類型,第二個是轉化後的類型
        Function<String, Integer> function = s -> {
            System.out.println("獲取字符串" + s + "的長度");
            return s.length();
        };

        Stream<String> stream = Stream.of("sada", "dfg", "12");
        Stream<Integer> stream1 = stream.map(function);
        stream1.forEach(System.out::println);
    }

Consumer接口

消費型接口,接收一個參數,並處理,不返回

    public static void main(String[] args) {
        Consumer<Integer> consumer = i -> {
            System.out.println("Consumer 接收 參數 i 開始處理");
            int step = 1;
            System.out.printf("Consumer 輸入%d, 輸出%d%n", i, i + step);
        };

        List<Integer> list = Arrays.asList(4, 2, 6);
        list.forEach(consumer);
    }

Predicate接口

Predicate 接口是一個謂詞型接口,是一個類似於 bool 類型的判斷的接口。接收一個T類型參數,返回一個bool值

Stream的filter接口參數為Predicate<? super T>

    public static void main(String[] args) {

        //將Predicate作為filter接口,Predicate起到一個判斷的作用
        Predicate<Integer> predicate = integer -> integer > 4;

        Stream<Integer> stream = Stream.of(1,3,2,4,5,12,13);
        List<Integer> list = stream.filter(predicate).collect(Collectors.toList());
        list.forEach(System.out::println);

    }

Supplier接口

生產者接口,沒有參數,返回一個T類型的結果。
1、Supplier 接口可以理解為一個容器,用於裝數據的。
2、Supplier 接口有一個 get 方法,可以返回值。

Optional中的 orElseGet 方法的參數就是Supplier<? extends T>

        Stream<Integer> stream = Stream.of(1, 2, 3, 4);
        //返回一個optional對象
        Optional<Integer> first = stream.filter(i -> i > 4)
                .findFirst();

        //optional對象有需要Supplier接口的方法
        //orElse,如果first中存在數,就返回這個數,如果不存在,就放回傳入的數
        System.out.println(first.orElse(1));
        System.out.println(first.orElse(7));

        Supplier<Integer> supplier = new Supplier<Integer>() {
            @Override
            public Integer get() {
                //返回一個隨機值
                return new Random().nextInt();
            }
        };

        //orElseGet,如果first中存在數,就返回這個數,如果不存在,就返回supplier返回的值
        System.out.println(first.orElseGet(supplier));
Tags: