Interface NodeStream<T extends Node>
-
- Type Parameters:
T
- Type of nodes this stream contains. This parameter is covariant, which means for maximum flexibility, methods taking a node stream argument should declare it with an "extends" wildcard.
- All Superinterfaces:
Iterable<@NonNull T>
- All Known Subinterfaces:
NodeStream.DescendantNodeStream<T>
public interface NodeStream<@NonNull T extends Node> extends Iterable<@NonNull T>
A sequence of AST nodes. Conceptually similar to aStream
, and exposes a specialized API to navigate abstract syntax trees. This API can make it as easy as a XPath expression to navigate the tree.API usage
The
Node
interface exposes methods likeNode.children()
orNode.asStream()
to obtain new NodeStreams. Null-safe construction methods are available here, seeof(Node)
,of(Node[])
,fromIterable(Iterable)
.Most functions have an equivalent in the
Stream
interface and their behaviour is similar. One important departure from theStream
contract is the absence of requirement on the laziness of pipeline operations. More on that in the details section below.Some additional functions are provided to iterate the axes of the tree:
children()
,descendants()
,descendantsOrSelf()
,parents()
,ancestors()
,ancestorsOrSelf()
,precedingSiblings()
,followingSiblings()
. Filtering and mapping nodes by type is possible throughfilterIs(Class)
, and the specializedchildren(Class)
,descendants(Class)
, andancestors(Class)
.Many complex predicates about nodes can be expressed by testing the emptiness of a node stream. E.g. the following tests if the node is a variable declarator id initialized to the value
0
:NodeStream.of(someNode) // the stream here is empty if the node is null .filterIs(ASTVariableId.class) // the stream here is empty if the node was not a variable declarator id .followingSiblings() // the stream here contains only the siblings, not the original node .take(1) // the stream here contains only the first sibling, if it exists .filterIs(ASTNumericLiteral.class) .filter(it -> !it.isFloatingPoint() && it.getValueAsInt() == 0) .nonEmpty(); // If the stream is non empty here, then all the pipeline matched
Many existing operations from the node interface can be written with streams too:
- Traverse the children to find the first instance of type childType:
node.
children(t)
.first()
- Traverse down the tree to find the first descendant instance of type descendantType without crossing find boundaries:
node.
descendants(t)
.first()
- Traverse up the tree to find the first parent instance of type parentType or one of its subclasses:
node.
ancestors(t)
.first()
- Traverse the children to find all the instances of type childType or one of its subclasses:
node.
children(t)
.toList()
- Traverse down the tree to find all the descendant instances of type descendantType without crossing find boundaries:
node.
descendants(t)
.toList()
- Traverse up the tree to find all of the parent instances of type parentType or one of its subclasses, ordering the nodes deepest first:
node.
ancestors(t)
.toList()
- Get the n-th parent or null if there are less than
n
ancestors:node.
ancestors()
.get(n - 1)
- Find if this node contains a descendant of the given type without crossing find boundaries:
node.
descendants(t)
.nonEmpty()
node.getFirstParentOfAnyType(c1, c2) === node.
ancestors()
.firstNonNull
(asInstanceOf(c1, c2)
)node.hasDescendantOfAnyType(c1, c2) === node.
descendants()
.map
(asInstanceOf(c1, c2)
).nonEmpty()
Unlike
Stream
s, NodeStreams can be iterated multiple times. That means, that the operations that are terminal in the Stream interface (i.e. consume the stream) don't consume NodeStreams. Be aware though, that node streams don't cache their results by default, so e.g. callingcount()
followed bytoList()
will execute the whole pipeline twice. The elements of a stream can however be cached at an arbitrary point in the pipeline to evaluate the upstream only once. Some construction methods allow building a node stream from an external data source, e.g.fromIterable
. Depending on how the data source is implemented, the built node streams may be iterable only once.Node streams may contain duplicates, which can be pruned with
distinct()
.Details
NodeStreams are not necessarily implemented with
Stream
, but when a method has an equivalent in theStream
API, their contract is similar. The only difference, is that node streams are not necessarily lazy, ie, a pipeline operation may be evaluated eagerly to improve performance. For this reason, relying on side-effects produced in the middle of the pipeline is a bad idea.Stream
gives the same guideline about statefulness, but not for the same reason. Their justification is parallelism and operation reordering, once the pipeline is fully known.Node streams are meant to be sequential streams, so there is no equivalent to
Stream.findAny()
. The methodfirst()
is an equivalent toStream.findFirst()
. There is however alast()
method, which may be implemented efficiently on some streams (egchildren()
).Node streams are most of the time ordered in document order (w.r.t. the XPath specification), a.k.a. prefix order. Some operations which explicitly manipulate the order of nodes, like
union
orappend
, may not preserve that ordering.map
andflatMap
operations may not preserve the ordering if the stream has more than one element, since the mapping is applied in order to each element of the receiver stream. This extends to methods defined in terms of map or flatMap, e.g.descendants()
orchildren()
.- Author:
- Clément Fournier
- Implementation Note:
- Choosing to wrap a stream instead of extending the interface is to
allow the functions to return NodeStreams, and to avoid the code bloat
induced by delegation.
The default implementation relies on the iterator method. From benchmarking, that appears more efficient than streams.
- Since:
- 7.0.0
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static interface
NodeStream.DescendantNodeStream<T extends Node>
A specialization ofNodeStream
that allows configuring tree traversal behaviour when traversing the descendants of a node.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description boolean
all(Predicate<? super @NonNull T> predicate)
Returns whether all elements of this stream match the provided predicate.default NodeStream<Node>
ancestors()
Returns a node stream containing all the ancestors of the nodes contained in this stream.default <R extends Node>
NodeStream<R>ancestors(Class<? extends R> rClass)
Returns the ancestor stream of each node in this stream, filtered by the given node type.default NodeStream<Node>
ancestorsOrSelf()
Returns a node stream containing the nodes contained in this stream and their ancestors.boolean
any(Predicate<? super @NonNull T> predicate)
Returns whether any elements of this stream match the provided predicate.NodeStream<T>
append(NodeStream<? extends @NonNull T> right)
Returns a new node stream that contains all the elements of this stream, then all the elements of the given stream.static <O> Function<@Nullable Object,@Nullable O>
asInstanceOf(Class<? extends O> c1, Class<? extends O>... rest)
Returns a map function, that checks whether the parameter is an instance of any of the given classes.NodeStream<T>
cached()
Returns a node stream containing all the elements of this node stream, but which will evaluate the upstream pipeline only once.default NodeStream<Node>
children()
Returns a node stream containing all the children of the nodes contained in this stream.default <R extends Node>
NodeStream<R>children(Class<? extends R> rClass)
Returns the children stream of each node in this stream, filtered by the given node type.<R,A>
Rcollect(Collector<? super @NonNull T,A,R> collector)
Collects the elements of this node stream using the specifiedCollector
.int
count()
Returns the number of nodes in this stream.NodeStream.DescendantNodeStream<Node>
descendants()
Returns a node stream containing all the strict descendants of the nodes contained in this stream.<R extends Node>
NodeStream.DescendantNodeStream<R>descendants(Class<? extends R> rClass)
Returns the descendant stream of each node in this stream, filtered by the given node type.NodeStream.DescendantNodeStream<Node>
descendantsOrSelf()
Returns a node stream containing the nodes contained in this stream and their descendants.NodeStream<T>
distinct()
Returns a stream consisting of the distinct elements (w.r.tObject.equals(Object)
) of this stream.NodeStream<T>
drop(int n)
Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.NodeStream<T>
dropLast(int n)
Returns a stream consisting of the elements of this stream except the n tail elements.static <T extends Node>
NodeStream<T>empty()
Returns an empty node stream.NodeStream<T>
filter(Predicate<? super @NonNull T> predicate)
Returns a node stream consisting of the nodes of this stream that match the given predicate.default <R extends Node>
NodeStream<R>filterIs(Class<? extends R> rClass)
Filters the nodes of this stream that are a subtype of the given class.default <U> NodeStream<T>
filterMatching(Function<? super @NonNull T,? extends @Nullable U> extractor, U comparand)
Filters the nodes of this stream by comparing a value extracted from the nodes with the given constant.default NodeStream<T>
filterNot(Predicate<? super @NonNull T> predicate)
Filters the node of this stream using the negation of the given predicate.default <U> NodeStream<T>
filterNotMatching(Function<? super @NonNull T,? extends @Nullable U> extractor, U comparand)
Inverse offilterMatching(Function, Object)
.@Nullable T
first()
Returns the first element of this stream, ornull
if the stream is empty.default <R extends Node>
@Nullable Rfirst(Class<? extends R> rClass)
Returns the first element of this stream of the given type, ornull
if there is none.default @Nullable T
first(Predicate<? super @NonNull T> predicate)
Returns the first element of this stream that matches the given predicate, ornull
if there is none.default <R extends Node>
NodeStream<R>firstChild(Class<? extends R> rClass)
Returns a stream containing the first child of each of the nodes in this stream that has the given type.default <R extends Node>
@Nullable RfirstNonNull(Function<? super @NonNull T,? extends @Nullable R> nullableFun)
Returns the first element of this stream for which the mapping function returns a non-null result.default Optional<T>
firstOpt()
Returns an optional containing the first element of this stream, or an empty optional if the stream is empty.default @NonNull T
firstOrThrow()
Returns the first element of this stream, or throws aNoSuchElementException
if the stream is empty.<R extends Node>
NodeStream<R>flatMap(Function<? super @NonNull T,? extends @Nullable NodeStream<? extends R>> mapper)
Returns a node stream consisting of the results of replacing each node of this stream with the contents of a stream produced by the given mapping function.default NodeStream<Node>
followingSiblings()
Returns a node stream containing all the following siblings of the nodes contained in this stream.void
forEach(Consumer<? super @NonNull T> action)
static <T extends Node,R extends Node>
NodeStream<R>forkJoin(NodeStream<? extends T> upstream, Function<? super @NonNull T,? extends NodeStream<? extends R>> fst, Function<? super @NonNull T,? extends NodeStream<? extends R>> snd, Function<? super @NonNull T,? extends NodeStream<? extends R>>... rest)
Applies the given mapping functions to the given upstream in order and merges the results into a new node stream.static <T extends Node>
NodeStream<T>fromIterable(Iterable<? extends @Nullable T> iterable)
Returns a new node stream that contains the same elements as the given iterable.default @Nullable T
get(int n)
Returns the element at index n in this stream.default boolean
isEmpty()
Returns 'true' if the stream has no elements.@Nullable T
last()
Returns the last element of this stream, ornull
if the stream is empty.default <R extends Node>
@Nullable Rlast(Class<? extends R> rClass)
Returns the last element of this stream of the given type, ornull
if there is none.<R extends Node>
NodeStream<R>map(Function<? super @NonNull T,? extends @Nullable R> mapper)
Returns a node stream consisting of the results of applying the given mapping function to the node of this stream.boolean
none(Predicate<? super @NonNull T> predicate)
Returns whether no elements of this stream match the provided predicate.boolean
nonEmpty()
Returns 'true' if the stream has at least one element.static <T extends Node>
NodeStream<T>of(@Nullable T node)
Returns a node stream containing zero or one node, depending on whether the argument is null or not.static <T extends Node>
NodeStream<T>of(T... nodes)
Returns a node stream whose elements are the given nodes in order.static <T extends Node>
NodeStream<T>ofOptional(Optional<? extends T> optNode)
Returns a node stream containing zero or one node, depending on whether the optional is empty or not.default NodeStream<Node>
parents()
Returns a node stream containing all the (first-degree) parents of the nodes contained in this stream.NodeStream<T>
peek(Consumer<? super @NonNull T> action)
Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.default NodeStream<Node>
precedingSiblings()
Returns a node stream containing all the preceding siblings of the nodes contained in this stream.NodeStream<T>
prepend(NodeStream<? extends @NonNull T> right)
Returns a new node stream that contains all the elements of the given stream, then all the elements of this stream.default <R> R
reduce(R identity, BiFunction<? super R,? super @NonNull T,? extends R> accumulate)
Reduce the elements of this stream sequentially.default int
sumBy(ToIntFunction<? super @NonNull T> toInt)
Sum the elements of this stream by associating them to an integer.default int
sumByInt(ToIntFunction<? super @NonNull T> intMapper)
Returns the sum of the value of the function applied to all elements of this stream.NodeStream<T>
take(int maxSize)
Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.NodeStream<T>
takeWhile(Predicate<? super @NonNull T> predicate)
Returns the longest prefix of elements that satisfy the given predicate.default List<T>
toList()
Collects the elements of this node stream into a list.default <R> List<R>
toList(Function<? super @NonNull T,? extends R> mapper)
Maps the elements of this node stream using the given mapping and collects the results into a list.Stream<@NonNull T>
toStream()
Returns a new stream of Ts having the pipeline of operations defined by this node stream.static <T extends Node>
NodeStream<T>union(Iterable<? extends NodeStream<? extends T>> streams)
Returns a node stream containing all the elements of the given streams, one after the other.static <T extends Node>
NodeStream<T>union(NodeStream<? extends T>... streams)
Returns a node stream containing all the elements of the given streams, one after the other.-
Methods inherited from interface java.lang.Iterable
iterator, spliterator
-
-
-
-
Method Detail
-
flatMap
<R extends Node> NodeStream<R> flatMap(Function<? super @NonNull T,? extends @Nullable NodeStream<? extends R>> mapper)
Returns a node stream consisting of the results of replacing each node of this stream with the contents of a stream produced by the given mapping function. If a mapped stream is null, it is discarded.If you want to flatMap this node stream to a
Stream
with arbitrary elements (ie not nodes), usetoStream()
thenStream.flatMap(Function)
.- Type Parameters:
R
- Type of nodes contained in the returned stream- Parameters:
mapper
- A function mapping the elements of this stream to another stream- Returns:
- A flat mapped stream
- See Also:
Stream.flatMap(Function)
-
map
<R extends Node> NodeStream<R> map(Function<? super @NonNull T,? extends @Nullable R> mapper)
Returns a node stream consisting of the results of applying the given mapping function to the node of this stream. If the mapping function returns null, the elements are not included.If you want to map this node stream to a
Stream
with arbitrary elements (ie not nodes), usetoStream()
thenStream.map(Function)
.- Type Parameters:
R
- The node type of the new stream- Parameters:
mapper
- A function mapping the elements of this stream to another node type- Returns:
- A mapped stream
- See Also:
Stream.map(Function)
-
filter
NodeStream<T> filter(Predicate<? super @NonNull T> predicate)
Returns a node stream consisting of the nodes of this stream that match the given predicate.- Parameters:
predicate
- A predicate to apply to each node to determine if it should be included- Returns:
- A filtered node stream
- See Also:
Stream.filter(Predicate)
,filterNot(Predicate)
,filterIs(Class)
,filterMatching(Function, Object)
-
peek
NodeStream<T> peek(Consumer<? super @NonNull T> action)
Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream. Note that terminal operations such ascount()
don't necessarily execute the action.- Parameters:
action
- an action to perform on the elements as they are consumed from the stream- Returns:
- A new stream
-
append
NodeStream<T> append(NodeStream<? extends @NonNull T> right)
Returns a new node stream that contains all the elements of this stream, then all the elements of the given stream.- Parameters:
right
- Other stream- Returns:
- A concatenated stream
- See Also:
union(NodeStream[])
-
prepend
NodeStream<T> prepend(NodeStream<? extends @NonNull T> right)
Returns a new node stream that contains all the elements of the given stream, then all the elements of this stream.- Parameters:
right
- Other stream- Returns:
- A concatenated stream
- See Also:
union(NodeStream[])
-
cached
NodeStream<T> cached()
Returns a node stream containing all the elements of this node stream, but which will evaluate the upstream pipeline only once. The returned stream is not necessarily lazy, which means it may evaluate the upstream pipeline as soon as the call to this method is made.This is useful e.g. if you want to call several terminal operations without executing the pipeline several times. For example,
NodeStream<T> stream = NodeStream.of(...) // long pipeline // ... .cached() // downstream // ... ; stream.forEach(this::addViolation); // both up- and downstream will be evaluated curViolations += stream.count(); // only downstream is evaluated
- Returns:
- A cached node stream
-
take
NodeStream<T> take(int maxSize)
Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.- Parameters:
maxSize
- Maximum size of the returned stream- Returns:
- A new node stream
- Throws:
IllegalArgumentException
- if n is negative- See Also:
Stream.limit(long)
,drop(int)
-
drop
NodeStream<T> drop(int n)
Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream. If this stream contains fewer than n elements then an empty stream will be returned.- Parameters:
n
- the number of leading elements to skip- Returns:
- A new node stream
- Throws:
IllegalArgumentException
- if n is negative- See Also:
Stream.skip(long)
,take(int)
,dropLast(int)
-
dropLast
NodeStream<T> dropLast(int n)
Returns a stream consisting of the elements of this stream except the n tail elements. If n is greater than the number of elements of this stream, returns an empty stream. This requires a lookahead buffer in general.- Parameters:
n
- the number of trailing elements to skip- Returns:
- A new node stream
- Throws:
IllegalArgumentException
- if n is negative- See Also:
drop(int)
-
takeWhile
NodeStream<T> takeWhile(Predicate<? super @NonNull T> predicate)
Returns the longest prefix of elements that satisfy the given predicate.- Parameters:
predicate
- The predicate used to test elements.- Returns:
- the longest prefix of this stream whose elements all satisfy the predicate.
-
distinct
NodeStream<T> distinct()
Returns a stream consisting of the distinct elements (w.r.tObject.equals(Object)
) of this stream.- Returns:
- a stream consisting of the distinct elements of this stream
-
ancestors
default NodeStream<Node> ancestors()
Returns a node stream containing all the ancestors of the nodes contained in this stream. The returned stream doesn't preserve document order, since ancestors are yielded in innermost to outermost order.This is equivalent to
flatMap(Node::ancestors)
.- Returns:
- A stream of ancestors
- See Also:
Node.ancestors()
,ancestorsOrSelf()
,ancestors(Class)
-
ancestorsOrSelf
default NodeStream<Node> ancestorsOrSelf()
Returns a node stream containing the nodes contained in this stream and their ancestors. The nodes of the returned stream are yielded in a depth-first fashion.This is equivalent to
flatMap(Node::ancestorsOrSelf)
.- Returns:
- A stream of ancestors
- See Also:
ancestors()
-
parents
default NodeStream<Node> parents()
Returns a node stream containing all the (first-degree) parents of the nodes contained in this stream.This is equivalent to
map(Node::getParent)
.- Returns:
- A stream of parents
- See Also:
ancestors()
,ancestorsOrSelf()
-
children
default NodeStream<Node> children()
Returns a node stream containing all the children of the nodes contained in this stream.This is equivalent to
flatMap(Node::children)
.- Returns:
- A stream of children
- See Also:
Node.children()
,children(Class)
-
descendants
NodeStream.DescendantNodeStream<Node> descendants()
Returns a node stream containing all the strict descendants of the nodes contained in this stream. SeeNodeStream.DescendantNodeStream
for details.This is equivalent to
flatMap(Node::descendants)
, except the returned stream is aNodeStream.DescendantNodeStream
.- Returns:
- A stream of descendants
- See Also:
Node.descendants()
,descendants(Class)
,descendantsOrSelf()
-
descendantsOrSelf
NodeStream.DescendantNodeStream<Node> descendantsOrSelf()
Returns a node stream containing the nodes contained in this stream and their descendants. SeeNodeStream.DescendantNodeStream
for details.This is equivalent to
flatMap(Node::descendantsOrSelf)
, except the returned stream is aNodeStream.DescendantNodeStream
.- Returns:
- A stream of descendants
- See Also:
Node.descendantsOrSelf()
,descendants()
-
followingSiblings
default NodeStream<Node> followingSiblings()
Returns a node stream containing all the following siblings of the nodes contained in this stream.- Returns:
- A stream of siblings
-
precedingSiblings
default NodeStream<Node> precedingSiblings()
Returns a node stream containing all the preceding siblings of the nodes contained in this stream. The nodes are yielded from left to right, i.e. in document order.- Returns:
- A stream of siblings
-
children
default <R extends Node> NodeStream<R> children(Class<? extends R> rClass)
Returns the children stream of each node in this stream, filtered by the given node type.This is equivalent to
children().filterIs(rClass)
.- Type Parameters:
R
- Type of node the returned stream should contain- Parameters:
rClass
- Type of node the returned stream should contain- Returns:
- A new node stream
- See Also:
filterIs(Class)
,Node.children(Class)
-
firstChild
default <R extends Node> NodeStream<R> firstChild(Class<? extends R> rClass)
Returns a stream containing the first child of each of the nodes in this stream that has the given type.This is equivalent to
flatMap(it -> it.children(rClass).take(1))
.- Type Parameters:
R
- Type of node the returned stream should contain- Parameters:
rClass
- Type of node the returned stream should contain- Returns:
- A new node stream
- See Also:
Node.children(Class)
-
descendants
<R extends Node> NodeStream.DescendantNodeStream<R> descendants(Class<? extends R> rClass)
Returns the descendant stream of each node in this stream, filtered by the given node type. SeeNodeStream.DescendantNodeStream
for details.This is equivalent to
descendants().filterIs(rClass)
, except the returned stream is aNodeStream.DescendantNodeStream
.- Type Parameters:
R
- Type of node the returned stream should contain- Parameters:
rClass
- Type of node the returned stream should contain- Returns:
- A new node stream
- See Also:
filterIs(Class)
,Node.descendants(Class)
-
ancestors
default <R extends Node> NodeStream<R> ancestors(Class<? extends R> rClass)
Returns the ancestor stream of each node in this stream, filtered by the given node type.This is equivalent to
ancestors().filterIs(rClass)
.- Type Parameters:
R
- Type of node the returned stream should contain- Parameters:
rClass
- Type of node the returned stream should contain- Returns:
- A new node stream
- See Also:
filterIs(Class)
,Node.ancestors(Class)
-
filterNot
default NodeStream<T> filterNot(Predicate<? super @NonNull T> predicate)
Filters the node of this stream using the negation of the given predicate.This is equivalent to
filter(predicate.negate())
- Parameters:
predicate
- A predicate to apply to each node to determine if it should be included- Returns:
- A filtered node stream
- See Also:
filter(Predicate)
-
filterMatching
default <U> NodeStream<T> filterMatching(Function<? super @NonNull T,? extends @Nullable U> extractor, U comparand)
Filters the nodes of this stream by comparing a value extracted from the nodes with the given constant. This takes care of null value by callingObjects.equals(Object, Object)
. E.g. to filter nodes that have the image"a"
, usefilterMatching(Node::getImage, "a")
.This is equivalent to
filter(t -> Objects.equals(extractor.apply(t), comparand))
.- Type Parameters:
U
- Type of value to compare- Parameters:
extractor
- Function extracting a value from the nodes of this streamcomparand
- Value to which the extracted value will be compared- Returns:
- A filtered node stream
- See Also:
filter(Predicate)
,filterNotMatching(Function, Object)
-
filterIs
default <R extends Node> NodeStream<R> filterIs(Class<? extends R> rClass)
Filters the nodes of this stream that are a subtype of the given class.This is equivalent to
filter(rClass::isInstance).map(rClass::cast)
.- Type Parameters:
R
- The type of the nodes of the returned stream- Parameters:
rClass
- The type of the nodes of the returned stream- Returns:
- A filtered node stream
- See Also:
filter(Predicate)
,asInstanceOf(Class, Class[])
-
filterNotMatching
default <U> NodeStream<T> filterNotMatching(Function<? super @NonNull T,? extends @Nullable U> extractor, U comparand)
Inverse offilterMatching(Function, Object)
.- Type Parameters:
U
- Type of value to compare- Parameters:
extractor
- Function extracting a value from the nodes of this streamcomparand
- Value to which the extracted value will be compared- Returns:
- A filtered node stream
- See Also:
filter(Predicate)
,filterMatching(Function, Object)
-
reduce
default <R> R reduce(R identity, BiFunction<? super R,? super @NonNull T,? extends R> accumulate)
Reduce the elements of this stream sequentially.- Type Parameters:
R
- Result type- Parameters:
identity
- Identity elementaccumulate
- Combine an intermediate result with a new node from this stream, returns the next intermediate result- Returns:
- The last intermediate result (identity if this stream is empty)
-
sumBy
default int sumBy(ToIntFunction<? super @NonNull T> toInt)
Sum the elements of this stream by associating them to an integer.- Parameters:
toInt
- Map an element to an integer, which will be added to the running sum returns the next intermediate result- Returns:
- The sum, zero if the stream is empty.
-
count
int count()
Returns the number of nodes in this stream.- Returns:
- the number of nodes in this stream
-
sumByInt
default int sumByInt(ToIntFunction<? super @NonNull T> intMapper)
Returns the sum of the value of the function applied to all elements of this stream.- Parameters:
intMapper
- Mapping function- Returns:
- The sum
-
nonEmpty
boolean nonEmpty()
Returns 'true' if the stream has at least one element.- Returns:
- 'true' if the stream has at least one element.
- See Also:
isEmpty()
-
isEmpty
default boolean isEmpty()
Returns 'true' if the stream has no elements.- Returns:
- 'true' if the stream has no elements.
- See Also:
nonEmpty()
-
any
boolean any(Predicate<? super @NonNull T> predicate)
Returns whether any elements of this stream match the provided predicate. If the stream is empty then false is returned and the predicate is not evaluated.- Parameters:
predicate
- The predicate that one element should match for this method to return true- Returns:
- true if any elements of the stream match the provided predicate, otherwise false
- See Also:
all(Predicate)
,none(Predicate)
-
none
boolean none(Predicate<? super @NonNull T> predicate)
Returns whether no elements of this stream match the provided predicate. If the stream is empty then true is returned and the predicate is not evaluated.- Parameters:
predicate
- The predicate that no element should match for this method to return true- Returns:
- true if either no elements of the stream match the provided predicate or the stream is empty, otherwise false
- See Also:
any(Predicate)
,all(Predicate)
-
all
boolean all(Predicate<? super @NonNull T> predicate)
Returns whether all elements of this stream match the provided predicate. If the stream is empty then true is returned and the predicate is not evaluated.- Parameters:
predicate
- The predicate that all elements should match for this method to return true- Returns:
- true if either all elements of the stream match the provided predicate or the stream is empty, otherwise false
- See Also:
any(Predicate)
,none(Predicate)
-
get
default @Nullable T get(int n)
Returns the element at index n in this stream. If no such element exists,null
is returned.This is equivalent to
.drop(n)
.first()
If you'd rather continue processing the nth element as a node stream, you can use
.drop(n)
.take(1)
- Parameters:
n
- Index of the element to find- Returns:
- The nth element of this stream, or
null
if it doesn't exist - Throws:
IllegalArgumentException
- if n is negative
-
first
@Nullable T first()
Returns the first element of this stream, ornull
if the stream is empty.If you'd rather continue processing the first element as a node stream, you can use
take(1)
.This is equivalent to
get(0)
.- Returns:
- the first element of this stream, or
null
if it doesn't exist - See Also:
first(Predicate)
,first(Class)
,firstOpt()
-
firstOrThrow
default @NonNull T firstOrThrow()
Returns the first element of this stream, or throws aNoSuchElementException
if the stream is empty.- Returns:
- the first element of this stream
- See Also:
first(Predicate)
,first(Class)
,firstOpt()
-
firstOpt
default Optional<T> firstOpt()
Returns an optional containing the first element of this stream, or an empty optional if the stream is empty.This is equivalent to
Optional.ofNullable(first())
.- Returns:
- the first element of this stream, or an empty optional if it doesn't exist
- See Also:
first(Predicate)
,first(Class)
,first()
-
first
default @Nullable T first(Predicate<? super @NonNull T> predicate)
Returns the first element of this stream that matches the given predicate, ornull
if there is none.- Parameters:
predicate
- The predicate that one element should match for this method to return it- Returns:
- the first element of this stream that matches the given
predicate, or
null
if it doesn't exist - See Also:
first()
,first(Class)
-
first
default <R extends Node> @Nullable R first(Class<? extends R> rClass)
Returns the first element of this stream of the given type, ornull
if there is none.- Type Parameters:
R
- The type of node to find- Parameters:
rClass
- The type of node to find- Returns:
- the first element of this stream of the given type, or
null
if it doesn't exist - See Also:
first()
,first(Predicate)
-
firstNonNull
default <R extends Node> @Nullable R firstNonNull(Function<? super @NonNull T,? extends @Nullable R> nullableFun)
Returns the first element of this stream for which the mapping function returns a non-null result. Returns null if there is no such element. This is a convenience method to use withasInstanceOf(Class, Class[])
, because using justmap
followed byfirst()
will lose the type information and mentioning explicit type arguments would be needed.- Type Parameters:
R
- Result type- Parameters:
nullableFun
- Mapper function- Returns:
- A node, or null
- See Also:
asInstanceOf(Class, Class[])
-
last
@Nullable T last()
Returns the last element of this stream, ornull
if the stream is empty. This may or may not require traversing all the elements of the stream.- Returns:
- the last element of this stream, or
null
if it doesn't exist
-
last
default <R extends Node> @Nullable R last(Class<? extends R> rClass)
Returns the last element of this stream of the given type, ornull
if there is none.- Type Parameters:
R
- The type of node to find- Parameters:
rClass
- The type of node to find- Returns:
- the last element of this stream of the given type, or
null
if it doesn't exist - See Also:
last()
-
collect
<R,A> R collect(Collector<? super @NonNull T,A,R> collector)
Collects the elements of this node stream using the specifiedCollector
. This is equivalent totoStream()
followed byStream.collect(Collector)
.- Type Parameters:
R
- the type of the resultA
- the intermediate accumulation type of theCollector
- Parameters:
collector
- theCollector
describing the reduction- Returns:
- the result of the reduction
- See Also:
Stream.collect(Collector)
,Collectors
,toList()
,toList(Function)
-
toStream
Stream<@NonNull T> toStream()
Returns a new stream of Ts having the pipeline of operations defined by this node stream. This can be called multiple times.- Returns:
- A stream containing the same elements as this node stream
-
toList
default List<T> toList()
Collects the elements of this node stream into a list. Just like forCollectors.toList()
, there are no guarantees on the type, mutability, serializability, or thread-safety of the returned list.This is equivalent to
collect(Collectors.toList())
.- Returns:
- a list containing the elements of this stream
- See Also:
Collectors.toList()
,collect(Collector)
-
toList
default <R> List<R> toList(Function<? super @NonNull T,? extends R> mapper)
Maps the elements of this node stream using the given mapping and collects the results into a list.This is equivalent to
collect(Collectors.mapping(mapper, Collectors.toList()))
.- Type Parameters:
R
- Return type of the mapper, and element type of the returned list- Parameters:
mapper
- Mapping function- Returns:
- a list containing the elements of this stream
- See Also:
Collectors.mapping(Function, Collector)
,collect(Collector)
-
of
static <T extends Node> NodeStream<T> of(@Nullable T node)
Returns a node stream containing zero or one node, depending on whether the argument is null or not.If you know the node is not null, you can also call
node.
.asStream()
- Type Parameters:
T
- Element type of the returned stream- Parameters:
node
- The node to contain- Returns:
- A new node stream
- See Also:
Node.asStream()
-
fromIterable
static <T extends Node> NodeStream<T> fromIterable(Iterable<? extends @Nullable T> iterable)
Returns a new node stream that contains the same elements as the given iterable. Null items are filtered out of the resulting stream.It's possible to map an iterator to a node stream by calling
fromIterable(() -> iterator)
, but then the returned node stream would only be iterable once.- Type Parameters:
T
- Type of nodes in the returned node stream- Parameters:
iterable
- Source of nodes- Returns:
- A new node stream
-
ofOptional
static <T extends Node> NodeStream<T> ofOptional(Optional<? extends T> optNode)
Returns a node stream containing zero or one node, depending on whether the optional is empty or not.- Type Parameters:
T
- Element type of the returned stream- Parameters:
optNode
- The node to contain- Returns:
- A new node stream
- See Also:
of(Node)
-
of
@SafeVarargs static <T extends Node> NodeStream<T> of(T... nodes)
Returns a node stream whose elements are the given nodes in order. Null elements are not part of the resulting node stream.- Type Parameters:
T
- Element type of the returned stream- Parameters:
nodes
- The elements of the new stream- Returns:
- A new node stream
-
union
@SafeVarargs static <T extends Node> NodeStream<T> union(NodeStream<? extends T>... streams)
Returns a node stream containing all the elements of the given streams, one after the other.- Type Parameters:
T
- The type of stream elements- Parameters:
streams
- the streams to flatten- Returns:
- the concatenation of the input streams
-
union
static <T extends Node> NodeStream<T> union(Iterable<? extends NodeStream<? extends T>> streams)
Returns a node stream containing all the elements of the given streams, one after the other.- Type Parameters:
T
- The type of stream elements- Parameters:
streams
- the streams to flatten- Returns:
- the concatenation of the input streams
-
empty
static <T extends Node> NodeStream<T> empty()
Returns an empty node stream.- Type Parameters:
T
- Expected type of nodes.- Returns:
- An empty node stream
-
forkJoin
@SafeVarargs static <T extends Node,R extends Node> NodeStream<R> forkJoin(NodeStream<? extends T> upstream, Function<? super @NonNull T,? extends NodeStream<? extends R>> fst, Function<? super @NonNull T,? extends NodeStream<? extends R>> snd, Function<? super @NonNull T,? extends NodeStream<? extends R>>... rest)
Applies the given mapping functions to the given upstream in order and merges the results into a new node stream. This allows exploring several paths at once on the same stream. The method is lazy and won't evaluate the upstream pipeline several times.- Type Parameters:
R
- Common supertype for the element type of the streams returned by the mapping functions- Parameters:
upstream
- Source of the streamfst
- First mappersnd
- Second mapperrest
- Rest of the mappers- Returns:
- A merged node stream
-
asInstanceOf
@SafeVarargs static <O> Function<@Nullable Object,@Nullable O> asInstanceOf(Class<? extends O> c1, Class<? extends O>... rest)
Returns a map function, that checks whether the parameter is an instance of any of the given classes. If so, it returns the parameter, otherwise it returns null.This may be used to filter a node stream to those specific classes, for example:
Using this in the middle of a call chain might require passing explicit type arguments:NodeStream<ASTExpression> exprs = someStream.map(asInstanceOf(ASTInfixExpression.class, ASTCastExpression.class));
ASTTypeDeclaration ts = node.ancestors() .<ASTTypeDeclaration>map(asInstanceOf(ASTClassDeclaration.class, ASTEnumDeclaration.class)) .first(); // would not compile without the explicit type arguments
For this use case the
firstNonNull(Function)
method may be used, which reduces the above toASTTypeDeclaration ts = node.ancestors().firstNonNull(asInstanceOf(ASTClassDeclaration.class, ASTEnumDeclaration.class));
- Type Parameters:
O
- Output type- Parameters:
c1
- First type to testrest
- Other types to test- See Also:
firstNonNull(Function)
-
-