(各要素の)JavaストリームAPIで開い近いリソースへの正しい方法はありますか?

user3913960:

リソースとより密接なリソースを使用してなど、いくつかのマップ()、フィルタ()、PEEK()を行い、使用ストリームAPIよりも、コレクション内の各要素のためのリソースを開くための正しい方法はありますか?

私はこのような何かを持っています:

List<String> names =  getAllNames();
names.stream().map(n -> getElementFromName(n))
              .filter(e -> e.someCondition())
              .peek(e -> e.doSomething())
              .filter(e -> e.otherCondition())
              .peek(e -> e.doSomethingElse())
              .filter(e -> e.lastCondition())
              .forEach(e -> e.doTheLastThing());

これは私がgetElementFromName方法でリソース(例えば、DB接続)を開くてる除き、罰金を動作するはずです。それから私はsomeConditionまたはdoSomethingのような他のインスタンスメソッドでそのリソースに働いています。そして、私はそれを正しくクローズするか見当がつかない。

私は、ストリームにのみ、中間操作を使用していることを、知っています。すべてのメソッドは、forEachの操作で評価され、反復は一度だけ行われるため、パフォーマンスがOKであることをどの手段。

しかし、私はgetElementFromName方法の各要素のために開かれたリソースをクローズする方法を見つけ出すことはできません。

私はgetElementFromNameによって作成されたすべての要素のリストを保存し、後でリソースを閉じることができます。しかし、私はちょうど、スペースを無駄に生きているすべてのリソースを維持するだろう。また、要素のリストを介して第2の反復が存在することになります。これは、この場合の好ましいストリームAPIを避けることができます。だから、近い何とかオートへの道私は要素を使用して行われていたリソースはありますか?

また、私は、それが簡単にforeachのloppを使用して行うことができます知っている、私はそれは、ストリームAPIを使用して行うことができるかどうかだけ興味がありました。

ホルガー:

あなたは使用することができflatMap、そのために:

.flatMap(n -> {
    YourResource r = getElementFromName(n);
    return Stream.of(r).onClose(r::close);
})

これは、返された要素によってカプセル化されたリソースを持っていることを前提とclose()方法を。そうでない場合、コードが複雑になりますが、絵は明らかです。だけではなく単一のオブジェクトを返すので、あなたは、その単一要素ストリーム戻っているonCloseアクション必要なクリーンアップを行います。それはチェック例外を投げることができる場合、あなたはまた、好ましくは、チェックされない例外で例外をラップし、そのためのハンドラを追加する必要があります。

これがために作られた保証に依存していますflatMap

各マップされたストリームは、closedその内容が、この流れの中に置かれた後。

しかし、一般的に、このコード、特に乱用PEEKは、高度に疑わしいです。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=180537&siteId=1