Java将一个可选类型转换为另一个可选类型

4
我是一名有用的助手,可以为您翻译文本。
我需要将一个Optional<EmployeeModel>对象转换为Optional<EmployeeDto>对象,并且我正在寻找比下面两个更好/更清晰的选项。 选项1:
public Optional<EmployeeDto> findById(String employeeId){
    Optional<EmployeeModel> employeeModel = employeeService.findById(employeeId);
    return Optional.ofNullable(toEmployeeDto(toEmployeeDto.orElse(null)));
}
private EmployeeDto toEmployeeDto(EmployeeModel employeeModel) {
    if(employeeModel != null) {//We need this because orElse passes null
        //return EmployeeDto (convert EmployeeModel to dto)
    } else {
        return null;
    }
}

选项2:

public Optional<EmployeeDto> findById(String employeeId){
    Optional<EmployeeModel> employeeModel = employeeService.findById(employeeId);
    if(employeeModel.isPresent()) {
        return Optional.of(toEmployeeDto(employeeModel.get()));
    } else {
        return Optional.empty();
    }
}
private EmployeeDto toEmployeeDto(EmployeeModel employeeModel) {
    //isPresent()check already done so no null checks
    //return EmployeeDto (convert EmployeeModel to dto)
}

我不能直接使用Optional.map(),因为EmployeeModel对象可能为空(即被Optional包装的null),来自employeeService。此外,我只是在检查Optional类内部的map()方法的源代码,它执行以下检查:

Objects.requireNonNull(mapper);

简而言之,我的问题是:我们可以将null对象传递给Optionalmap()方法吗?如果可以,为什么源代码中要进行Objects.requireNonNull()检查?

1
如果例如还有类似于 findBySomeOtherAttribute(String someValue) 的内容,那么Option1就是DRY的。如果它跨越多个类,那么if/else可以被提取到一个工厂类中。 - Andrew S
3
如果 employeeService.findById 返回一个 Optional 类型,然后返回 null 而不是 Optional.empty,那么 findById 是严重有缺陷的,需要进行修复。使用 Optional 的整个意义在于永远不返回 null - Andreas
@Andreas 同意。 - Naman
你对 Objects.requireNonNull(mapper) 有什么看法?当然,如果没有提供映射函数,你是无法调用 map() 的。 - Andreas
1
Objects.requireNonNull()在源代码中的作用是什么?”因为必须提供映射函数。这个空值检查不是检查对象(存储在Optional中的value字段),而是检查映射函数map方法的参数)。 - Andreas
1个回答

8
使用 Optional.map() 方法:
如果存在值,则将提供的映射函数应用于它,如果结果非空,则返回描述结果的 Optional。否则返回一个空的 Optional
public Optional<EmployeeDto> findById(String employeeId){
    Optional<EmployeeModel> employeeModel = employeeService.findById(employeeId);
    return employeeModel.map(this::toEmployeeDto);
}
private EmployeeDto toEmployeeDto(EmployeeModel employeeModel) {
    //employeeModel will not be null, so:
    //return EmployeeDto (convert EmployeeModel to dto)
}

1
如果employeeModel本身为null怎么办?难道不应该首先解决这个问题吗 - Naman
4
如果 employeeService.findById 返回的是 Optional 类型,但实际返回的是 null,而不是 Optional.empty,那么 findById 存在严重缺陷,需要修复。使用 Optional 的整个目的在于不返回 null - Andreas
@Andreas:我的employeeService只返回Optional类型,而不是null - developer
2
@开发者 然后按照这里所示的方式调用map。我不明白为什么你的问题说你不能使用map,因为这种情况恰恰是map的目的所在。 - Andreas
据我所知,Optional map() 会进行 Objects.requireNonNull() 检查,即我们只应传递非 null 对象。 - developer
2
@developer map 方法(参见 source)对 mapper 参数进行了空值检查,以确保提供了映射函数。它不会对包装对象(EmployeeModel)进行空值检查,因为在源代码中可以看到它对其进行了 isPresent() 检查。 - Andreas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接