Commit | Line | Data |
---|---|---|
648903b9 AM |
1 | /******************************************************************************* |
2 | * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials | |
5 | * are made available under the terms of the Eclipse Public License v1.0 | |
6 | * which accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | *******************************************************************************/ | |
9 | ||
10 | package org.eclipse.tracecompass.common.core; | |
11 | ||
12 | import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; | |
13 | ||
369de651 AM |
14 | import java.util.Iterator; |
15 | import java.util.Spliterator; | |
16 | import java.util.Spliterators; | |
648903b9 AM |
17 | import java.util.function.Function; |
18 | import java.util.stream.Stream; | |
19 | import java.util.stream.StreamSupport; | |
20 | ||
21 | /** | |
22 | * Common utilities for {@link Stream}. | |
23 | * | |
24 | * @author Alexandre Montplaisir | |
25 | * @since 2.0 | |
26 | */ | |
27 | public final class StreamUtils { | |
28 | ||
29 | private StreamUtils() {} | |
30 | ||
31 | /** | |
32 | * Get a sequential {@link Stream} from an {@link Iterable}. | |
33 | * | |
34 | * @param iterable | |
35 | * Any iterable | |
36 | * @return The stream on the elements of the iterable | |
37 | */ | |
38 | public static <T> Stream<T> getStream(Iterable<T> iterable) { | |
39 | return StreamSupport.stream(iterable.spliterator(), false); | |
40 | } | |
41 | ||
369de651 AM |
42 | /** |
43 | * Get a {@link Stream} from a generic {@link Iterator}. | |
44 | * | |
45 | * Depending on the type of terminal operation used on the stream, the | |
46 | * iterator may or may not have some elements remaining. Be wary if you | |
47 | * re-use the same iterator afterwards. | |
48 | * | |
49 | * @param iterator | |
50 | * The iterator to wrap | |
51 | * @return A stream containing the iterator's elements | |
52 | * @since 2.2 | |
53 | */ | |
54 | public static <T> Stream<T> getStream(Iterator<T> iterator) { | |
55 | Spliterator<T> spliterator = Spliterators.spliteratorUnknownSize(iterator, 0); | |
56 | return StreamSupport.stream(spliterator, false); | |
57 | } | |
58 | ||
648903b9 AM |
59 | /** |
60 | * Generic utility class to "flatten" a data structure using the | |
61 | * {@link Stream} API. | |
62 | * | |
63 | * @param <T> | |
64 | * The type of container, or "node" in the tree | |
65 | */ | |
66 | public static class StreamFlattener<T> { | |
67 | ||
68 | private final Function<T, Stream<T>> fGetChildrenFunction; | |
69 | ||
70 | /** | |
71 | * Constructor | |
72 | * | |
73 | * @param getChildrenFunction | |
74 | * The function to use to get each element's children. Should | |
75 | * return a {@link Stream} of those children. | |
76 | */ | |
77 | public StreamFlattener(Function<T, Stream<T>> getChildrenFunction) { | |
78 | fGetChildrenFunction = getChildrenFunction; | |
79 | } | |
80 | ||
81 | /** | |
82 | * Do an in-order flattening of the data structure, starting at the given | |
83 | * element (or node). | |
84 | * | |
85 | * @param element | |
86 | * The tree node or similar from which to start | |
87 | * @return A unified Stream of all the children that were found, | |
88 | * recursively. | |
89 | */ | |
90 | public Stream<T> flatten(T element) { | |
91 | Stream<T> ret = Stream.concat( | |
92 | Stream.of(element), | |
93 | fGetChildrenFunction.apply(element).flatMap(this::flatten)); | |
94 | return checkNotNull(ret); | |
95 | } | |
96 | } | |
97 | } |