![](/img/trans.png)
[英]Converting traditional nested if else condition to java 8 optionals efficiently
[英]Java 8 : getting default values for a collection with nested Optionals
從這里開始 ,有一種獲取嵌套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
?
要么
如何將所有計算機(包括unknown
計算機)映射到其聲卡的USB版本?
謝謝。
電腦課:
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;
}
}
只需流式傳輸計算機列表,然后將與應用於單個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());
如果要使用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"
代替它們。 無論如何,為屬性“聲卡的USB版本”生成一個后備值"UNKNOWN"
,實際上可能意味着“不是USB設備”或“不存在聲卡”……
如果要保留原始邏輯,則必須在流管線中攜帶Optional
,以便保留有關存在或不存在的信息:
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答案的分解版本。 請注意,這不一定比僅使用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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.