Создание потока Java 8 из ArrayNode

можно ли создать поток от com.fasterxml.jackson.databind.node.ArrayNode?
Я попробовал:

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

но он фактически даст поток одного элемента, начального объекта ArrayNode.
Правильный результат должен быть Stream<JsonNode>, Я могу этого добиться?

3 ответов


ArrayNode осуществляет Iterable. Интерфейс Iterable имеет spliterator() метод. Ты можешь!--7-->создайте последовательный поток из Spliterator используя

StreamSupport.stream(spliterator, false)

An ArrayNode класс обеспечивает случайный доступ: вы можете получить size() и элемент по индексу (используя get(index)). Это все, что вам нужно, чтобы создать хороший поток:

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

обратите внимание, что это решение лучше, чем использование сплитератора по умолчанию (как предложено другими ответчиками), поскольку он может хорошо разбиваться и правильно сообщает размер. Даже если вы не заботитесь о параллельной обработке, некоторые операции, такие как toArray() будет работать более эффективно, как знать размер заранее помогите выделить массив нужного размера.


ArrayNode#elements возвращает итератор над его элементами, которые вы можете использовать для создания потока (используя StreamSupport). StreamSupport требует Spliterator и для создания Spliterator из итератора можно использовать класс Spliterators.

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

Циклоп-потоки есть StreamUtils класс имеет статический метод, который делает это немного чище (я автор).

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

принимая во внимание ответ @ JB Nizet, что ArrayNode является итерацией с StreamUtils, которые вы можете передать в ArrayNode и получить поток обратно напрямую.

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