簡體   English   中英

Java 8:使用嵌套的Optionals獲取集合的默認值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM