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