将循环内的复杂条件逻辑转换为流和lambdas

时间:2015-03-20 15:02:21

标签: loops if-statement lambda java-8 java-stream

我正在寻找一种简洁的方法,将导致不同操作ifelse语句转换为lambdas和stream。 / p>

假设我有这段代码:

List<OuterData> result = new LinkedList<>();

for (Outer outer : getOutersFromSomewhere()) {
    OuterData outerData = new OuterData();

    if (outer.isImportant()) {
        doImportantAction(outer, outerData);
    } else if (outer.isTrivial()) {
        doTrivialAction(outer, outerData);
    } else {
        doDefaultAction(outer, outerData);
    }

    for (Inner inner : outer.getInners()) {
        if (inner.mustBeIncluded()) {
            InnerData innerData = new InnerData();

            if (inner.meetsCondition1()) {
                doAction1(inner, innerData, outer, outerData);
            } else if (inner.meetsCondition2()) {
                doAction2(inner, innerData, outer, outerData);
            } else {
                doDefaultAction(inner, innerData, outer, outerData);
            }
            outerData.add(innerData);
        }
    }
    result.add(outerData);
}

return result;

这比我的实际代码简化了。我知道它可以被优化和重构,即我可以将内部for移动到private方法。我想知道如何将ifelse ifelse部分翻译成溪流和lambdas。

我知道如何翻译这个例子的骨架。我使用List.stream()Stream.map()Stream.filter()Stream.collect()Stream.peek()。我的问题只是条件分支。我该怎么做这个翻译?

1 个答案:

答案 0 :(得分:5)

第一个显而易见的方法是流式传输元素,根据所需条件过滤元素,然后对每个剩余元素应用操作。这也使代码更清晰:

List<Outer> outers = getOutersFromSomewhere();
outers.stream().filter(Outer::isImportant)
    .forEach(outer -> doImportantAction(outer, outerDate));
outers.stream().filter(Outer::isTrivial)
    .forEach(outer -> doTrivialAction(outer, outerDate));
// default action analog

警告:仅当重要元素,普通元素和默认元素构成分区时才有效。否则它不等同于你的if-else结构。但也许这是打算......

这种方法的主要问题是:OOP不是很好。您正在查询对象以便做出决定。但是OOP应该是&#34;告诉,不要问&#34;尽可能多。

另一个解决方案是在Outer类中提供一种消费方法:

public class Outer {
    ...
    public void act(OuterData data, Consumer<Outer> importantAction,
            Consumer<Outer> trivialAction, Consumer<Outer> defaultAction) {
        if (isImportant())
            importantAction.accept(this, data);
        else if (isTrivial())
            trivialAction.accept(this, data);
        else
            defaultAction.accept(this, data);
    }
}

现在你称它为这么简单:

List<Outer> outers = getOutersFromSomewhere();
outers.forEach(outer -> outer.act(...)); // place consumers here (lambdas)

这有一个明显的优势:如果您必须为Outer课程添加功能 - 让我们说isComplex() - 您只需更改该单个班级的内部(并且可能解决其他部分的编译器故障)。或者,您可以以向后兼容的方式添加此功能。

相同的规则可以应用于Inner类和迭代。