Java 8将for循环和值求和转换为流/ lambda?

问题描述

我正在遍历一些String输入,试图将其转换为java 8 stream / lambdas,但遇到了一些问题。我的样板代码如下:

public static int count(List<String> list) {
    String regex = "someRegexPatternHere"
    Pattern p = Pattern.compile(regex);
    int sum = 0;

    for (String val: list) {
        Matcher m = p.matcher(val);
        if (m.find()) {
            // summing logic here 
        }
    }
    return sum;
}

我正在尝试做类似的事情

list.stream()
    .filter(i -> p.matcher(i).find())
    .map(..............)
    ...

...但是无法得出汇总逻辑。谁能指出我正确的方向?

解决方法

您需要先应用matcher,然后对find 进行过滤

return inputs.stream()
             .map(p::matcher)
             .filter(Matcher::find)
             .map(m -> m.group(0))
             .mapToInt(Integer::parseInt)
             .sum();

使用lambda函数可以更清楚地看到它,但这是相同的

    return inputs.stream().map(input -> p.matcher(input))
                 .filter(matcher -> matcher.find())
                 .map(m -> m.group(0))
                 .mapToInt(s -> Integer.parseInt(s)).sum();
,

由于Matcher的逻辑,这是一个棘手的问题。我会这样写

list.stream()
 .map(p::matcher)
 .filter(Matcher::find)
 .mapToInt(m -> Integer.parseInt(m.group(0))
 .sum();
,

您非常亲密。用count()替换map(),该方法返回一个long。

long count = list.stream().filter(s -> p.matcher(s).find()).count();
,

只要您引用起源于的Stream API功能(而不是特定版本本身),就让我为您介绍使用Java较新版本的方法。

Java 9 +

从Java的较新版本开始,您可以在Matcher类上使用方法,直接返回结果流。

为匹配模式的输入序列的每个子序列返回匹配结果流。匹配结果的顺序与输入序列中匹配子序列的顺序相同。

Flatmap可以执行以下操作:

int sum = list.stream()
    .map(p::matcher)
    .flatMap(Matcher::results)
    .mapToInt(mr -> Integer.parseInt(mr.group(0)))
    .sum();

...或更短:

int sum = list.stream()
    .flatMap(string -> pattern.matcher(string).results())
    .mapToInt(mr -> Integer.parseInt(mr.group(0)))
    .sum();

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...