使用使用者避免Java8中的forEach尝试捕获时forEach中的错误

时间:2019-07-19 15:46:22

标签: java-8

我有一个log()方法来避免下面的forEach()中的try catch语句在其他代码中起作用。

public <T> Consumer<T> log(LogConsumer<T, Throwable> logConsumer)
{
    return i -> {
        try
        {
            logConsumer.accept(i);
        }
        catch (Throwable e)
        {
            log("e = " + e);
        }
    };
}

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

现在我只想在下面的forEach中使用登录,但是我在LINE中有红色的波纹线,这样

new Task.runJob(job, type))

  

我的工作下有红色波纹线,请输入       “无法将Task中的runJob(Job,JobType)应用于(java.lang.Object,)”

     

现在请确保如何解决此问题以使用forEach登录只是为了避免   尝试在其中捕获。

execute() {
    Map<Job, JobType> map = getJobMap();

    map.forEach( log((job, type)-> new Taks().runJob(job,type)) );    // LINE: error here 
}

class Task {
    public String runJob(Job job, JobType type) throws Exception
    {
        ...
        return result;
    }
}

1 个答案:

答案 0 :(得分:0)

发生这种情况是因为您无法执行使用Lambda表达式引发异常的函数。您必须使用try-catch块来处理异常。但是,为了使您的代码更具可读性,请创建一个函数,该函数将处理异常并返回所需的结果。

class Task {
    public String runJob(Job job, JobType type)
    {
        try {
            ...
            return result;
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }
}

如果您关心结果是什么,则将其映射并过滤函数的结果不为null,否则,将其忽略,但请注意日志中是否有任何错误。

然后按如下所示进行调用。 注意:两种方法都可以使用,但是第二种方法更可靠,因为您可以处理并非所有作业都无一例外地执行的情况。

execute() {
    Map<Job, JobType> map = getJobMap();

    // First way
    map.forEach( log((job, type) -> new Taks().runJob(job,type)) );

    // Another way
    List<Object> batchResult = map.entrySet().stream()
            .map((job, type) -> new Task().runJob(jon, type))
            .filter(Objects::nonNull)
            .collect(Collectors.toList());

    if (batchResult.size() == map.size()) {
        // everythings is ok (all operations resulted in non-null result
    } else {
        // Have to study logs and figure out what went wrong
    }

}