在执行.findFirst()之前对所有值进行操作

时间:2018-02-27 16:29:40

标签: java java-stream

我有以下代码(val tb = runtimeMirror(this.getClass.getClassLoader).mkToolBox() val tree = tb.parse(script) val transformedTree = transform(tree) // I'm keeping a script engine around during the session to use val engine:ScriptEngine = globals.scriptEngine // Is there a way to do this: engine.eval(transformedTree) TrResponse的代码无关紧要):

TrNode

我试图找出如何为所有public TrResponse from(final TrNode b1, final TrNode b2, final TrNode b3) { final TrResponse resp = new TrResponse(); Stream.of(b1, b2, b3) .filter(Objects::nonNull) .findFirst() .ifPresent(it -> { resp.m1 = it.m1; resp.m2 = it.m2; resp.m3 = it.m3; }); // b1, b2 or b3 can be null // normalize() returns a mutated TrNode resp.b1 = (null != b1) ? b1.normalize() : null; resp.b2 = (null != b2) ? b2.normalize() : null; resp.b3 = (null != b3) ? b3.normalize() : null; return resp; } normalizeb1执行b2函数(最终不是b3)在同一个流操作中,所以我以后不必进行null次检查(正如我现在所做的那样)。我在null之前尝试.map(TrNode::normalize),但最终只将其应用于第一个找到的实例(如果有的话)。

任何线索?

2 个答案:

答案 0 :(得分:2)

findFirst正在做这里应该做的事情。这是一个short-circuiting terminal operation

您可以编写自己的收集器,它只接受第一个元素并忽略其他所有元素。 collect不会短路,因此会处理每个元素。然后,您可以按照惯例使用map

class FirstNode
{
    private TrNode node;

    public void setNode(final TrNode node)
    {
        if (this.node == null)
        {
            this.node = node;
        }
    }

    public Optional<TrNode> first()
    {
        return Optional.ofNullable(node);
    }
}

Stream.of(b1, b2, b3)
    .map(TrNode::normalize)
    .filter(Objects::nonNull)
    .collect(
        Collector.of(
            FirstNode::new,
            FirstNode::setNode,
            (node, node2) -> node
        )
    )
    .first()
    .ifPresent(it -> {
        resp.m1 = it.m1;
        resp.m2 = it.m2;
        resp.m3 = it.m3;
    });

但这比你现在的更好还是更具可读性?并不是的。同样值得注意的是,你将对所有事情进行规范化 - 这是必需的还是可取的?

答案 1 :(得分:1)

b2b3resp.b1 = (null != b1) ? b1.normalize() : null; resp.b2 = (null != b2) ? b2.normalize() : null; resp.b3 = (null != b3) ? b3.normalize() : null; 不是集合,而是对象的各个字段。
您想如何应用流操作?

只需替换此重复代码:

TrResponse

通过辅助方法。

就个人而言,我会在resp.setNormalizedOrNull(b1, b2, b3); 中提供具体方法,以便能够以这种方式应用规范化方法:

setNormalizedOrNull

public void setNormalizedOrNull(TrNode b1, TrNode b2, TrNode b3){ this.b1 = getNormalizedOrNull(b1); this.b2 = getNormalizedOrNull(b2); this.b3 = getNormalizedOrNull(b3); } // helper method : private TrNode getNormalizedOrNull(TrNode node){ return null != node ? node.normalize() : null; } 定义为:

checked