web-dev-qa-db-ja.com

作成Java 8 ArrayNodeからのストリーム

com.fasterxml.jackson.databind.node.ArrayNodeからストリームを作成することは可能ですか?
私は試した:

ArrayNode files = (ArrayNode) json.get("files");
Stream<JsonNode> stream = Stream.of(files);

しかし、実際には1つの要素のストリーム、つまり初期ArrayNodeオブジェクトを提供します。
正しい結果はStream<JsonNode>になるはずですが、達成できますか?

19
icl7126

ArrayNodeIterableを実装します。 Iterableには spliterator() メソッドがあります。 スプリッターから順次ストリームを作成 を使用して

StreamSupport.stream(spliterator, false)
21
JB Nizet

ArrayNode クラスはランダムアクセスを提供します。size()と要素をインデックスで取得できます(get(index)を使用)。これは、良いストリームを作成するために必要なすべてです。

_Stream<JsonNode> nodes = IntStream.range(0, files.size()).mapToObj(files::get);
_

このソリューションは、他の回答者が提案するように、デフォルトのスプリッターを使用するよりも優れていることに注意してください。並列処理を気にしない場合でも、toArray()などの一部の操作は、事前にサイズを知っていると適切なサイズの配列を割り当てるのに役立つため、より効果的に機能します。

13
Tagir Valeev

ArrayNode#elementsは、(StreamSupportを利用して)ストリームを作成するために使用できる要素のIteratorを返します。 StreamSupportにはSpliteratorが必要です。IteratorからSpliteratorを作成するには、Splitatoratorsクラスを使用できます。

  ArrayNode files = (ArrayNode) json.get("files");
  Stream<JsonNode>  elementStream = StreamSupport.stream(Spliterators
                  .spliteratorUnknownSize(files.elements(),
                        Spliterator.ORDERED),false);

cyclops-streams には StreamUtils クラスがあり、これを少しすっきりさせる静的メソッドがあります(私は作成者です)。

 ArrayNode files = (ArrayNode) json.get("files");
 Stream<JsonNode>  elementStream = StreamUtils.stream(files.elements());

ArrayNodeがStreamUtilsで反復可能であるという@JB Nizetの回答を考慮すると、ArrayNodeに渡して直接Streamを取得できます。

Stream<JsonNode>  elementStream = StreamUtils.stream((ArrayNode) json.get("files"));
5
John McClean