Java streams.orelsetrow

Java streams.orelsetrow,java,java-stream,optional,Java,Java Stream,Optional,我想将我一直在处理的连接池项目中的一段代码转换为使用流 原始代码是 for (Map.Entry<JdbConnection,Instant> entry : borrowed.entrySet()) { Instant leaseTime = entry.getValue(); JdbConnection jdbConnection = entry.getKey(); Duration timeElapsed = Duration.between(leaseTime,

我想将我一直在处理的连接池项目中的一段代码转换为使用流

原始代码是

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");
上面的代码可以编译,但当我在
IfPresent
之后添加
orelsetrow
时,我得到了以下内容

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

这是因为
ifPresent
返回void。它不能用链子拴住。你可以这样做:

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());

但要让它工作,
ifPresent
必须返回
可选的
,这有点奇怪。这意味着您可以将一个
ifPresent
链接到另一个,对该值执行多个操作。这可能是一个很好的设计,但它不是
Optional
的创建者所采用的设计。

使用map而不是isPresent,并返回可选而不是异常

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;
               })

对于那些想知道@JeanValjean建议的人,我推荐
findFirst
,而不是
findFirst
。@Dinei FWIW,我坚持
findFirst
的原因是OP在问题中使用了
findFirst
。我不知道OP这样做是否有任何特殊原因,但我不想随意将其更改为
findAny
。当然,
findAny
是并行流上的一个性能胜利,当你真的可以接受任何匹配时,而不仅仅是第一个。非常公平@DavidConrad,我只是想补充我必须挖掘的更多信息。
.findFirst().ifPresent(value -> use(value)).orElseThrow(Exception::new);
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;
               })