使用Streams替换For-Each循环

lil*_*s27 2 java foreach java-8 java-stream

我想使用Java 8 Streams替换以下for-each循环:

for (Rule rule : this.rules) {

    if (rule.getCondition().evaluate(rule, record)) {
        Records.emit(collector, outputStreamMapping.get(rule.getOutputStream()), tuple, recordId, record);
        collector.ack(tuple);

        ruleApplied = true;
        break;
    }
}

if (!ruleApplied) {
    LOGGER.warn("No rule was applied to record {}", record);
    LOGGER.debug("Rules: {}", this.rules);
    ErrorReporter.emitErrorNode(this.collector, recordId, componentName,
            "No matching rule for record " + record, record);
    collector.fail(tuple);
}
Run Code Online (Sandbox Code Playgroud)

我想迭代一组规则,并评估每个规则的条件.如果条件适用,我会对该记录采取行动并停止处理.如果没有应用规则,那么我想记录它并执行不同的记录处理.

不过,我不确定如何做到这一点.任何帮助和解释将不胜感激.

编辑:

我试过这个:

    this.rules.stream().filter(rule -> rule.getCondition().evaluate(rule, record)).forEach((rule) -> {
        Records.emit(collector, outputStreamMapping.get(rule.getOutputStream()), tuple, recordId, record);
        collector.ack(tuple);

        ruleApplied = true;
        break;
    });
Run Code Online (Sandbox Code Playgroud)

当然,它不喜欢break语句,并且还抱怨ruleApplied不是最终的,因为它被声明在lambda的范围之外.

基于我所看到的答案,似乎循环是最干净的方式.我不确定是否有其他流构造允许我以与在基本循环中所做的不同的方式封装逻辑(即,中断和跟踪布尔).

EDIT2:

以下是基于此主题建议的解决方案:

Optional<Rule> possibleRule = rules.stream().filter(rule -> rule.getCondition().evaluate(rule, record))
        .findFirst();

if (possibleRule.isPresent()) {
    Records.emit(collector, outputStreamMapping.get(possibleRule.get().getOutputStream()), tuple, recordId,
            record);
    collector.ack(tuple);
} else {
    LOGGER.warn("No rule was applied to record {}", record);
    LOGGER.debug("Rules: {}", this.rules);
    ErrorReporter.emitErrorNode(this.collector, recordId, componentName,
            "No matching rule for record " + record, record);
    collector.fail(tuple);
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*rey 6

你可以做

Optional<Rule> rule = rules.stream().
                       .filter(rule -> rule.getCondition().evaluate(rule, record))
                       .findFirst();
if (rule.isPresent()) {
    Records.emit(collector, outputStreamMapping.get(rule.get().getOutputStream()), 
                 tuple, recordId, record);
    collector.ack(tuple);

    ruleApplied = true;
}
Run Code Online (Sandbox Code Playgroud)

  • 您不需要单独的变量ruleApplied.如果没有应用规则,您想要执行的逻辑可以简单地放在else块中. (3认同)