使用 Stream 避免 NoSuchElementException

Avoid NoSuchElementException with Stream

我有以下 Stream:

Stream<T> stream = stream();

T result = stream.filter(t -> {
    double x = getX(t);
    double y = getY(t);
    return (x == tx && y == ty);
}).findFirst().get();

return result;

但是,并不总是出现以下错误的结果:

NoSuchElementException: No value present

如果没有值,我怎么能 return 一个 null

Stream#findFirst() returns an Optional 专门存在,因此您无需对 null 值进行操作。

A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

否则,Optional#get() 抛出 NoSuchElementException

If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException.

如果 Optionalnull,则它永远不会暴露其值。

如果您确实需要,请自行检查isPresent()和return null

Stream<T> stream = stream();

Optional<T> result = stream.filter(t -> {
    double x = getX(t);
    double y = getY(t);
    return (x == tx && y == ty);
}).findFirst();

if (result.isPresent()) 
    return result.get();
return null;

可以用Optional.orElse,比查isPresent简单多了:

T result = stream.filter(t -> {
    double x = getX(t);
    double y = getY(t);
    return (x == tx && y == ty);
}).findFirst().orElse(null);

return result;

替换 Optional.get (which more likely than not fails the user's intentions with a NoSuchElementException) is with a more verbose API introduced in JDK10 termed as Optional.orElseThrow(). In author's words -

的替代方法

Optional.get() is an "attractive nuisance" and is too tempting for programmers, leading to frequent errors. People don't expect a getter to throw an exception. A replacement API for Optional.get() with equivalent semantics should be added.

注意 :- 这两个 API 的底层实现是相同的,但后者更清楚地表明 NoSuchElementException 是如果值不存在则默认抛出,该值内联到消费者用作显式替代的现有 Optional.orElseThrow​(Supplier<? extends X> exceptionSupplier) 实现。

如果您希望继续使用该对象而不抛出任何异常,那么

Optional.isPresent(object) 是要走的路