在 Java 中将一个 Optional<List<Object>> 转换为另一个 Optional<List<Object>>

问题描述

例如,如何将可选列表对象从一种类型转换为另一种类型

Optional<List<ProductMultipleOptionviewmodel>> productOptionType1 // One type

Optional<List<ProductMultipleOption>> productOptionType2 // Other type

ProductMultipleOptionviewmodel

类型 1

@Introspected
public record ProductMultipleOptionviewmodel(
        ProductOptionviewmodel productOption,String optionName) {
}

类型 2

 @Introspected
    public record ProductMultipleOption(
            ProductOptionviewmodel productOption,String optionName) {
    }

我想从 Optional<List<ProductMultipleOption>> 转换为其他 Optional<List<ProductMultipleOptionviewmodel>>。我试过下面的代码

Optional<List<ProductMultipleOptionviewmodel>> conveertItem = Optional.ofNullable(product.getProductMultipleOption())
                .orElseGet(null)
                .stream()
                .map(option -> {
                    return new ProductMultipleOptionviewmodel(
                            ProductOptionviewmodel.valueOf(//Access the option value//),//access the option value//
                    );
                })
                .collect(Collectors.toList());

使用上面的代码,我无法访问 map 方法中的选项值

如果 product.getProductMultipleOption() 为 null,则返回 null 或空列表。

解决方法

您应该很少同时使用 OptionalCollection(如 ListSet)。相反,您应该使用空的 Collection。还要记住 Optionals should not really be used for conditional logic,but rather as return values

使用普通的 if 语句:

List<ProductMultipleOptionViewModel> conveertItem = new ArrayList<>(); 
if (product.getProductMultipleOption() != null) {
   for(ProductMultipleOption option : product.getProductMultipleOption()) {
       conveertItem.add(new ProductMultipleOptionViewModel(
          ProductOptionViewModel.valueOf(option)
       ));
   }
}

另一种变体:

List<ProductMultipleOption> list = product.getProductMultipleOption();
if (list == null) {
    list = Collections.emptyList();
}
List<ProductMultipleOptionViewModel> conveertItem = new ArrayList<>(); 
for(ProductMultipleOption option : list) {
   conveertItem.add(new ProductMultipleOptionViewModel(
      ProductOptionViewModel.valueOf(option)
   ));
}

或者,如果您真的想使用 StreamOptional(个人喜好):

List<ProductMultipleOptionViewModel> conveertItem = Optional.ofNullable(product.getProductMultipleOption())
    .map(List::stream)
    .orElseGet(Stream::empty)
    .map(option -> new ProductMultipleOptionViewModel(
        ProductOptionViewModel.valueOf(option)
    ))
    .collect(Collectors.toList());

现在有很多代码可以简单地转换null可用的List。那么为什么不首先返回一个空的 List 呢?将 product.getProductMultipleOption() 更改为如下所示:

public List<ProductMultipleOption> getProductMultipleOption() {
    List<ProductMultipleOption> list = ...; // your current logic for getting the list
    return list == null ? Collections.emptyList() : list;
}

这样你就不必担心空检查。因为无论您在何处调用 getProductMultipleOption(),您都只是在处理一个空集合。

,

将处理空值/空选项与处理列表分开考虑会有所帮助。下面的代码使用 Optional.map() 方法处理空值,如果给定参数为空,该方法返回一个空的可选项(具有适当的返回类型);否则,应用列表上的映射函数。

Optional<List<ProductMultipleOptionViewModel>> convertedItem =
        Optional.ofNullable(product.getProductMultipleOption())
                .map(list -> list.stream()
                        .map(option -> new ProductMultipleOptionViewModel(
                                option.productOption(),option.optionName()))
                        .collect(Collectors.toList()));