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);
}
}
參考:
沒有留言:
張貼留言