当前位置: 首页 > 知识库问答 >
问题:

有什么方法可以让这条流更有效率吗?

漆雕育
2023-03-14

如果不向新的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个答案

赵嘉悦
2023-03-14

当使用流时,最好不要修改流的源,而后者迭代前者。例如,请参阅此。)

关于可读性和流操作的惯用用法,您的代码与普通的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());
    

    (我假设listArray是一个List,你不会在代码片段中显示它

    • 条件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]
    

  •  类似资料:
    • 这里的图片显示了我当前的问题,我尽最大努力修改路径。JAVA\u HOME的路径是正确的,但我一直很困惑,因为它总是显示出来,即使我已经修改了它。如果我尝试放置SDK的目录路径,则会出现相同的错误。 图像链接:https://i.stack.imgur.com/LeipD.png

    • 材料设计非常强调“纸张”的隐喻。要做到这一点,阴影是必不可少的。由于材料设计是一种理念,而不是API(尽管它内置在L中),因此应该在任何地方(Windows窗体、HTML/CSS等)进行设计。如何在Android API 14到20中做到这一点? 请注意,对于圆形和其他非方形形状,预制PNG实际上并不实用。

    • 问题内容: 我有一个使用XML和反射将 s 返回到另一个类的类。 通常,这些对象是外部对象的子字段,但有时我想即时生成它。我已经尝试过类似的方法,但无济于事。我相信这是因为Java不允许你访问进行反射的方法。 如果提供的方法失败,则失败。我可以通过制作方法来解决它,或者制作另一个类来派生它。 长话短说,我只是想知道是否存在一种通过反射访问方法的方法。 问题答案: 你可以使用反射调用私有方法。修改已

    • 情况 我应该显示200-350帧动画在我的应用程序。图像有500x300ish分辨率。如果用户想分享动画,我必须转换成视频。对于转换,我使用ffmpeg命令。 null 问题 有什么方法(库(甚至是本机))可以使保存过程更快。 有没有办法将Byte[]或位图对象(我指的是解压缩为Android位图类对象的png文件)传递给ffmpeg库视频创建方法 是否有其他工作库可以在大约30秒内(对于200帧

    • 我正在处理一个大型医学数据集,我想看看是否有一些行对应于同一个患者。与患者 ID 对应的列是 。 我想创建一个新列,如果该患者出现在多行中,它将是“是”,如果它只出现一次,它将 这是我做的代码: 但是这个操作太花时间了。有什么方法可以做得更快吗?