如何在我想要返回的方法中从lambda返回一个值?

时间:2018-03-26 16:48:35

标签: java lambda return

如何在我想要返回的方法中从lambda返回一个值?

最初,我有这个:

myCollection.forEach(item -> {
  try {
    doSomething(item);
  } catch (Exception e) {
    return "There was a problem doing something: " + e.getMessage();
  }
});

但我的意图是返回包含所有这些代码的方法,而不仅仅返回lambda。所以,我最终不得不这样做:

String error = "";
myCollection.stream().filter(item -> {
  try {
    doSomething(item);
    return true;
  } catch (Exception e) {
    error = "There was a problem doing something: " + e.getMessage();
  }
  return false;
});
if (!error.isEmpty()) {
  return error;
}

但这不是最好的方法。什么是Java 8功能,优雅的方法呢?

4 个答案:

答案 0 :(得分:1)

可以使用流周围的try子句捕获从流内部抛出的任何内容。

try {
    myCollection.forEach(SurroundingClass::doSomething);
} catch (Exception e) {
    return "..."
}

但是,我不建议使用异常作为流量控制的方法。投掷和捕获异常很慢。如果可以,请务必先检查数据是否会产生异常,然后再将其传递给doSomething

如果您正在讨论检查异常,则没有简单的方法来处理它们。如果您想了解一些(相当冗长的)变通方法,请查看此post

答案 1 :(得分:1)

也许是这样的,我还没有测试过。

select respondent_id, max(counter) from (
select respondent_id, day_session, 
 if(daydiff = 1, @counter := @counter + 1, @counter := 0) counter 
 from mydata 
 join (select @counter := 0) d
 order by respondent_id, day_session
) a 
group by respondent_id

答案 2 :(得分:1)

你真的需要在这里使用Lambda吗?最好的Java方法就是在集合中使用1.5 for-each:

var event = new InputEvent('input', {
    bubbles: true,
    cancelable: false,
    data: "a"
}); 

document.getElementById('email').dispatchEvent(event);

请注意,在进入和退出try { for (final E item : myCollection) { doSomething(item) } } catch (final Exception ex) { return "blah"; } 区块时会产生性能损失,因此最好将其置于循环之外。

答案 3 :(得分:0)

可以通过以下方式处理lambda中已检查的异常

    @FunctionalInterface
    public interface ThrowingConsumer<T, E extends Exception> {
        void accept(T t) throws E;
    }

    private static <T> Consumer<T> wrap(ThrowingConsumer<T, Exception> throwingConsumer) {
        return item -> {
            try {
                throwingConsumer.accept(item);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        };
    }

    private String processCollection(List</* whatever type */> myCollection) {
        try {
            myCollection.forEach(wrap(this::doSomething));
        } catch (Exception e) {
            return e.getMessage(); // error
        }
        return null; // no error
    }