在文件流上应用模式

Tob*_*ias 5 java lambda java-8

public final Pattern PATTERN = Pattern.compile("<abc:c\\sabc:name=\"(\\S+)\"\\sabc:type=\"(\\S+)\">");
    try (Stream<String> stream = Files.lines(template.getPath())) {
        stream.filter(s -> PATTERN.matcher(s).find()).forEach(System.out::println);

    } catch (IOException e) {
        e.printStackTrace();
    }
Run Code Online (Sandbox Code Playgroud)

该模式工作正常,但我如何捕获/获取我的组?目前我只得到弦乐.

Tun*_*aki 7

如果选择应用模式只出现1次的线,可以映射你Stream<String>Stream<Matcher>,过滤与该模式匹配的线和最后通过将它们存储在一个阵列中提取的组1和2.

try (Stream<String> stream = Files.lines(Paths.get(""))) {
    stream.map(PATTERN::matcher)
          .filter(Matcher::find)
          .map(m -> new String[] { m.group(1), m.group(2) })
          .forEach(a -> System.out.println(Arrays.toString(a)));
} catch (IOException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

如果模式出现多次,我们需要遍历Matcher直到find()返回false.在这种情况下,我们可以

try (Stream<String> stream = Files.lines(Paths.get(""))) {
    stream.map(PATTERN::matcher)
          .flatMap(m -> {
              List<String[]> list = new ArrayList<>();
              while (m.find()) {
                  list.add(new String[] { m.group(1), m.group(2) });
              }
              return list.stream();
          })
          .forEach(a -> System.out.println(Arrays.toString(a)));
Run Code Online (Sandbox Code Playgroud)

在Java 9中,可能有一种新方法Matcher.results()来检索Stream<MatchResult>结果.这里我们可以用它代替带有2个单独findgroup操作.

  • 另外(仅限Java 9)参见[`Scanner.findAll()`](http://download.java.net/jdk9/docs/api/java/util/Scanner.html#findAll-java.util.regex.Pattern - )得到一个`Stream <MatchResult>`.扫描仪可以直接读取文件,避免基于行的读取及其限制. (5认同)
  • 这就是为什么我说*潜在的*.对于少量元素,`ArrayList`和`Stream.Builder`之间没有区别,对于更大的数字,构建器获胜.由于'ArrayList`的默认容量是10,这是小和大之间的阈值......哦,好吧,构建器只有一个元素的特殊情况,这可能比这里更大的元素计数优化更相关. (2认同)