Fed*_*ner 5 lambda loops if-statement java-8 java-stream
我正在寻找一种简洁的方法来将复杂的逻辑条件if和导致不同操作的else语句转换为lambda和流.
假设我有这个代码:
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;
Run Code Online (Sandbox Code Playgroud)
这比我的实际代码简化了.我知道它可以被优化和重构,即我可以将内部移动for到private方法.我想知道如何翻译if,else if以及else部分流和lambda表达式.
我知道如何翻译这个例子的骨架.我会使用List.stream(),Stream.map(),Stream.filter(),Stream.collect()和Stream.peek().我的问题只是条件分支.我该怎么做这个翻译?
第一个显而易见的方法是流式传输元素,根据所需条件过滤它们,然后对每个剩余元素应用操作.这也使代码更清晰:
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
Run Code Online (Sandbox Code Playgroud)
警告:仅当重要元素,普通元素和默认元素构成分区时才有效.否则它不等同于你的if-else结构.但也许这是打算......
这种方法的主要问题是:OOP不是很好.您正在查询对象以便做出决定.但OOP应尽可能"告诉,不要问".
所以另一种解决方案是在你的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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在你称它为这么简单:
List<Outer> outers = getOutersFromSomewhere();
outers.forEach(outer -> outer.act(...)); // place consumers here (lambdas)
Run Code Online (Sandbox Code Playgroud)
这有一个明显的优势:如果你必须为你的Outer类添加一个功能- 比方说isComplex()- 你只需要改变那个单一类的内部(并且可能解决其他部分的编译失败).或者,您可以以向后兼容的方式添加此功能.
可以将相同的规则应用于Inner类和迭代.