2017-06-15 47 views
5

我從一個不受我控制的服務中獲得一個映射,該映射可能爲null,並且想要處理它,比方說,篩選,映射並減少到我需要的單個元素。使用基於內容的流<Map>

問:有沒有從「可選」到「流」的「鏈接」?

我試過(除其他事項外):

return Optional.ofNullable(getMap()) 
    .map(Map::entrySet) // gets the entryset 
    .map(Stream::of) 
    .orElseGet(Stream::empty) 
    // i would then like to continue with 
    .filter(e -> e.getKey().startsWith("f") 
    .map(Entry::getValue) 
    .findFirst(); 

但後來我得到不Stream<Entry>Stream<Set<Entry>> ......有沒有辦法以某種方式flatMap集合或映射出一個可選的?

注意:我對流利的純流/可選方法感興趣。當然,當我將地圖保存到本地變量並確保它不爲空時它是有效的。

+0

cast stream to Stream ?不,我不能。 –

+7

你應該考慮改變你的getMap()來返回一個空映射而不是null。那麼你就不會把它包裝在'Optional'中,而且你很容易避免這樣的問題。正如[Stuart Marks](https://stackoverflow.com/users/1441122/stuart-marks)所說的那樣[Rule#4:爲了從中鏈接方法的特定目的而創建一個'Optional'通常是個不錯的主意以獲得價值。](https://youtu.be/Ej0sss6cq14?t=27m55s)。 –

+3

在Java 9中,['Optional'將有'stream()'方法](http://download.java.net/java/jdk9/docs/api/java/util/Optional.html#stream--) ,你可以簡單地做:'Optional.ofNullable(getMap()).map(Map :: entrySet).stream()。flatMap(Set :: stream)...' –

回答

8

你的錯誤是在這條線:

.map(Stream::of) 

of函數採用單個參數(或可變參數參數),並且僅與該元件返回的流。您將因此獲得Stream<Set<Map.Entry>>。相反,你應該調用入口集上的流方法,像這樣:

.map(Set::stream) 
0

我想我要回答這個問題。

return Optional.ofNullable(getMap()) 
    .map(Map::entrySet) // gets the entryset 
    .map(Stream::of) 
    .orElseGet(Stream::empty) 
    // i would then like to continue with 
    .filter(e -> e.getKey().startsWith("f") 
    .map(Entry::getValue) 
    .findFirst(); 

我生病了,生病時我看到上面的代碼。以流暢的方式編寫代碼,而不是編寫簡單的代碼真的非常重要嗎?首先,正如@迪迪埃L在評論中提到的那樣,使用Optional是錯誤的方法。其次,代碼很難閱讀,不是嗎?如果你用定義一個局部變量來編寫它:

Map<String, Integer> map = getMap(); 

return map == null ? Optional.<Integer> empty() 
        : map.entrySet().stream() 
         .filter(e -> e.getKey().startsWith("f")).map(Entry::getValue).findFirst(); 

不是很清楚嗎?或者你也可以用StreamEx做,如果你不能得到比不使用流利的做法:

StreamEx.ofNullable(getMap()) 
     .flatMapToEntry(Function.identity()) 
     .filterKeys(k -> k.startsWith("f")).values().findFirst(); 

或我的圖書館AbacusUtil

EntryStream.of(getMap()).filterByKey(k -> k.startsWith("f")).values().first(); 

總是試圖尋找一個更好的方法,如果事情被卡住了。