在 Optional<List<Entity>> 的情况下 orElseGet 如何工作
How does orElseGet work in case of an Optional<List<Entity>>
我有一个 class 的可选列表,即:Optional<List<MyEntity>> opListEntity
当 Optional 存在时,我需要将所有 MyEntity
映射到 MyEntityDto
。如果 Optional 为空,我将 return 一个空的 ArrayList.
方法 1(非功能性):
注:myEntityMapper
是映射器class的一个对象,它将MyEntity
映射到MyEntityDto
。
List<MyEntityDto> res;
if (opListEntity.isPresent()) {
res = opListEntity.get().stream()
.map(myEntityMapper::entityToDto)
.collect(Collectors.toList());
} else {
res = new ArrayList<>();
}
这种方法很好,但 IntelliJ 建议将其转换为函数式表达式。我让 IntelliJ 进行转换,这就是我得到的:
方法二(函数表达式):
List<MyEntityDto> res = opListEntity.map(myEntities -> myEntities.stream()
.map(myEntityMapper::entityToDto)
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
我不明白的是,在方法 2 @ line 1 中,为什么会有地图?
让我再解释一下。参见第三种方法:
方法三:
List<CustomerAddressEntity> myEntities = opListEntity
.orElseGet(ArrayList::new);
List<MyEntityDto> res = myEntities.stream()
.map(myEntityMapper::entityToDto)
.collect(Collectors.toList());
方法 3 工作正常,但如果我尝试将方法 3 转换为方法 4,它不起作用。
方法四:
List<MyEntityDto> res = opListEntity.stream()
.map(myEntityMapper::entityToDto)
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
为什么 方法 4 不起作用但 方法 2 有效?
map 在 approach 2 @ line 1 中做什么?
我认为如果您将代码缩进一点以使其更容易发现,就会变得很明显:
List<MyEntityDto> res = opListEntity // Optional<List<MyEntity>>
.map(
myEntities -> myEntities.stream() // Stream<MyEntity>
.map(myEntityMapper::entityToDto) // Stream<MyEntityDto>
.collect(Collectors.toList()) // List<MyEntityDto>
)
.orElseGet(ArrayList::new); // List<MyEntityDto>
即 Optional
(如果存在)映射到将包含的列表转换为流、映射元素并构建集合的结果,或者(如果为空)映射到新的空列表。
在您的第 4 种方法中 opListEntity
是类型 Optional<List<MyEntity>>
。现在它取决于您使用的 JDK 版本。在 JDK8 Optional
中没有 stream()
方法。
List<MyEntityDto> res = opListEntity.stream() // there is no such method in JDK8
...
自 JDK9 以来有一个 stream()
方法,但它当然会 return Stream<List<MyEntity>>
因为这是 Optional
的类型。但是要使映射正常工作,您需要 Stream<MyEntity>
。为此,您可以使用 flatMap
方法映射 returned 流:
List<MyEntityDto> res = opListEntity.stream() // Stream<List<MyEntity>>
.flatMap(List::stream) // Stream<MyEntity>
.map(myEntityMapper::entityToDto)
...
我有一个 class 的可选列表,即:Optional<List<MyEntity>> opListEntity
当 Optional 存在时,我需要将所有 MyEntity
映射到 MyEntityDto
。如果 Optional 为空,我将 return 一个空的 ArrayList.
方法 1(非功能性):
注:myEntityMapper
是映射器class的一个对象,它将MyEntity
映射到MyEntityDto
。
List<MyEntityDto> res;
if (opListEntity.isPresent()) {
res = opListEntity.get().stream()
.map(myEntityMapper::entityToDto)
.collect(Collectors.toList());
} else {
res = new ArrayList<>();
}
这种方法很好,但 IntelliJ 建议将其转换为函数式表达式。我让 IntelliJ 进行转换,这就是我得到的:
方法二(函数表达式):
List<MyEntityDto> res = opListEntity.map(myEntities -> myEntities.stream()
.map(myEntityMapper::entityToDto)
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
我不明白的是,在方法 2 @ line 1 中,为什么会有地图?
让我再解释一下。参见第三种方法:
方法三:
List<CustomerAddressEntity> myEntities = opListEntity
.orElseGet(ArrayList::new);
List<MyEntityDto> res = myEntities.stream()
.map(myEntityMapper::entityToDto)
.collect(Collectors.toList());
方法 3 工作正常,但如果我尝试将方法 3 转换为方法 4,它不起作用。
方法四:
List<MyEntityDto> res = opListEntity.stream()
.map(myEntityMapper::entityToDto)
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
为什么 方法 4 不起作用但 方法 2 有效?
map 在 approach 2 @ line 1 中做什么?
我认为如果您将代码缩进一点以使其更容易发现,就会变得很明显:
List<MyEntityDto> res = opListEntity // Optional<List<MyEntity>>
.map(
myEntities -> myEntities.stream() // Stream<MyEntity>
.map(myEntityMapper::entityToDto) // Stream<MyEntityDto>
.collect(Collectors.toList()) // List<MyEntityDto>
)
.orElseGet(ArrayList::new); // List<MyEntityDto>
即 Optional
(如果存在)映射到将包含的列表转换为流、映射元素并构建集合的结果,或者(如果为空)映射到新的空列表。
在您的第 4 种方法中 opListEntity
是类型 Optional<List<MyEntity>>
。现在它取决于您使用的 JDK 版本。在 JDK8 Optional
中没有 stream()
方法。
List<MyEntityDto> res = opListEntity.stream() // there is no such method in JDK8
...
自 JDK9 以来有一个 stream()
方法,但它当然会 return Stream<List<MyEntity>>
因为这是 Optional
的类型。但是要使映射正常工作,您需要 Stream<MyEntity>
。为此,您可以使用 flatMap
方法映射 returned 流:
List<MyEntityDto> res = opListEntity.stream() // Stream<List<MyEntity>>
.flatMap(List::stream) // Stream<MyEntity>
.map(myEntityMapper::entityToDto)
...