如何干净地处理java 8流"findFirst()"结果,即使是空的

Dav*_*arr 7 java optional java-8 java-stream

我经常发现java 8流混淆的一个方面是当中间结果为空时,如果它是空的或不为空,则需要采用备用路径.

例如,如果我有这样的代码:

String pymtRef = defaultValue;
Optional<PaymentTender> paymentTender = paymentTenders.stream()
        .filter(pt -> (pt.getFlag() == Flag.N || pt.getFlag() == null)).findFirst();
if (paymentTender.isPresent()) {
    pymtRef = paymentTender.get().getId();
}
return pymtRef;
Run Code Online (Sandbox Code Playgroud)

我想弄清楚如何删除条件块并在单个流中执行此操作.

如果我只是在过滤结果上调用".map",那么如果它找到匹配的条目就可以工作.如果没有,我得到一个NoSuchElementException.

我可能会使用"ifPresent()",但返回类型为"void".

有没有办法让这个更干净?

更新:

使用"orElse()"的解决方案工作正常.

整个方法现在看起来像这样:

public String getPaymentReference(OrderContext orderContext) {
    List<PaymentTender> paymentTenders = getPaymentTenders(orderContext);
    if (paymentTenders.size() == 1) {
        return paymentTenders.get(0).getId();
    }
    return paymentTenders.stream()
            .filter(pt -> (pt.getAutoBill() == AutoBill.N || pt.getAutoBill() == null))
            .findFirst().map(pt -> pt.getId()).orElse(DEFAULT_VALUE);
}
Run Code Online (Sandbox Code Playgroud)

你能想到一种方法来在流中包含第一个条件而不会使它更复杂吗?

Ous*_* D. 5

调用get()后直接map将产生一个异常,如果有可选的空白状态,而是调用orElsemap,并提供一个默认值:

paymentTenders.stream()
            .filter(pt -> (pt.getFlag() == Flag.N || pt.getFlag() == null))
            .findFirst()
            .map(PaymentTender::getId)
            .orElse(someDefaultValue);
Run Code Online (Sandbox Code Playgroud)

编辑:

至于:

你能想出一种在流中包含第一个条件而不使其更复杂的方法吗?

不,这比你做的更好。它更具可读性,更易于遵循。

引入任何类型的逻辑以使其成为一个管道(如果可能)只会变得复杂,因此更难以遵循和理解。