JDK提供了大量常用的函數式接口以豐富Lambda的典型使用場景,它們主要在 java.util.function 包中被提供。 下面是最簡單的Consumer接口及使用示例。
Consumer接口 概述
@FunctionalInterface
public interface Consumer<T> {
/**
* 對給定參數執行消費操作。
*
* @param t 輸入參數
*/
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
java.util.function.Consumer
抽象方法:accept
Consumer 接口中包含抽象方法 void accept(T t) ,意為消費一個指定泛型的數據。基本使用如:
import java.util.function.Consumer;
public class Demo01Consumer {
public static void main(String[] args) {
consumerString(s -> System.out.println(s));
}
private static void consumerString(Consumer<String> function) {
function.accept("Hello");
}
}
運行程序,控制台輸出:
Hello
當然,更好的寫法是使用方法引用。
默認方法:andThen
如果一個方法的參數和返回值全都是 Consumer 類型,那么就可以實現效果:消費數據的時候,首先做一個操作, 然后再做一個操作,實現組合。而這個方法就是 Consumer 接口中的default方法 andThen 。
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
備注: java.util.Objects 的 requireNonNull 靜態方法將會在參數為null時主動拋出
NullPointerException 異常。這省去了重復編寫if語句和拋出空指針異常的麻煩。
要想實現組合,需要兩個或多個Lambda表達式即可,而 andThen 的語義正是“一步接一步”操作。例如兩個步驟組 合的情況:
import java.util.function.Consumer;
public class Demo02Consumer {
public static void main(String[] args) {
consumerString(
// toUpperCase()方法,將字符串轉換為大寫
s -> System.out.println(s.toUpperCase()),
// toLowerCase()方法,將字符串轉換為小寫
s -> System.out.println(s.toLowerCase())
);
}
private static void consumerString(Consumer<String> one, Consumer<String> two) {
one.andThen(two).accept("Hello");
}
}
運行結果將會首先打印完全大寫的HELLO,然后打印完全小寫的hello。當然,通過鏈式寫法可以實現更多步驟的組合。
HELLO
hello
練習:格式化打印信息
題目
下面的字符串數組當中存有多條信息,請按照格式“ 姓名:XX。性別:XX。 ”的格式將信息打印出來。要求將打印姓 名的動作作為第一個 Consumer 接口的Lambda實例,將打印性別的動作作為第二個 Consumer 接口的Lambda實 例,將兩個 Consumer 接口按照順序“拼接”到一起。
String[] array = { "大雄,男", "靜香,女", "胖虎,男" };
解答
import java.util.function.Consumer;
public class DemoPrintInfo {
public static void main(String[] args) {
String[] array = { "大雄,男", "靜香,女", "胖虎,男" };
printInfo(
s -> System.out.print("姓名:" + s.split(",")[0] + ","),
s -> System.out.println("性別:" + s.split(",")[1] + "。"),
array
);
}
private static void printInfo(Consumer<String> one, Consumer<String> two, String[] array) {
for (String info : array) {
one.andThen(two).accept(info);
}
}
}
運行程序,控制台輸出:
姓名:大雄,性別:男。
姓名:靜香,性別:女。
姓名:胖虎,性別:男。