This tutorial teaches some useful techniques involving streams that let you employ them in a much wider set of uses.
When you work with Java collections, the stream
method of Collection objects helps you easily create a stream based on the contents of the collection. But not all iterable objects have in-built methods to get a stream. For example, I use the Jackson library for JSON quite heavily and often miss being able to process sequences of JSON elements as a stream. But, given an interator to the underlying sequence, it is not that hard to create a stream on it.
import java.util.stream.StreamSupport;
Iterator<ObjectType> iter = container.iterator();
Iterable<ObjectType> iterable = () -> iter; // java.lang.Iterable's only method iterator is assigned the lambda
Boolean parallel = true;
Stream<ObjectType> stream = StreamSupport.stream(iterable.spliterator, !parallel);
You can easily fold this into a generic function:
public static <T, U> Stream<U> getStream(T container, Function<T, Iterator<U>> iterGetter,
Boolean parallel) {
Iterator<U> iter = iterGetter.apply(container);
Iterable<U> iterable = () -> iter;
return StreamSupport.stream(iterable.spliterator(), parallel);
}
If you now want to apply it on say the JsonNode class from Jackson, you could do so easily:
JsonNode node = ...;
if (node.isArray()) {
Stream<JsonNode> stream = getStream(node, JsonNode::elements, false);
} else if (node.isObject()) {
Stream<Map.Entry<String, JsonNode>> stream = getStream(node, JsonNode::fields, false);
}