有没有办法使用 Java 流从字符串的 ArrayList 中过滤符合条件的子字符串?

Is there a way to filter eligible substrings from an ArrayList of Strings using Java Streams?

有没有办法使用 Java Streams 实现此目的?

List<String> list = new ArrayList<>();
list.add("x=aa,y=bb,y=cc");
list.add("y=dd,z=ee,w=ff");
list.add("w=gg,w=hh,w=ii");

并且我想在 ArrayList 上方进行过滤以仅包含 'y' 类型的字符串值。喜欢下面

list=["bb","cc","dd"]

我能够使用多行代码使用 String.split(",") 并将符合条件的子字符串插入新的 ArrayList 来实现此目的。但是有没有一种干净的方法可以使用 Java Streams 来实现这一点?

你问过:

is there a clean way to achieve this using Java Streams?

是的。事实上,您可以处理您的输入,过滤掉不需要的部分,并生成一个完成的列表,所有这些都使用流。

首先定义一些示例数据,一个list of输入。

从该列表生成 stream。根据我们的示例数据,此流有 3 个元素。

调用 Stream#flatMap 到 return 一个新流,其元素由原始流的元素片段组成。新流有 9 个元素,通过将 3 个原始元素中的每一个分成 3 个部分(3 * 3 = 9)而产生。

Filter 文本以我们的目标 y= 前缀开头的元素的较新的较长流。

将每个通过过滤器 predicate test. Use simple string manipulation to replace“y=”的字符串元素转换为空字符串。因此 y=bb 等值变为 bb.

通过收集到一个新的 List 对象来收集转换后的字符串。

List < String > inputs =
        List.of(
                "x=aa,y=bb,y=cc" ,
                "y=dd,z=ee,w=ff" ,
                "w=gg,w=hh,w=ii"
        );
List < String > results =
        inputs
                .stream()                                                 // Generate stream whose elements are each of the list’s elements.
                .flatMap( input -> Arrays.stream( input.split( "," ) ) )  // Break each element into parts, feeding each part into a new longer stream.
                .filter( pairing -> pairing.startsWith( "y=" ) )          // Filter out any strings not beginning with `y=`. 
                .map( pairing -> pairing.replace( "y=" , "" ) )           // A value such as `y=bb` becomes `bb`.
                .toList();                                                // Collect transformed strings into a new list.

当运行.

results.toString() = [bb, cc, dd]

要按排序顺序排列结果,请在 toList() 之前添加对 .sorted() 的调用。

这是一种方法。

List<String> list = new ArrayList<>();
list.add("x=aa,y=bb,y=cc");
list.add("y=dd,z=ee,w=ff");
list.add("w=gg,w=hh,w=ii");
List<String> result = getListOf(list,"y");
System.out.println(result);

打印

[bb, cc, dd]
  • 流式传输字符串并在 ","
  • 上拆分
  • 然后拆分 "=" 上的那些 returns 数组,如 arr = [x,aa]
  • 然后过滤 arr[0] 和 return arr[1] 如果匹配。
  • 和return结果列表。
public static List<String> getListOf(List<String> items, String key) {
    return items.stream()
            .flatMap(str -> Arrays.stream(str.split(",")))
            .map(str -> str.split("="))
            .filter(s -> s[0].equals(key))
            .map(s -> s[1])
            .toList();
    
}

您可以使用 mapMulti 避免平面映射 (Java 16) 注意:从 答案中窃取了 startsWith 的想法。

public static List<String> getListOf(List<String> items, String key) {
     final String kk = key+"="; 
     return items.stream().<String>mapMulti((str,putOnStream)-> {
            for (String s : str.split(",")) {
                  if (s.startsWith(kk)) {    
                      putOnStream.accept(s.substring(kk.length()));
                  }
             }})
             .toList();
}