網頁

2018/9/1

Java 8 java.util.function 常用的Functional Interface

Java 8新增了Lambda語法,而lambda語法的參數為Functional Interface的實作。以下為Java 8新增的java.util.function常用的Functional Interface及被使用到的方法。

  • Consumer<T>:List.forEach(Consumer<? super T> action),Optional.ifPresent(Consumer<? super T> consumer)
  • Function<T,R>:Optional.map(Function<? super T,? extends U> mapper)
  • Predicate<T>:Optional.filter(Predicate<? super T> predicate)
  • Supplier<T>:Optional.orElseGet(Supplier<? extends T> other)
  • BiConsumer<T,U>:Map.forEach(BiConsumer<? super K,? super V> action)

以下範例分別以傳統的實作匿名內部類別,Java 8的lambda語法及method reference語法(如果可以用的話)來撰寫。


Consumer<T>

Consumer<T>accept(T t)方法會接收一個參數,且執行後不回傳任何東西。此方法設計來對傳入的參數做處理。

例如List.forEach(Consumer&tl;? super T> action)即以Consumer<T>為參數,並實作其accept(T t)方法來將strList中每一個傳入的元素(字串)印出。

public class Main {

    public static void main(String[] args) {
        List<String> strList = Arrays.asList("a", "b", "c");
        // implements anonymous inner class 實作匿名內部類別
        strList.forEach(new Consumer<String>() {
            @Override
            public void accept(String e) {
                System.out.println(e.toUpperCase());
            }
        });

        // lambda
        strList.forEach(e -> {
            System.out.println(e.toUpperCase());
        });

        // method references 方法參考
        strList.forEach(Main::print);

    }

    private static void print(String e) {
        System.out.println(e.toUpperCase());
    }

}

Optional.ifPresent(Consumer<? super T> consumer)也是以Consumer<T>為參數。

public class Main {

    public static void main(String[] args) {

        String str = "hello world";

        // implements anonymous inner class 實作匿名內部類別
        Optional.ofNullable(str).ifPresent(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        // lambda
        Optional.ofNullable(str).ifPresent((s) -> {
            System.out.println(s);
        });

        // method references 方法參考
        Optional.ofNullable(str).ifPresent(Main::print);
    }

    private static void print(String s) {
        System.out.println(s);
    }

}

Function<T,R>

Function<T,R>apply(T t)用來接收一個參數,及回傳指定型態的結果。

例如Optiona.map(Function<? super T,? extends U> mapper)即以Function<T,R>為參數。

public class Main {

    public static void main(String[] args) {

        String str = "hello world";

        // implements anonymous inner class 實作匿名內部類別
        Optional<String> os1 = Optional.ofNullable(str).map(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.toUpperCase();
            }
        });
        System.out.println(os1.get()); // HELLO WORLD

        // lambda
        Optional<String> os2 = Optional.ofNullable(str).map(s -> s.toUpperCase());
        System.out.println(os2.get()); // HELLO WORLD

        // method references 方法參考
        Optional<String> os3 = Optional.ofNullable(str).map(String::toUpperCase);
        System.out.println(os3.get()); // HELLO WORLD
    }

}

Predicate<T>

Predicate<T>test(T t)用來接收一個參數,並回傳boolean

例如Optional.filter(Predicate<? super T> predicate)即以Predicate<T>為參數。

public class Main {

    public static void main(String[] args) {

        String str = "hello world";

        // implements anonymous inner class 實作匿名內部類別
        Optional<String> os1 = Optional.ofNullable(str).filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() < 10; // false
            }
        });
        System.out.println(os1); // Optional.empty

        // lambda
        Optional<String> os2 = Optional.ofNullable(str).filter(s -> s.length() < 10);
        System.out.println(os2); // Optional.empty

        // method references 方法參考
        Optional<String> os3 = Optional.ofNullable(str).filter(Main::isLessThanTenWords);
        System.out.println(os3); // Optional.empty
    }

    private static boolean isLessThanTenWords(String s) {
        return s.length() < 10;
    }

}

Supplier<T>

Supplier<T>get()用來回傳特定的結果,回傳值的型態須同呼叫的方法的回傳型態。

例如Optiona.orElseGet(Supplier<? extends T> other)即以Supplier<T>為參數。

public class Main {

    public static void main(String[] args) {

        String str = null;

        // implements anonymous inner class 實作匿名內部類別
        String s1 = Optional.ofNullable(str).orElseGet(new Supplier<String>() {
            @Override
            public String get() {
                return "A";
            }
        });
        System.out.println(s1); // A

        // lambda
        String s2 = Optional.ofNullable(str).orElseGet(() -> "B");
        System.out.println(s2); // B

        // method references 方法參考
        String s3 = Optional.ofNullable(str).orElseGet(Main::getJohn);
        System.out.println(s3); // John
    }

    private static String getJohn() {
        return "John";
    }

}

BiConsumer<T,U>

BiConsumer<T,U>accept(T t, U u)用來傳入兩個參數,且不回傳值。

例如Map.forEach(BiConsumer<? super K,? super V> action)即以BiConsumer<T,U>為參數。

public class Main {

    public static void main(String[] args) {

        Map<String, String> map = new HashMap<String, String>();
        map.put("a", "A");
        map.put("b", "B");
        map.put("c", "C");

        // implements anonymous inner class 實作匿名內部類別
        map.forEach(new BiConsumer<String, String>() {
            @Override
            public void accept(String k, String v) {
                System.out.println(k + ":" + v);
            }
        });

        // lambda
        map.forEach((k, v) -> {
            System.out.println(k + ":" + v);
        });

        // method references 方法參考
        map.forEach(Main::printKeyValue);
    }

    private static void printKeyValue(String k, String v) {
        System.out.println(k + ":" + v);
    }

}

參考:

沒有留言:

張貼留言