我具有内部节点和终端节点的树状结构:
public interface Node
{
}
public class InternalNode implements Node {
private List<Node> nodes;
}
public class TerminalNode implements Node {
private String label;
}
我现在有一个List<Node>
,我想弄平。在这里,展平意味着我要用其子级递归替换内部节点,直到所有内部节点都被终端替换为止。
我想出了这个功能:
private static List<Node> flatten(final List<Node> nodes) {
return nodes
.stream()
.map(node -> {
if (node instanceof InternalNode) {
return flatten(((InternalNode) node).getNodes());
}
return Collections.singletonList(node);
})
.flatMap(List::stream)
.collect(Collectors.toList());
}
这似乎可以做到。但是,我想知道是否有更好的实现方案。似乎很奇怪,我首先必须通过TerminalNode
将List<TerminalNode>
包装到单例列表(类型为Collections.singletonList(node)
)中,然后再通过以下方式将那个单例列表再次转换回该节点flatMap(List::stream)
。
是否有一种方法可以避免终端节点出现无用的Collections.singletonList(node)
后跟flatMap(List::stream)
的情况?
答案 0 :(得分:8)
您可以直接使用flatMap:
private static Stream<TerminalNode> flatten(final List<Node> nodes) {
return nodes
.stream()
.flatMap(node -> {
if (node instanceof InternalNode) {
return flatten(((InternalNode) node).getNodes());
}
return Stream.of((TerminalNode) node);
});
}
如果要使用列表,则只需收集该方法调用的结果即可。