有什么方法可以使此流更高效?

时间:2020-07-27 08:42:32

标签: java arraylist foreach java-stream

如何在不将值添加到新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);
                                                }
                                        );
                                    }
                                });

1 个答案:

答案 0 :(得分:0)

使用流时,最好不要修改流的源,而要在流的源上进行迭代。 (例如,请参见this。)

关于可读性和惯用的流操作,您的代码与普通的for循环几乎没有区别(我建议您将其更改为仅使用流来执行forEach的情况,但是您可以对其进行修改,以使用更短和更多的“原子”流操作链,如以下示例所示。

  • 获取至少包含一个单词 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());
    

(我假设您未在代码段中显示的listArrayList<String>。)

注释

  • 条件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()));
    }
}

输出:

[BAR, spam EGGS ham bAt, xxbazz]
[BAR, spam EGGS ham bAt]
[bar, bat, xxbazz]