我有一個流,我想根據條件提取一個值:
- 如果任何匹配條件A首先找到匹配A
- 否則,如果任何匹配條件 B 首先找到匹配 B
- 否則,如果任何匹配條件 C 首先找到匹配 C
- 否則為空
例如 :
Stream<String> stream0 = Stream.of("a", "b", "c", "d");
Stream<String> stream1 = Stream.of("b", "c", "d", "a");
Stream<String> stream2 = Stream.of("b", "c", "d", "e");
Stream<String> stream3 = Stream.of("d", "e", "f", "g");
findBestValue(stream0); //should return "a"
findBestValue(stream1); //should return "a"
findBestValue(stream2); //should return "b"
findBestValue(stream3); //should return null
我嘗試了以下,但回傳一個java.lang.IllegalStateException: stream has already been operated upon or closed
private static String findBestValue(Stream<String> stream) {
return stream.filter(str -> str.equals("a"))
.findFirst()
.orElse(stream.filter(str -> str.equals("b"))
.findFirst()
.orElse(stream.filter(str -> str.equals("c"))
.findFirst()
.orElse(null))
);
}
知道如何存檔嗎?
注意:a、b、c 僅用于我不能使用 .sort() 的示例
uj5u.com熱心網友回復:
一旦流被消耗 - 它就完成了,你不能再使用它了。否則,你會得到一個IllegalStateException
.
因為 Stream 是資料源迭代的平均值,而不是資料的容器。
這是來自API 檔案的參考:
流在以下幾個方面與集合不同:
- 沒有存盤。流不是存盤元素的資料結構;相反,它通過計算操作的管道從資料結構、陣列、生成器函式或 I/O 通道等源傳送元素。
您可以將傳入的流資料存盤到一個集合中,然后與之互動。作為一個集合,我們可以使用 a LinkedHashMap
(例如,帶有字串的集合就足夠了,但是如果我們生成代碼,則映射對于處理與字串相反的復雜物件很有用,即使它們相等也不一定相同) .
這就是它可以在不使用硬編碼條件的情況下實作的方式:
private static <T> T findBestValue(Stream<T> stream,
T key1, T key2, T key3) {
Map<T, T> map = stream.collect(Collectors.toMap(
Function.identity(),
Function.identity(),
(l, r) -> l, // preserve the first value - precaution against duplicates
LinkedHashMap::new
));
return Stream.of(map.get(key1), map.get(key2), map.get(key3))
.filter(Objects::nonNull)
.findFirst()
.orElse(null); // NOTE that it's NOT the most recommended option (we can return Optional itself or use methods like orElseThrow())
}
我們可以讓這個方法期望一個可變引數鍵:
private static <T> T findBestValue(Stream<T> stream,
T... keys) {
Map<T, T> map = stream.collect(Collectors.toMap(
Function.identity(),
Function.identity(),
(l, r) -> l,
LinkedHashMap::new
));
return Arrays.stream(keys)
.map(map::get)
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
}
main()
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("a", "b", "c", "d");
Stream<String> stream2 = Stream.of("b", "c", "d", "e");
Stream<String> stream3 = Stream.of("d", "e", "f", "g");
System.out.println(findBestValue(stream1, "a", "b", "c")); //should return "a"
System.out.println(findBestValue(stream2, "a", "b", "c")); //should return "b"
System.out.println(findBestValue(stream3, "a", "b", "c")); //should return null
}
輸出:
a
b
null
uj5u.com熱心網友回復:
這里對錯誤的很好解釋: https ://www.baeldung.com/java-stream-operated-upon-or-closed-exception
基本上,您只能運行一次流。
如果您真的想這樣做,請嘗試:
private static String findBestValue(List<String> list) {
return list.stream().filter(str -> str.equals("a"))
.findFirst()
.orElse(list.stream().filter(str -> str.equals("b"))
.findFirst()
.orElse(list.stream().filter(str -> str.equals("c"))
.findFirst()
.orElse(null)));
}
uj5u.com熱心網友回復:
@Alexander Ivanchenko 的解決方案也可以寫成
private static <T> T findBestValue(Stream<T> stream, T... keys) {
Set<T> set = stream.collect(Collectors.toSet());
return Stream.of(keys)
.filter(set::contains)
.findFirst()
.orElse(null);
}
public static void main(String[] args) {
Stream<String> stream0 = Stream.of("a", "b", "c", "d");
Stream<String> stream1 = Stream.of("b", "c", "d", "a");
Stream<String> stream2 = Stream.of("b", "c", "d", "e");
Stream<String> stream3 = Stream.of("d", "e", "f", "g");
System.out.println(findBestValue(stream0, "a", "b", "c")); //should return "a"
System.out.println(findBestValue(stream1, "a", "b", "c")); //should return "a"
System.out.println(findBestValue(stream2, "a", "b", "c")); //should return "b"
System.out.println(findBestValue(stream3, "a", "b", "c")); //should return null
}
輸出:
a
a
b
null
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/529597.html
標籤:爪哇java流
上一篇:JavaFX-自動完成文本欄位,僅建議以輸入開頭的匹配項(SuggestionProvider不可訪問)
下一篇:用數字多次替換文字