连接可选列表
Concatenate Optional Lists
我有三个 Optional> 必须合并并返回。我尝试使用 Optional.map()
和 flatmap()
但没有成功。
public Optional<List<Entiy>> getRecords() {
Optional<List<Entiy>> entity1 = repo.findAllByStatus("1");
Optional<List<Entiy>> entity2 = repo.findAllByStatus("2");
Optional<List<Entiy>> entity3 = repo.findAllByStatus("3");
//Need to return a concatenation of entity1, 2 and 3
}
关于如何高效地做事有什么想法吗?
类似于:
return Optional.of(Stream.of(entity1.orElse(new ArrayList<>()), entity2.orElse(new ArrayList<>()), entity3.orElse(new ArrayList<>()))
.flatMap(List::stream)
.collect(Collectors.toList()));
或者更可读:
return Optional.of(Stream.of(entity1, entity2, entity3)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(List::stream)
.collect(Collectors.toList()));
使用流时会变得更容易:
return Stream.of(entity1, entity2, entity3)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(List::stream)
.collect(Collectors.collectingAndThen(Collectors.toList(), Optional::of));
重要的是要注意这个可选的永远不会是空的。它将至少包含一个空列表,这违背了使用可选值的目的。当使用 Collection
类型作为 return 类型时,Optional
并没有真正被使用,因为它被推荐给 return 一个 empty 集合,其中一个空可选的将被使用。
所以我只是将方法的 return 类型更改为 List
并在没有输入可选 present[=22 时让流 return 成为一个空列表=].
我建议您不要从您的方法中 return Optional
。如果三个实体列表中的任何一个都没有记录,调用者宁愿只拥有一个空列表。
public List<Entity> getRecords() {
return Stream.of("1", "2", "3")
.map(repo::findAllByStatus)
.flatMap(el -> el.map(List::stream).orElse(Stream.empty()))
.collect(Collectors.toList());
}
其他几个答案使用 isPresent
和 get
。它们是低级的,我们这里不需要它们。
不过,我们并不是绝对需要流操作。没有它的可能性是:
public List<Entity> getRecords() {
List<Entity> concatenation = new ArrayList<>();
repo.findAllByStatus("1").ifPresent(concatenation::addAll);
repo.findAllByStatus("2").ifPresent(concatenation::addAll);
repo.findAllByStatus("3").ifPresent(concatenation::addAll);
return concatenation;
}
我有三个 Optional> 必须合并并返回。我尝试使用 Optional.map()
和 flatmap()
但没有成功。
public Optional<List<Entiy>> getRecords() {
Optional<List<Entiy>> entity1 = repo.findAllByStatus("1");
Optional<List<Entiy>> entity2 = repo.findAllByStatus("2");
Optional<List<Entiy>> entity3 = repo.findAllByStatus("3");
//Need to return a concatenation of entity1, 2 and 3
}
关于如何高效地做事有什么想法吗?
类似于:
return Optional.of(Stream.of(entity1.orElse(new ArrayList<>()), entity2.orElse(new ArrayList<>()), entity3.orElse(new ArrayList<>()))
.flatMap(List::stream)
.collect(Collectors.toList()));
或者更可读:
return Optional.of(Stream.of(entity1, entity2, entity3)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(List::stream)
.collect(Collectors.toList()));
使用流时会变得更容易:
return Stream.of(entity1, entity2, entity3)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(List::stream)
.collect(Collectors.collectingAndThen(Collectors.toList(), Optional::of));
重要的是要注意这个可选的永远不会是空的。它将至少包含一个空列表,这违背了使用可选值的目的。当使用 Collection
类型作为 return 类型时,Optional
并没有真正被使用,因为它被推荐给 return 一个 empty 集合,其中一个空可选的将被使用。
所以我只是将方法的 return 类型更改为 List
并在没有输入可选 present[=22 时让流 return 成为一个空列表=].
我建议您不要从您的方法中 return Optional
。如果三个实体列表中的任何一个都没有记录,调用者宁愿只拥有一个空列表。
public List<Entity> getRecords() {
return Stream.of("1", "2", "3")
.map(repo::findAllByStatus)
.flatMap(el -> el.map(List::stream).orElse(Stream.empty()))
.collect(Collectors.toList());
}
其他几个答案使用 isPresent
和 get
。它们是低级的,我们这里不需要它们。
不过,我们并不是绝对需要流操作。没有它的可能性是:
public List<Entity> getRecords() {
List<Entity> concatenation = new ArrayList<>();
repo.findAllByStatus("1").ifPresent(concatenation::addAll);
repo.findAllByStatus("2").ifPresent(concatenation::addAll);
repo.findAllByStatus("3").ifPresent(concatenation::addAll);
return concatenation;
}