从 ArrayNode 创建 Java 8 个流

Create Java 8 Stream from ArrayNode

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

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

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

ArrayNode 实施 Iterable。 Iterable 有一个 spliterator() method. You can create a sequential Stream from a Spliterator 使用

ArrayNode arrayNode = (ArrayNode) json.get("xyz");
StreamSupport.stream(arrayNode.spliterator(), false)

ArrayNode#elements returns 对其元素的迭代器,您可以使用它来创建流(通过利用 StreamSupport)。 StreamSupport 需要一个 Spliterator,要从迭代器创建一个 Spliterator,您可以使用 Spliterators class.

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

cyclops-streams has a StreamUtils class 有一个静态方法使它更清晰(我是作者)。

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

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

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

ArrayNode class 提供随机访问:您可以通过索引获取 size() 和一个元素(使用 get(index))。这就是创建优质流所需的全部内容:

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

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