Java 流 .orElseThrow

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34349261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:33:43  来源:igfitidea点击:

Java streams .orElseThrow

javajava-streamoptional

提问by spakai

I want convert a piece of code from a Connection Pool project i have been working on to use streams

我想从我一直致力于使用流的连接池项目中转换一段代码

the original code is

原始代码是

for (Map.Entry<JdbConnection,Instant> entry : borrowed.entrySet()) {
  Instant leaseTime = entry.getValue();
  JdbConnection jdbConnection = entry.getKey();
  Duration timeElapsed = Duration.between(leaseTime, Instant.now());
  if (timeElapsed.toMillis() > leaseTimeInMillis) {
    //expired, let's close it and remove it from the map
    jdbConnection.close();
    borrowed.remove(jdbConnection);

    //create a new one, mark it as borrowed and give it to the client
    JdbConnection newJdbConnection = factory.create();
    borrowed.put(newJdbConnection,Instant.now());
    return newJdbConnection;
  }
}

throw new ConnectionPoolException("No connections available");

I have got to the point of this

我已经到了这个地步

borrowed.entrySet().stream()
                   .filter(entry -> Duration.between(entry.getValue(), Instant.now()).toMillis() > leaseTimeInMillis)
                   .findFirst()
                   .ifPresent(entry -> {
                     entry.getKey().close();
                     borrowed.remove(entry.getKey());
                   });


JdbConnection newJdbConnection = factory.create();
borrowed.put(newJdbConnection,Instant.now());
return newJdbConnection;

The above can compile but the moment i add orElseThrowafter IfPresenti am getting the following

以上可以编译,但orElseThrowIfPresent我得到以下内容后添加的那一刻

/home/prakashs/connection_pool/src/main/java/com/spakai/ConnectionPool.java:83: error: void cannot be dereferenced
                       .orElseThrow(ConnectionPoolException::new);

采纳答案by David Conrad

That's because ifPresentreturns void. It can't be chained. You could do something like:

那是因为ifPresent返回无效。不能上链。你可以这样做:

Entry<JdbConnection, Instant> entry =
    borrowed.entrySet().stream()
        .filter(entry -> Duration.between(entry.getValue(), Instant.now())
                            .toMillis() > leaseTimeInMillis)
        .findFirst()
        .orElseThrow(ConnectionPoolException::new));
entry.getKey().close();
borrowed.remove(entry.getKey());

What you were looking for would read well:

您正在寻找的内容会很好读:

.findFirst().ifPresent(value -> use(value)).orElseThrow(Exception::new);

But for it to work, ifPresentwould have to return the Optional, which would be a little odd. It would mean you could chain one ifPresentafter another, doing multiple operations on the value. That might have been a good design, but it isn't the one the creators of Optionalwent with.

但是要让它工作,ifPresent就必须返回Optional,这有点奇怪。这意味着你可以一个ifPresent接一个地链接起来,对值进行多次操作。这可能是一个很好的设计,但它不是创造者所Optional采用的设计。

回答by ZoltanTheHun

Use map instead of isPresent, and return with an Optional instead of an exception.

使用 map 而不是 isPresent,并返回一个 Optional 而不是异常。

borrowed.entrySet().stream()
               .filter(entry -> Duration.between(entry.getValue(), Instant.now()).toMillis() > leaseTimeInMillis)
               .findFirst()
               .map(entry -> {
                 entry.getKey().close();
                 borrowed.remove(entry.getKey());
                 JdbConnection newJdbConnection = factory.create();
                 borrowed.put(newJdbConnection,Instant.now());
                 return newJdbConnection;
               })