我很好奇,想知道为什么Java的可选没有提供peek
类似的方法Stream
的一个。
该peek
方法的Javadoc所述的Stream
界面态:
- @apiNote这种方法主要存在于支持调试,您希望看到的元素,因为他们流过一定点在管道
这几乎正好说明我的使用情况:
@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<User>
(见CrudRepository#findById))
但它不会编译,因为没有peek
对方法Optional
。
所以没有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;
};
}
}
并与使用它map
的方法:
return repository.findById(id)
.map(OptionalUtils.peek(u -> logger.debug("Found user = {} with id = {}", u, id)))
.orElseThrow(() -> new UserNotFoundException("id = " + id));
但我认为这是一个黑客,而不是清洁的使用Optional
。
由于Java 9可以转换Optional
到Stream
,但流没有orElseThrow
方法(显然它不应该)。
此外,也可以用做同样的ifPresent
,但它返回void
。(对我来说似乎ifPresent
不应该返回比其他任何东西void
)
我是不是滥用Optional
?
是不存在的peek
方法故意的吗?(但与此同时Vavr的Option
确实提供了peek
方法。)
或者,它只是认为不值得吗?
嗯,只有设计者可以回答你的“精确”的细节,为什么有人支持选配没有偷看方法。
所以,现在,你坚持使用isPresent()
它实际上在我看来,似乎只是罚款:
if (userOptional.isPresent())
logger.debug("Found user = {} with id = {}", userOptional.get(), id);
或者,如果你想它作为管道的一部分,你可以考虑链接页面上的参考答案。
顺便说一句,鉴于新的stream
方法JDK9的你可以这样做:
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))
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句