在Java 8 Lambda Stream collect 排除 null 元素的List
中的元素為一般的物件,若List
中的元素為Optional
包裝的物件,且有部分可能是Optional.empty()
的情況,蒐集元素中某個屬性轉換成另一個List
的寫法如下。
例如下面範例有個List
裡面裝的是被Optional
包裝的Employee
物件,如果要排除空元素及Employee.name == null
的lambda的寫法如下。
package com.abc.demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
public class Main {
public static void main(String[] args) {
List<Optional<Employee>> employeeOptList = new ArrayList<>(); // 一個List,裡面裝有Optional<Empoyee>,可能是資料庫傳回的東西。
employeeOptList.add(Optional.ofNullable(new Employee(1L, "Ann")));
employeeOptList.add(Optional.ofNullable(new Employee(2L, "Jin")));
employeeOptList.add(Optional.ofNullable(new Employee(3L, null)));
employeeOptList.add(Optional.ofNullable(new Employee(4L, "Ken")));
employeeOptList.add(Optional.ofNullable(null));
List<String> nameList1 = employeeOptList.stream()
.filter(Optional::isPresent) // 過濾掉Optional.empty()的元素
.map(Optional::get) // 經過filter的過濾,這邊的元素不會是Optional.empty(),所以可以放心呼叫get()
.map(Employee::getName) // 取得Employee.name
.filter(StringUtils::isNotEmpty) // 排除Employe.name 為空的情況
.collect(Collectors.toList()); // 把Employee.name蒐集成List<String>
nameList1.forEach(System.out::println);
System.out.println("------------------------------------");
List<String> nameList2 = employeeOptList.stream()
.flatMap(Optional::stream) // Java 9 Optional.stream()
.map(Employee::getName)
.filter(StringUtils::isNotEmpty)
.collect(Collectors.toList());
nameList2.forEach(System.out::println);
}
}
class Employee {
private Long id;
private String name;
public Employee(Long id, String name) {
this.id = id;
this.name = name;
}
// getters and setters
}
印出的結果如下。
Ann
Jin
Ken
------------------------------------
Ann
Jin
Ken
Optional.stream()
原始碼如下。
若元素為Optional.empty()
返回Stream.empty()
,反之返回Stream.of(value)
。
public Stream<T> stream() {
if (!isPresent()) {
return Stream.empty();
} else {
return Stream.of(value);
}
}
沒有留言:
張貼留言