2015-09-20 21 views
8

Czy można utworzyć strumień z com.fasterxml.jackson.databind.node.ArrayNode?
Próbowałem:Utwórz strumień Java 8 z ArrayNode

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

Ale to faktycznie dają strumień z jednego elementu, początkowej przedmiotu ArrayNode.
Prawidłowy wynik powinien być Stream<JsonNode>, czy mogę to osiągnąć?

+1

Czy cała tablica zostanie załadowana do pamięci? Uważam, że odpowiedź brzmi "tak". Więc jaki jest sens posiadania strumienia? –

+0

@AndreyKarayvansky nie chodzi o wydajność, ale o możliwość korzystania z metod 'Java 8 Stream API' do przetwarzania kolekcji' ArrayNode' w "funkcjonalny sposób" (używając takich metod jak 'map',' filter', 'collect' ...) . – icl7126

Odpowiedz

4

ArrayNode # elementy zwraca iterator na to elementy można używać, aby stworzyć strumień (wykorzystując StreamSupport). StreamSupport wymaga Spliteratora, a do stworzenia Spliteratora z Iteratora możesz użyć klasy Spliterators.

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

cyclops-streams ma klasę StreamUtils ma statyczną metodę, która sprawia, że ​​ten nieco czystsze (jestem autorem).

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

Uwzględniając @JB odpowiedź Nizet że ArrayNode jest iterable z StreamUtils można przekazać w ArrayNode i dostać z powrotem bezpośrednio Stream.

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

ArrayNode klasa zapewnia swobodny dostęp: można dostać size() oraz element o indeksie (używając get(index)). To wszystko, czego potrzebujesz, aby stworzyć dobrą strumieniowe:

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

Zauważ, że to rozwiązanie jest lepsze niż przy użyciu domyślnego spliterator (sugerowane przez innych Główni odpowiadający), gdyż może to dobrze podzielone i informuje o wielkości odpowiednio. Nawet jeśli nie dbasz o przetwarzanie równoległe, niektóre operacje, takie jak toArray(), będą działać efektywniej, ponieważ znajomość rozmiaru z góry pomoże przydzielić tablicę o odpowiednim rozmiarze.

+0

Zgadzam się ze wszystkim, co powiedziałeś i jest to na wiele sposobów lepsze rozwiązanie. Ale spodziewałbym się zobaczyć takie rozwiązanie bezpośrednio w klasie 'ArrayNode' lub w jakiejś metodzie' Utils'. Strumienie powinny sprawić, że kod będzie łatwiejszy do odczytania i zrozumienia. Wykorzystanie tego rozwiązania do prostej operacji filtrowania mapy-mapy nieznacznie zwiększyłoby złożoność kodu. W każdym razie bardzo ładne myślenie, masz moje +1. – icl7126

+0

@klerik, To nie jest takie proste, aby zapewnić metody strumieniowego API przy jednoczesnym zachowaniu zgodności z wersją wcześniejszą niż Java 8. –

Powiązane problemy