从here开始,有一种方法可以获取嵌套Optional的值或默认值:
Optional<Computer> maybeComputer = Optional.of(computer);
String version = maybeComputer.flatMap(Computer::getSoundcard).flatMap(Soundcard::getUsb).map(USB::getVersion).orElse("UNKNOWN");
或
Computer computer = ...;
String version = computer.getSoundcard().flatMap(Soundcard::getUsb).map(USB::getVersion).orElse("UNKNOWN");
但是,如何获取所有收藏品计算机的所有版本? - List<Computer>
例如,如何使用stream
API 打印所有USB版本,包括unknown
?
或
如何将所有计算机映射到声卡的USB版本,包括unknown
个?
感谢。
计算机课程:
public static class Computer {
private Optional<Soundcard> soundcard;
public Computer(Optional<Soundcard> soundcard) {
this.soundcard = soundcard;
}
public Optional<Soundcard> getSoundcard() {
return soundcard;
}
}
public static class Soundcard {
private Optional<USB> usb;
public Soundcard(Optional<USB> usb) {
this.usb = usb;
}
public Optional<USB> getUsb() {
return usb;
}
}
public static class USB {
private String version;
public String getVersion() {
return version;
}
}
答案 0 :(得分:4)
只需对计算机列表进行流式处理,然后将适用于单个Optional<Computer>
的映射应用于每个计算机:
List<String> versions =
computers.stream()
.map(c -> Optional.ofNullable(c) // takes care of null elements in your List
.flatMap(Computer::getSoundcard)
.flatMap(Soundcard::getUsb)
.map(USB::getVersion)
.orElse("UNKNOWN"))
.collect(Collectors.toList());
答案 1 :(得分:0)
如果您想使用Stream API而不是Optional API执行这些步骤,可以使用
computers.stream()
.filter(Objects::nonNull)
// Java 9: .flatMap(c -> c.getSoundcard().stream())
.flatMap(c -> c.getSoundcard().map(Stream::of).orElseGet(Stream::empty))
// Java 9: .flatMap(s -> s.getUSB().stream())
.flatMap(s -> s.getUsb().map(Stream::of).orElseGet(Stream::empty))
.map(USB::getVersion)
.forEach(System.out::println);
不同之处在于它将跳过缺少的值而不是用默认值ala "UNKNOWN"
替换它们。无论如何,为“Soundcard的USB版”属性产生一个回落值"UNKNOWN"
是值得怀疑的,这实际上可能意味着“不是USB设备”或“没有声卡存在”...
如果您想保留原始逻辑,则必须通过流管道携带Optional
s,以便保留有关是否存在的信息:
computers.stream()
.map(Optional::ofNullable)
.map(oc -> oc.flatMap(Computer::getSoundcard))
.map(os -> os.flatMap(Soundcard::getUsb))
.map(os -> os.map(USB::getVersion))
.map(ou -> ou.orElse("UNKNOWN"))
.forEach(System.out::println);
这只是Eran’s answer的分解版本。请注意,这不一定比使用null
:
computers.stream()
.map(c -> c==null? null: c.getSoundcard().orElse(null))
.map(s -> s==null? null: s.getUsb().orElse(null))
.map(u -> u==null? "UNKNOWN": u.getVersion())
.forEach(System.out::println);