使用lambda过滤流并抛出异常

时间:2016-08-28 08:05:18

标签: java exception lambda java-stream

目前,我们使用Set<String> clients实现基本方法如下 -

if (clients.isEmpty()) {
    throw new InvalidClientException();
}

for (String client : clients) {
    if (!myMay.containsKey(client)) {
        throw new InvalidClientException(client);
    }
}

我尝试使用lambda表达式转换它,如下所示 -

clients.stream().filter(client -> !myMay.containsKey(client) || clients.isEmpty())
            .forEach(InvalidClientException::new);

但是这似乎没有同样的工作方式,参数化构造函数在这里调用了吗?

1 个答案:

答案 0 :(得分:5)

首先,如果set为空,则传递给forEach的lambda将不会被执行:空流为空,过滤它不会添加任何元素。只能删除一些。

其次,lambda创建了一个例外。但它并没有扔掉它。

您可以使用

if (clients.isEmpty() || clients.stream().anyMatch(client -> !myMay.containsKey(client))) {
    throw new InvalidClientException();
}

编辑:我错过了你想要将不在集合中的(第一个?)客户端传递给异常的事实。要做到这一点,你可以做到

if (clients.isEmpty()) {
    throw new InvalidClientException();
}

clients.stream()
       .filter(client -> !myMay.containsKey(client))
       .findAny() // or .findFirst()
       .ifPresent(client -> {
           throw new InvalidClientException(client);
       });

但是,只有在异常是运行时异常时才会起作用,因为您不能从Consumer中抛出已检查的异常。如果它是已检查的异常并且您确实希望将其保留为已检查的异常,则可以使用

if (clients.isEmpty()) {
    throw new InvalidClientException();
}

Optional<String> wrongClient = 
    clients.stream()
           .filter(client -> !myMay.containsKey(client))
           .findAny();
if (wrongClient.isPresent()) {
    throw new InvalidClientException(wrongClient.get());
}