web-dev-qa-db-ja.com

Javaストリーム.orElseThrow

ストリームを使用するために取り組んでいる接続プールプロジェクトのコードを変換したい

元のコードは

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

私はこれのポイントに到達しました

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;

上記はコンパイルできますが、orElseThrowの後にIfPresentを追加すると、次のようになります。

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

これは、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());

あなたが探していたものはよく読むでしょう:

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

しかし、それが機能するためには、ifPresentOptionalを返す必要があり、これは少し奇妙です。つまり、値に対して複数の操作を実行して、ifPresentを次々にチェーンできるということです。それは良いデザインだったかもしれませんが、Optionalの作成者が一緒に行ったものではありません。

15
David Conrad

IsPresentの代わりにmapを使用し、例外の代わりに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;
               })
2
ZoltanTheHun