1. 扁平化流 - flatMap(Funtion)
- flatMap(Arrays::stream) 生成的单个流都被合并起来,即扁平化为一个流
- flatMap() 把一个流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流
1.1 flatMap()
public interface Stream<T> extends BaseStream<T, Stream<T>> {
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
/**
* flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
*
* public interface Function<T, R> {
* R apply(T t);
* }
*
* <R> – The element type of the new stream
*/
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
}
1.2 Stream to List
Stream<String[]> -> flatMap -> Stream<String>
Stream<Set<String>> -> flatMap -> Stream<String>
Stream<List<String>> -> flatMap -> Stream<String>
Stream<List<Object>> -> flatMap -> Stream<Object>
例如:
@Test
public void flatMapTo() {
List<List<OrderDTO>> lists = new ArrayList<>();
/*
* 分析 flatMap(Function<T, Stream> mapper);
*
* 比如:
* .flatMap(orderList -> orderList.stream())
* 此处的 orderList 即 List<OrderDTO>
* Stream<OrderDTO> stream = orderList.stream();
*/
Stream<List<OrderDTO>> stream = lists.stream();
Stream<OrderDTO> orderStream = stream.flatMap(orderList -> orderList.stream());
List<OrderDTO> list = orderStream.collect(Collectors.toList());
List<OrderDTO> collect = lists.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
2. 处理 String[]
map() 可对管道流中的数据进行转换操作,如果管道中还有管道该如何处理?
@Test
public void flatMapToString() {
List<String> words = Arrays.asList("hello", "world");
List<String> list = words.stream()
// Stream<String[]>: String.split(str) 返回类型 String[]
.map(str -> str.split(""))
// Stream<String>
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
System.out.println(list);
// 输出结果: [h, e, l, o, w, r, d]
}
执行分析:
image.png image.png image.png2.2 处理 String[][]
@Test
public void flatMapToArray() {
String[][] array = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}};
// array to a stream
Stream<String[]> stream = Arrays.stream(array);
// or
Stream<String[]> stream2 = Stream.of(array);
String[] words = Stream.of(array)
.flatMap(Stream::of)
.toArray(String[]::new);
// [a, b, c, d, e, f]
System.out.println(Arrays.asList(words));
}
3. 处理List
@Test
public void flatMapToList() {
Map<String, List<OrderDTO>> orderMap = new HashMap<>();
orderMap.put("A1001", Arrays.asList(new OrderDTO("A1001", "1001", 1), new OrderDTO("A1002", "1002", 1)));
orderMap.put("A2001", Arrays.asList(new OrderDTO("A2001", "2001", 1)));
orderMap.put("A3001", Arrays.asList(new OrderDTO("A3001", "3001", 1), new OrderDTO("A3002", "3002", 1)));
List<OrderDTO> orders = orderMap.values().stream()
.filter(orderList -> orderList.size() > 1)
.flatMap(orderList -> orderList.stream())
// or .flatMap(Collection::stream)
.collect(Collectors.toList());
}
4. 其他示例
@Test
public void flatMap3() {
/**
* public class OrderInfo {
* private OrderDTO orderDTO;
* private List<OrderItemDTO> orderItemDTOS;
* }
*/
List<OrderInfo> orderInfos = new ArrayList<>();
List<OrderItemDTO> orderItemDTOS = orderInfos.stream()
.flatMap(orderInfo -> orderInfo.getOrderItemDTOS().stream())
.collect(Collectors.toList());
// 用处1: 设置状态
orderInfos.stream()
.flatMap(orderInfo -> orderInfo.getOrderItemDTOS().stream())
.forEach(item -> item.setStatus(1));
// 用处2:
List<Long> ids = orderInfos.stream()
.map(OrderInfo::getOrderItemDTOS)
.flatMap(List::stream)
.filter(orderItemDTO -> orderItemDTO.getStatus() == 0)
.map(OrderItemDTO::getOrderId)
.distinct()
.collect(Collectors.toList());
}
Stream<OrderItemDTO> orderItemStream = orderInfos.stream()
.flatMap(orderInfo -> orderInfo.getOrderItemDTOS().stream());
// 等价
Stream<OrderItemDTO> orderItemStream2 = orderInfos.stream()
.map(OrderInfo::getOrderItemDTOS)
.flatMap(List::stream);
网友评论