如何使用 java lambda 表达式将列表传递给新对象的构造函数?

How to pass a List to a constructor of a new object using java lambda expression?

我有一个问题,我想将 POJO 列表转换为 DTO,并将它们传递到一个包装对象,然后返回该对象。考虑这段 working 代码:

List<Device> devices = dbService.getDevices(...);
List<DeviceDTO> devicesDTO = new ArrayList<DeviceDTO>();
for (Device d : devices) {
   devicesDTO.add(convertToDTO(d));
}

WrapperDTO wrapper = new WrapperDTO(devicesDTO);

我正在寻找一种使用 Java lambda 表达式将其重写为更小、可能更优雅的代码段的方法。这是我到目前为止所做的。我可以进行从 POJO 到 DTO 的转换,但我正在努力将 DTO 列表传递给新包装器对象的构造函数。

List<Device> devices = dbService.getDevices(...);
List<DeviceDTO> devicesDTO = devices.stream().map(d -> convertToDTO(d)).collect(Collectors.toList());

WrapperDTO wrapper = new WrapperDTO(devicesDTO);

我怎样才能把它弄得更短,像这样?

WrapperDTO wrapper = devices.stream()........collect( () -> WrapperDTO:new);

显然,最后一块没有用,但这是我想要实现的。有什么建议么?谢谢我的朋友们:)

你可以使用collectingAndThen收集器一举解决。使用 toList 收集器作为下游收集器,并传递 WrapperDTO::new 构造函数引用作为完成函数。这是它的样子。

final WrapperDTO wrapper = devices.stream()
    .map(d -> convertToDTO(d))
    .collect(Collectors.collectingAndThen(Collectors.toList(), WrapperDTO::new));

有一个调皮的秘密:List写一个map函数。

把那个小家伙藏起来,然后你只需要:

WrapperDTO wrapper = new WrapperDTO(map(devices, MyClass::convertToDTO));

不要告诉溪流很酷的孩子。

map 对于 List 应该类似于:

public static <T, R> List<R> map​(
    List<T> source, Function<? super T,​? extends R> mapper
) {
    List<R> result = new ArrayList<>();
    for (T item : source) {
        result.add(mapper.apply(item));
    }
    return result;
}