从ArrayNode创建Java 8流

icl*_*126 17 jackson java-8 fasterxml java-stream

是否可以从中创建流com.fasterxml.jackson.databind.node.ArrayNode
我试过了:

ArrayNode files = (ArrayNode) json.get("files");
Stream<JsonNode> stream = Stream.of(files);
Run Code Online (Sandbox Code Playgroud)

但它实际上会给出一个元素的流,即初始的ArrayNode对象.
应该是正确的结果Stream<JsonNode>,我可以实现吗?

JB *_*zet 24

ArrayNode实施Iterable.Iterable有一个spliterator()方法.您可以使用Spliterator创建顺序流

StreamSupport.stream(spliterator, false)
Run Code Online (Sandbox Code Playgroud)

  • 因为 Stream.of() 需要一个数组作为参数,而 ArrayNode 不是一个数组。 (2认同)

Tag*_*eev 14

ArrayNode类提供随机存取:你可以size()通过索引的元素(使用get(index)).这就是创建良好流所需的全部内容:

Stream<JsonNode> nodes = IntStream.range(0, files.size()).mapToObj(files::get);
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方案优于使用默认spliterator(由其他回答者建议),因为它可以很好地拆分并正确报告大小.即使您不关心并行处理,一些操作toArray()也会更有效,因为事先知道大小将有助于分配适当大小的数组.


Joh*_*ean 5

ArrayNode#elements在其元素上返回一个Iterator,您可以使用它来创建Stream(通过利用StreamSupport)。StreamSupport需要使用分隔器,并且可以使用Spliterators类从迭代器创建分隔器。

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

cyclops -streams具有StreamUtils 类,具有一个静态方法,该方法使它更简洁(我是作者)。

 ArrayNode files = (ArrayNode) json.get("files");
 Stream<JsonNode>  elementStream = StreamUtils.stream(files.elements());
Run Code Online (Sandbox Code Playgroud)

考虑到@JB Nizet的回答,即ArrayNode是StreamUtils的可迭代对象,您可以传入ArrayNode并直接将Stream返回。

Stream<JsonNode>  elementStream = StreamUtils.stream((ArrayNode) json.get("files"));
Run Code Online (Sandbox Code Playgroud)