提取结果集时是否应该使用新的流 lambda?

Should the new stream lambdas be used when extracting result sets?

从现有列表中提取结果集的通用代码如下:

List<Node> results;
for (Node node : rsp.getNodes()) {
    if (node.isValid() && node.getType == NodeType.TEST &&...) {
        if (results == null) {
            results = new ArrayList<>();
        }
        results.add(node);
    }
}

现在使用 java 8 和 lambda,因为建议始终使用流来支持吗?

rsp.getNodes().stream.filter(node -> {
    return node.isValid() && node.getType == NodeType.TEST &&...;
}).forEach(node -> results.add(node));

对我来说,最近从 java8 开始,这看起来并不比现在的 java7 代码干净多少。不管怎样,你有更多的经验,可以肯定地推荐我使用这些类型的 "shortcuts" 和 lambdas,而不是旧的 foreach 风格?

我知道最后这可能是一个品味问题。如果是这样,您会认为我的示例是一个完全可行的案例吗?它 可以 始终替换为流和 lambda 作为一种好的做法(我有意识地没有使用术语 "best practice") ?

您给定的案例当然可以转换为 lambda(这没有错)。事实上,您不需要预先创建列表,而是使用 Collectors 那里:

List<Node> results = rsp.getNodes().stream().filter(node -> {
              return node.isValid() && node.getType == NodeType.TEST &&...;
         }).collect(Collectors.toList());

但是,随着您的过滤器逻辑开始增长,或者您开始​​在循环或您的条件中添加更多逻辑,lambda 可能开始变得难看。遵循旧式 for 循环可能更具可读性,但这完全取决于场景。您不能一概而论在哪里使用 lambda 以及在哪里使用循环。

顺便说一句,可以通过避免显式 return:

来进一步修改 lambda
List<Node> results = rsp.getNodes().stream()
              .filter(node -> node.isValid() && node.getType == NodeType.TEST && ...)
              .collect(Collectors.toList());

也许把过滤条件分开,然后你也可以使用方法引用:

List<Node> results = rsp.getNodes().stream()
    .filter(Node::isValid)                      // Method reference
    .filter(n -> n.getType == NodeType.TEST)    // Lambda
    .filter(...)
    .collect(Collectors.toList());              // Produces List from Stream