使用 Stream.ofNullable 处理可空列表是不好的做法吗

Is it bad practise to use Stream.ofNullable to process a nullable List

这篇 using optionals correctly is not optional 文章中的第 12 项指出

Sometimes, we tend to "over-use" things. Meaning that we have a thing, like Optional, and we see a use case for it everywhere. In the case of Optional, a common scenario involves chaining its methods for the single purpose of getting a value. Avoid this practice and rely on simple and straightforward code.

Stream.ofNullable也是这样吗?我应该避免这种情况吗:

Stream.ofNullable(getHandlers(...))
   .flatMap(Collections::stream)
   .forEach(handler -> handler.handle(event));

赞成这个?

List<Handler> handlers = getHandlers(...) 

if (handlers == null) {
    return; // do nothing
}

handlers.forEach(handler -> handler.handle(event));

我认为"rely on simple and straightforward code"的建议在任何地方都是很好的建议,不限于OptionalStream.ofNullable

关于题中的具体选择:我觉得很难说一个客观上比另一个更简单直接。 Stream.ofNullable 更简洁,但需要你知道它的作用;显式 if 检查更冗长,但如果您不熟悉 Streams 可能更容易理解。

当一个 API 引入新方法时,可以说它在某种意义上是 "harder",因为不熟悉 API 方法的人会觉得它更难阅读,因为他们不知道该方法的作用。当然,人们可以反驳他们应该知道它,或者应该期望遇到他们不知道的事情。

所以,我基本上是说您应该使用 you/readers 您的代码中感觉最舒服的那个。


但是,我认为这里不好的做法是 getHandlers(...) 首先返回 null。 Effective Java 中有一项(第 3 版中的第 54 项,第 2 版中的第 43 项)关于始终返回空列表而不是 null。

这条建议在这里非常有效,因为您处理空列表的方式与处理空列表的方式相同。

这样做可以让你写:

List<Handler> handlers = getHandlers(...);
handlers.stream().forEach(...);

这是客观上更简单的代码。

我认为使用它会更好:

for (Handler h : getHandlers(...)) {
  // ...
}

因为您可以更灵活地在循环内执行更多操作(例如中断),而无需使用流(/类似流的方法)。