JB Nizet的答案是可以的,但它只用于副作用,而不是映射操作,这有点奇怪。当您只对某些事情的副作用感兴趣时,可以使用一种方法,例如抛出一个异常:。map
peek
List<Parent> filtered = list.stream()
.peek(Objects::requireNonNull)
.filter(predicate)
.collect(Collectors.toList());
如果你想要自己的例外,只需在那里放一个lambda:
List<Parent> filtered = list.stream()
.peek(p -> { if (p == null) throw new MyException(); })
.filter(predicate)
.collect(Collectors.toList());
已检查的异常
如果选中了异常,您可以事先检查 null,如果您不介意遍历列表两次。这在您的情况下可能是最好的,但可能并不总是可能的。
if (list.contains(null)) throw new MyCheckedException();
您还可以在流管道中抛出一个未选中的异常,捕获它,然后抛出选中的异常:
try {
...
.peek(p -> { if (p == null) throw new MyException(); })
...
} catch (MyException exc) {
throw new MyCheckedException();
}
偷偷摸摸的投掷
或者你可以走优雅但有争议的道路,使用偷偷摸摸的投掷方法。
但要小心!此技术绕过了已检查的异常系统,您应该知道自己在做什么。请务必声明周围的方法抛出 !如果您不这样做,编译器不会警告您,并且如果选中的异常出现在预期的位置,则可能会导致奇怪的错误。MyCheckedException
@SuppressWarnings("unchecked")
public <T extends Throwable> void throwSneakily(Throwable t) throws T {
throw (T) t;
}
public void m() throws MyCheckedException {
List<Parent> filtered = list.stream()
.peek(p -> { if (p == null) throwSneakily(new MyCheckedException()); })
.filter(predicate)
.collect(Collectors.toList());
}