我有一些字符串:
Stream<String> stream = ...;
Run Code Online (Sandbox Code Playgroud)
我想构造一个字符串,将这些项目与,分隔符连接起来。我这样做如下:
stream.collect(Collectors.joining(","));
Run Code Online (Sandbox Code Playgroud)
现在,仅在有多个项目的情况下,才想在此输出中添加前缀[和后缀]。例如:
a[a,b][a,b,c]可以在不首先实现Stream<String>到a List<String>然后进行检查的情况下完成此操作List.size() == 1吗?在代码中:
public String format(Stream<String> stream) {
List<String> list = stream.collect(Collectors.toList());
if (list.size() == 1) {
return list.get(0);
}
return "[" + list.stream().collect(Collectors.joining(",")) + "]";
}
Run Code Online (Sandbox Code Playgroud)
首先将流转换为列表,然后再次将其转换为流以能够应用,这感觉很奇怪Collectors.joining(",")。我认为遍历整个流(在期间完成Collectors.toList())只是发现是否存在一项或多项是次优的。
我可以实现自己的方法Collector<String, String>,对给定项目的数量进行计数,然后再使用该计数。但是我想知道是否有更直接的方法。
当流为空时,此问题有意忽略了这种情况。
我有内部节点和终端节点的树状结构:
public interface Node
{
}
public class InternalNode implements Node {
private List<Node> nodes;
}
public class TerminalNode implements Node {
private String label;
}
Run Code Online (Sandbox Code Playgroud)
我现在有一个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());
}
Run Code Online (Sandbox Code Playgroud)
这似乎做了它的工作.但是,我想知道是否有更好的实施可能.看起来奇怪的是我首先必须将TerminalNode一个单独的列表(类型List<TerminalNode>)包装到一个单独的列表中Collections.singletonList(node),然后我必须通过再次将该单个列表转换回节点flatMap(List::stream).
有没有办法避免这种无用的Collections.singletonList(node)后续flatMap(List::stream)终端节点?