2016-02-09 35 views
10

給定Map將字符串映射到List,是否有方法使用Java Streams返回布爾值,其中TRUE表示一個或多個列表有元素?如果地圖中的所有列表均爲空,則返回FALSE。如果映射中的所有列表值都爲空/非空,則使用流返回布爾值

Map< String , List<String> > map = … 

可以使用Streams替換這個傳統的代碼嗎?

// See if any diffs were found. Loop through the Map, look at each List of diffs to see if non-empty. 
boolean anyElementsInAnyList = false; 
for (List<String> list : map.values()) { 
    if (!list.isEmpty()) { 
     anyElementsInAnyList = true; 
     break; 
    } 
} 

請注意,我們可以在首次發現後突破檢查。無需檢查所有地圖值(所有列表)。如果出於效率考慮,Stream可以做同樣的停止首次查找(「短路」操作),那將會很好。

+1

你的意思是這個java-stream嗎? http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html –

+0

在你循環中使用布爾代替布爾值的任何理由? – Holger

回答

14

在Java 8中,您可以檢查並非所有列表都是空的。

boolean anyNonEmpty = !map.values().stream().allMatch(List::isEmpty); 
+1

使用'allMatch'與'anyMatch'相比,在[回答rgettman](http://stackoverflow.com/a/35282464/642706)中看到代碼的逆向有趣。在我看來,這種方法不能利用「短路」操作。所以它不像rgettman那樣會短路。 –

+5

@BasilBourque allMatch方法也是短路的。 – rgettman

+2

@Basil Bourque:不要按方法名稱去,通過[文檔](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#allMatch -java.util.function.Predicate-):「*這是一個短路終端操作。」*「 – Holger

7

使用the anyMatch method發現流的任何元素是否匹配Predicate。在這裏,你的謂詞是條目的值(列表)不是空的。

boolean anyNonEmpty = map.entrySet() 
    .stream() 
    .anyMatch(entry -> !entry.getValue().isEmpty()); 
+0

@hotkey你應該剛纔評論說我可以用'values'替換'entrySet',並且在謂詞中直接去'!list.isEmpty'。 – rgettman

+0

很好,謝謝!該文檔說這種方法是[短路終端操作](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps)。所以這個Stream應該有一些不檢查Map中的所有值的效率。顯然,根據[這個問題](http://stackoverflow.com/q/27235839/642706),我們甚至可以並行處理這個好處(多線程)。 –

+0

@rgettman,好的,對不起。 – hotkey

0
int size = Map.entrySet().stream() 
          .map(entry -> entry.getValue()) 
          .flatMap(list -> list.stream()) 
          .size(); 
if(size==0) 
    return Boolean.False; 
else 
    return Boolean.True; 

這段代碼是一個簡單的,這可能幫助你的工作。

+1

反對票?請留下您的評論意見和您的投票。這是一個堅實的答案,教育性的,有一個有趣的替代方法。不適合這個問題的場景,但對於稍有不同的場景的其他讀者可能會非常有用。 –

+2

我沒有downvote,但有一些明顯的事情要批評。首先,使用'Map'(容易與該名稱的類型混淆)而不是正確的變量名'map',那麼流過'entrySet()'僅僅映射到下一步,特別是因爲這個問題已經暗示了存在「values()」的可能性,因爲這個值可以放在第一位。而且,'Stream'中沒有'size()'方法,即使它存在,這裏也是浪費資源,因爲計算所有元素一般不能短路。不要說'返回大小== 0;'... – Holger

相關問題