[英]Any way to make this stream more efficient?
如果不向新的 ArrayList 增加價值,而只是更新原始列表,如何優化這一點?
String filterval = filter.toLowerCase();
ArrayList<String> filtredArr = new ArrayList<String>();
listArray.forEach(
valueText -> {
String val = valueText.toLowerCase();
if (val.startsWith(filterval) || val.contains(filterval))
filtredArr.add(valueText);
else {
Arrays.stream(valueText.split(" ")).forEach(
singleWord -> {
String word = singleWord.toLowerCase();
if(word.startsWith(filterval) || word.contains(filterval))
filtredArr.add(valueText);
}
);
}
});
使用流時,最好不要修改 stream 的源,而后者會迭代前者。 (例如看這個。)
關於可讀性和慣用 stream 操作,您的代碼與普通的舊 for 循環幾乎沒有區別(如果您只使用流來執行forEach
,我建議您將其更改為,但您可以修改它以使用更短且更“原子”的 stream 操作鏈,如下例所示。
要獲取至少一個單詞包含filterval
的字符串列表:
List<String> filtered = listArray.stream().filter(str -> str.toLowerCase().contains(filterval)).collect(Collectors.toList());
要獲取至少一個單詞以filterval
開頭的字符串列表:
List<String> filtered = listArray.stream().filter(str -> Arrays.stream(str.split(" ")).map(String::toLowerCase).anyMatch(word -> word.startsWith(filterval))).collect(Collectors.toList());
要獲取包含過濾器值的單詞列表(在任何字符串中):
List<String> filteredWords = listArray.stream().map(String::toLowerCase).flatMap(str -> Arrays.stream(str.split(" "))).filter(word -> word.contains(filterval)).collect(Collectors.toList());
(我假設您未在代碼片段中顯示的listArray
是List<String>
。)
val.startsWith(filterval) || val.contains(filterval)
val.startsWith(filterval) || val.contains(filterval)
完全等同於val.contains(filterval)
。 原因是,如果一個字符串以filterval
,它也一定意味着它包含它; 一個暗示另一個。split
應用於所有它們,然后使用filterMap
將單詞序列“連接”起來。import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
String filterval = "ba";
List<String> listArray = List.of("foo", "BAR", "spam EGGS ham bAt", "xxbazz");
List<String> filtered1 = listArray.stream()
.filter(str -> str.toLowerCase().contains(filterval))
.collect(Collectors.toList());
List<String> filtered2 =
listArray.stream()
.filter(str -> Arrays.stream(str.split(" "))
.map(String::toLowerCase)
.anyMatch(word -> word.startsWith(filterval)))
.collect(Collectors.toList());
List<String> filtered3 = listArray.stream()
.map(String::toLowerCase)
.flatMap(str -> Arrays.stream(str.split(" ")))
.filter(word -> word.contains(filterval))
.collect(Collectors.toList());
System.out.println(Arrays.toString(filtered1.toArray()));
System.out.println(Arrays.toString(filtered2.toArray()));
System.out.println(Arrays.toString(filtered3.toArray()));
}
}
Output:
[BAR, spam EGGS ham bAt, xxbazz]
[BAR, spam EGGS ham bAt]
[bar, bat, xxbazz]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.