我很想知道为什么Java的可选不提供类似于流的方法。
Stream
接口的peek
method javadoc声明:
这几乎完全描述了我的用例:
@Override
@Transactional
public User getUserById(long id) {
return repository.findById(id)
.peek(u -> logger.debug("Found user = {} by id = {}", u, id))
.orElseThrow(() -> new UserNotFoundException("id = " + id));
}
(repository.findById
返回可选
但是它不会编译,因为 Optional 上没有
peek
方法
。
因此,如果没有< code>peek
方法,上述所有内容都会转换为:
@Override
@Transactional
public User getUserById(long id) {
Optional<User> userOptional = repository.findById(id);
if (userOptional.isPresent()) {
logger.debug("Found user = {} with id = {}", userOptional.get(), id);
}
return userOptional.orElseThrow(() -> new UserNotFoundException("id = " + id));
}
也可以这样做(参见此答案):
@NoArgsConstructor(access = PRIVATE)
public abstract class OptionalUtils {
public static <T> UnaryOperator<T> peek(Consumer<T> consumer) {
return t -> {
consumer.accept(t);
return t;
};
}
}
并将其与映射
方法一起使用:
return repository.findById(id)
.map(OptionalUtils.peek(u -> logger.debug("Found user = {} with id = {}", u, id)))
.orElseThrow(() -> new UserNotFoundException("id = " + id));
但我认为这是一个黑客,而不是对可选
的干净用法。
从Java 9开始,可以将< code>Optional转换为< code>Stream,但是该流没有< code > orelsthrow 方法(显然它不应该有)。
也可以使用<code>ifPresent。(对我来说,<code>如果存在</code>不应返回除<code>void</code>以外的任何内容。)
我是否误用了< code>Optional?
缺少peek
方法是故意的吗?(但同时Vavr的Option
确实提供了peek
方法。)
还是只是被认为不值得?
已经有可选::ifPresent
和可选::isPresent
方法来记录结果。但是您可能想要一些符合要求的东西。对此的答案可能是疏忽。
嗯,只有设计师可以回答你“确切”的细节,说明为什么选项没有peek方法。
因此,现在,您只能使用<code>isPresent()
if (userOptional.isPresent())
logger.debug("Found user = {} with id = {}", userOptional.get(), id);
或者,如果您希望将链接页面上的建议答案作为管道的一部分,您也可以考虑。
顺便说一句,考虑到JDK9中新的<code>流
return repository.findById(id) // Optional<User>
.stream() // Stream<User>
.peek(u -> logger.debug("Found user = {} by id = {}", u, id)) // Stream<User>
.findFirst() // Optional<User>
.orElseThrow(() -> new UserNotFoundException("id = " + id))
类似的例子见这个回答。
已经有接受消费者的可选::ifPresent方法。
在Java 8中,唯一的方法是使用< code>Optional::map,将实体映射到自身,并将其用作< code>peek方法:
return repository.findById(id)
.map(u -> {
logger.debug("Found user = {} with id = {}", u, id)
return u;
})
.orElseThrow(() -> new UserNotFoundException("id = " + id));
...这应该简化实现自己的窥视
方法:
<T> UnaryOperator<T> peek(Consumer<T> consumer) {
return t -> {
consumer.accept(t);
return t;
};
}
…并与<code>可选<code>一起舒适使用:
return repository.findById(id)
.map(this.peek(logger.debug("Found user = {} with id = {}", u, id)))
.orElseThrow(() -> new UserNotFoundException("id = " + id));
问题内容: 有人知道为什么JUnit 4提供但不提供方法吗? 它提供了(对应于)和(对应于),因此它们似乎没有包含在内就显得很奇怪。 顺便说一下,我知道JUnit插件提供了我正在寻找的方法。我只是出于好奇而问。 问题答案: 我建议您使用较新的样式断言,该断言可以轻松描述各种否定形式,并在断言失败时自动构建对您的期望和得到的结果的描述: 这三个选项都是等效的,请选择最容易阅读的一个。 要使用方法的简
本质上,它包装了,确保了最大容量,并提供了一些其他有用的特性。更好的方法是直接将其实现为。 现在,为了方便起见,我认为最好实现,这样,如果您想要循环它,就可以使用增强的for-loops。(我的类还提供了方法,因此我认为是合理的。) 接口提供以下功能(省略了javadoc): null
groovy.lang.missingMethodException:方法的无签名:java.util.stream.referencePipeline$head.peek()适用于参数类型:(MolportFileverization$_run_closure1)值:[MolportFileverization$_run_closure1@d62472f]可能的解决方案:peek(java.ut
问题内容: 我想知道为什么接口不提供和方法。考虑以下类别: 它是 一手 牌的一种实现,因为您在玩交易纸牌游戏时可以手拿牌。 本质上,它包装了,可确保最大容量并提供其他一些有用的功能。最好将其直接实现为。 现在,为了方便起见,我认为实现起来会很不错,这样,如果您想对其进行循环,则可以使用增强的for循环。(我的课程也提供了一种方法,因此我认为该方法是合理的。) 该界面提供了以下内容(省略了javad
问题内容: 在Swift中处理可选选项的习惯用法似乎过于冗长,如果您只想在nil为零的情况下提供默认值,则它是: 涉及不必要地复制代码,或 这不需要是常数。 Scala的Option monad(与Swift的Optional基本相同)具有用于此目的的方法: 我想念什么吗?Swift已经有一种紧凑的方式做到这一点吗?否则,是否可以在扩展名中为Optional 定义? 问题答案: 更新资料 苹果现在
问题内容: 查看Guava的ImmutableList(和其他一些类),您会发现很多重载的便捷方法(“按顺序返回包含给定元素的不可变列表”。)这些方法使用不同数量的参数: 一直到这一步: 我的一些同事认为这很愚蠢,想知道为什么不只有一种方法:。他们怀疑这是不正确的性能“优化”,属于“您认为自己比编译器更聪明”之类的东西。 我的直觉是Kevin Bourrillion等。出于真正的原因将这些方法放在