author | darcy |
Wed, 10 Jul 2013 11:05:39 -0700 | |
changeset 18796 | 486b43748d9b |
parent 17920 | eef25bc37ccd |
child 19435 | 9d7530ff42cb |
permissions | -rw-r--r-- |
16929 | 1 |
/* |
2 |
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. |
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
package java.util; |
|
26 |
||
27 |
import java.util.function.Consumer; |
|
28 |
import java.util.function.DoubleConsumer; |
|
29 |
import java.util.function.IntConsumer; |
|
30 |
import java.util.function.LongConsumer; |
|
31 |
||
32 |
/** |
|
33 |
* An object for traversing and partitioning elements of a source. The source |
|
34 |
* of elements covered by a Spliterator could be, for example, an array, a |
|
35 |
* {@link Collection}, an IO channel, or a generator function. |
|
36 |
* |
|
37 |
* <p>A Spliterator may traverse elements individually ({@link |
|
38 |
* #tryAdvance tryAdvance()}) or sequentially in bulk |
|
39 |
* ({@link #forEachRemaining forEachRemaining()}). |
|
40 |
* |
|
41 |
* <p>A Spliterator may also partition off some of its elements (using |
|
42 |
* {@link #trySplit}) as another Spliterator, to be used in |
|
43 |
* possibly-parallel operations. Operations using a Spliterator that |
|
44 |
* cannot split, or does so in a highly imbalanced or inefficient |
|
45 |
* manner, are unlikely to benefit from parallelism. Traversal |
|
46 |
* and splitting exhaust elements; each Spliterator is useful for only a single |
|
47 |
* bulk computation. |
|
48 |
* |
|
49 |
* <p>A Spliterator also reports a set of {@link #characteristics()} of its |
|
50 |
* structure, source, and elements from among {@link #ORDERED}, |
|
51 |
* {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED}, {@link #NONNULL}, |
|
52 |
* {@link #IMMUTABLE}, {@link #CONCURRENT}, and {@link #SUBSIZED}. These may |
|
53 |
* be employed by Spliterator clients to control, specialize or simplify |
|
54 |
* computation. For example, a Spliterator for a {@link Collection} would |
|
55 |
* report {@code SIZED}, a Spliterator for a {@link Set} would report |
|
56 |
* {@code DISTINCT}, and a Spliterator for a {@link SortedSet} would also |
|
57 |
* report {@code SORTED}. Characteristics are reported as a simple unioned bit |
|
58 |
* set. |
|
59 |
* |
|
60 |
* Some characteristics additionally constrain method behavior; for example if |
|
61 |
* {@code ORDERED}, traversal methods must conform to their documented ordering. |
|
62 |
* New characteristics may be defined in the future, so implementors should not |
|
63 |
* assign meanings to unlisted values. |
|
64 |
* |
|
18796
486b43748d9b
8020294: Fix doclint issues in java.util.Spliterator
darcy
parents:
17920
diff
changeset
|
65 |
* <p><a name="binding">A Spliterator that does not report {@code IMMUTABLE} or |
16929 | 66 |
* {@code CONCURRENT} is expected to have a documented policy concerning: |
67 |
* when the spliterator <em>binds</em> to the element source; and detection of |
|
18796
486b43748d9b
8020294: Fix doclint issues in java.util.Spliterator
darcy
parents:
17920
diff
changeset
|
68 |
* structural interference of the element source detected after binding.</a> A |
16929 | 69 |
* <em>late-binding</em> Spliterator binds to the source of elements at the |
70 |
* point of first traversal, first split, or first query for estimated size, |
|
71 |
* rather than at the time the Spliterator is created. A Spliterator that is |
|
72 |
* not <em>late-binding</em> binds to the source of elements at the point of |
|
73 |
* construction or first invocation of any method. Modifications made to the |
|
74 |
* source prior to binding are reflected when the Spliterator is traversed. |
|
75 |
* After binding a Spliterator should, on a best-effort basis, throw |
|
76 |
* {@link ConcurrentModificationException} if structural interference is |
|
77 |
* detected. Spliterators that do this are called <em>fail-fast</em>. |
|
78 |
* |
|
79 |
* <p>Spliterators can provide an estimate of the number of remaining elements |
|
80 |
* via the {@link #estimateSize} method. Ideally, as reflected in characteristic |
|
81 |
* {@link #SIZED}, this value corresponds exactly to the number of elements |
|
82 |
* that would be encountered in a successful traversal. However, even when not |
|
83 |
* exactly known, an estimated value value may still be useful to operations |
|
84 |
* being performed on the source, such as helping to determine whether it is |
|
85 |
* preferable to split further or traverse the remaining elements sequentially. |
|
86 |
* |
|
87 |
* <p>Despite their obvious utility in parallel algorithms, spliterators are not |
|
88 |
* expected to be thread-safe; instead, implementations of parallel algorithms |
|
89 |
* using spliterators should ensure that the spliterator is only used by one |
|
90 |
* thread at a time. This is generally easy to attain via <em>serial |
|
91 |
* thread-confinement</em>, which often is a natural consequence of typical |
|
92 |
* parallel algorithms that work by recursive decomposition. A thread calling |
|
93 |
* {@link #trySplit()} may hand over the returned Spliterator to another thread, |
|
94 |
* which in turn may traverse or further split that Spliterator. The behaviour |
|
95 |
* of splitting and traversal is undefined if two or more threads operate |
|
96 |
* concurrently on the same spliterator. If the original thread hands a |
|
97 |
* spliterator off to another thread for processing, it is best if that handoff |
|
98 |
* occurs before any elements are consumed with {@link #tryAdvance(Consumer) |
|
99 |
* tryAdvance()}, as certain guarantees (such as the accuracy of |
|
100 |
* {@link #estimateSize()} for {@code SIZED} spliterators) are only valid before |
|
101 |
* traversal has begun. |
|
102 |
* |
|
103 |
* <p>Primitive subtype specializations of {@code Spliterator} are provided for |
|
104 |
* {@link OfInt int}, {@link OfLong long}, and {@link OfDouble double} values. |
|
105 |
* The subtype default implementations of |
|
106 |
* {@link Spliterator#tryAdvance(java.util.function.Consumer)} |
|
107 |
* and {@link Spliterator#forEachRemaining(java.util.function.Consumer)} box |
|
108 |
* primitive values to instances of their corresponding wrapper class. Such |
|
109 |
* boxing may undermine any performance advantages gained by using the primitive |
|
110 |
* specializations. To avoid boxing, the corresponding primitive-based methods |
|
111 |
* should be used. For example, |
|
112 |
* {@link Spliterator.OfInt#tryAdvance(java.util.function.IntConsumer)} |
|
113 |
* and {@link Spliterator.OfInt#forEachRemaining(java.util.function.IntConsumer)} |
|
114 |
* should be used in preference to |
|
115 |
* {@link Spliterator.OfInt#tryAdvance(java.util.function.Consumer)} and |
|
116 |
* {@link Spliterator.OfInt#forEachRemaining(java.util.function.Consumer)}. |
|
117 |
* Traversal of primitive values using boxing-based methods |
|
118 |
* {@link #tryAdvance tryAdvance()} and |
|
119 |
* {@link #forEachRemaining(java.util.function.Consumer) forEachRemaining()} |
|
120 |
* does not affect the order in which the values, transformed to boxed values, |
|
121 |
* are encountered. |
|
122 |
* |
|
123 |
* @apiNote |
|
124 |
* <p>Spliterators, like {@code Iterators}s, are for traversing the elements of |
|
125 |
* a source. The {@code Spliterator} API was designed to support efficient |
|
126 |
* parallel traversal in addition to sequential traversal, by supporting |
|
127 |
* decomposition as well as single-element iteration. In addition, the |
|
128 |
* protocol for accessing elements via a Spliterator is designed to impose |
|
129 |
* smaller per-element overhead than {@code Iterator}, and to avoid the inherent |
|
130 |
* race involved in having separate methods for {@code hasNext()} and |
|
131 |
* {@code next()}. |
|
132 |
* |
|
133 |
* <p>For mutable sources, arbitrary and non-deterministic behavior may occur if |
|
134 |
* the source is structurally interfered with (elements added, replaced, or |
|
135 |
* removed) between the time that the Spliterator binds to its data source and |
|
136 |
* the end of traversal. For example, such interference will produce arbitrary, |
|
137 |
* non-deterministic results when using the {@code java.util.stream} framework. |
|
138 |
* |
|
139 |
* <p>Structural interference of a source can be managed in the following ways |
|
140 |
* (in approximate order of decreasing desirability): |
|
141 |
* <ul> |
|
142 |
* <li>The source cannot be structurally interfered with. |
|
17693
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
143 |
* <br>For example, an instance of |
16929 | 144 |
* {@link java.util.concurrent.CopyOnWriteArrayList} is an immutable source. |
145 |
* A Spliterator created from the source reports a characteristic of |
|
146 |
* {@code IMMUTABLE}.</li> |
|
147 |
* <li>The source manages concurrent modifications. |
|
17693
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
148 |
* <br>For example, a key set of a {@link java.util.concurrent.ConcurrentHashMap} |
16929 | 149 |
* is a concurrent source. A Spliterator created from the source reports a |
150 |
* characteristic of {@code CONCURRENT}.</li> |
|
151 |
* <li>The mutable source provides a late-binding and fail-fast Spliterator. |
|
17693
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
152 |
* <br>Late binding narrows the window during which interference can affect |
16929 | 153 |
* the calculation; fail-fast detects, on a best-effort basis, that structural |
154 |
* interference has occurred after traversal has commenced and throws |
|
155 |
* {@link ConcurrentModificationException}. For example, {@link ArrayList}, |
|
156 |
* and many other non-concurrent {@code Collection} classes in the JDK, provide |
|
157 |
* a late-binding, fail-fast spliterator.</li> |
|
158 |
* <li>The mutable source provides a non-late-binding but fail-fast Spliterator. |
|
17693
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
159 |
* <br>The source increases the likelihood of throwing |
16929 | 160 |
* {@code ConcurrentModificationException} since the window of potential |
161 |
* interference is larger.</li> |
|
162 |
* <li>The mutable source provides a late-binding and non-fail-fast Spliterator. |
|
17693
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
163 |
* <br>The source risks arbitrary, non-deterministic behavior after traversal |
16929 | 164 |
* has commenced since interference is not detected. |
165 |
* </li> |
|
166 |
* <li>The mutable source provides a non-late-binding and non-fail-fast |
|
167 |
* Spliterator. |
|
17693
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
168 |
* <br>The source increases the risk of arbitrary, non-deterministic behavior |
16929 | 169 |
* since non-detected interference may occur after construction. |
170 |
* </li> |
|
171 |
* </ul> |
|
172 |
* |
|
173 |
* <p><b>Example.</b> Here is a class (not a very useful one, except |
|
174 |
* for illustration) that maintains an array in which the actual data |
|
175 |
* are held in even locations, and unrelated tag data are held in odd |
|
176 |
* locations. Its Spliterator ignores the tags. |
|
177 |
* |
|
178 |
* <pre> {@code |
|
179 |
* class TaggedArray<T> { |
|
180 |
* private final Object[] elements; // immutable after construction |
|
181 |
* TaggedArray(T[] data, Object[] tags) { |
|
182 |
* int size = data.length; |
|
183 |
* if (tags.length != size) throw new IllegalArgumentException(); |
|
184 |
* this.elements = new Object[2 * size]; |
|
185 |
* for (int i = 0, j = 0; i < size; ++i) { |
|
186 |
* elements[j++] = data[i]; |
|
187 |
* elements[j++] = tags[i]; |
|
188 |
* } |
|
189 |
* } |
|
190 |
* |
|
191 |
* public Spliterator<T> spliterator() { |
|
192 |
* return new TaggedArraySpliterator<>(elements, 0, elements.length); |
|
193 |
* } |
|
194 |
* |
|
195 |
* static class TaggedArraySpliterator<T> implements Spliterator<T> { |
|
196 |
* private final Object[] array; |
|
197 |
* private int origin; // current index, advanced on split or traversal |
|
198 |
* private final int fence; // one past the greatest index |
|
199 |
* |
|
200 |
* TaggedArraySpliterator(Object[] array, int origin, int fence) { |
|
201 |
* this.array = array; this.origin = origin; this.fence = fence; |
|
202 |
* } |
|
203 |
* |
|
204 |
* public void forEachRemaining(Consumer<? super T> action) { |
|
205 |
* for (; origin < fence; origin += 2) |
|
206 |
* action.accept((T) array[origin]); |
|
207 |
* } |
|
208 |
* |
|
209 |
* public boolean tryAdvance(Consumer<? super T> action) { |
|
210 |
* if (origin < fence) { |
|
211 |
* action.accept((T) array[origin]); |
|
212 |
* origin += 2; |
|
213 |
* return true; |
|
214 |
* } |
|
215 |
* else // cannot advance |
|
216 |
* return false; |
|
217 |
* } |
|
218 |
* |
|
219 |
* public Spliterator<T> trySplit() { |
|
220 |
* int lo = origin; // divide range in half |
|
221 |
* int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even |
|
222 |
* if (lo < mid) { // split out left half |
|
223 |
* origin = mid; // reset this Spliterator's origin |
|
224 |
* return new TaggedArraySpliterator<>(array, lo, mid); |
|
225 |
* } |
|
226 |
* else // too small to split |
|
227 |
* return null; |
|
228 |
* } |
|
229 |
* |
|
230 |
* public long estimateSize() { |
|
231 |
* return (long)((fence - origin) / 2); |
|
232 |
* } |
|
233 |
* |
|
234 |
* public int characteristics() { |
|
235 |
* return ORDERED | SIZED | IMMUTABLE | SUBSIZED; |
|
236 |
* } |
|
237 |
* } |
|
238 |
* }}</pre> |
|
239 |
* |
|
240 |
* <p>As an example how a parallel computation framework, such as the |
|
241 |
* {@code java.util.stream} package, would use Spliterator in a parallel |
|
242 |
* computation, here is one way to implement an associated parallel forEach, |
|
243 |
* that illustrates the primary usage idiom of splitting off subtasks until |
|
244 |
* the estimated amount of work is small enough to perform |
|
245 |
* sequentially. Here we assume that the order of processing across |
|
246 |
* subtasks doesn't matter; different (forked) tasks may further split |
|
247 |
* and process elements concurrently in undetermined order. This |
|
248 |
* example uses a {@link java.util.concurrent.CountedCompleter}; |
|
249 |
* similar usages apply to other parallel task constructions. |
|
250 |
* |
|
251 |
* <pre>{@code |
|
252 |
* static <T> void parEach(TaggedArray<T> a, Consumer<T> action) { |
|
253 |
* Spliterator<T> s = a.spliterator(); |
|
254 |
* long targetBatchSize = s.estimateSize() / (ForkJoinPool.getCommonPoolParallelism() * 8); |
|
255 |
* new ParEach(null, s, action, targetBatchSize).invoke(); |
|
256 |
* } |
|
257 |
* |
|
258 |
* static class ParEach<T> extends CountedCompleter<Void> { |
|
259 |
* final Spliterator<T> spliterator; |
|
260 |
* final Consumer<T> action; |
|
261 |
* final long targetBatchSize; |
|
262 |
* |
|
263 |
* ParEach(ParEach<T> parent, Spliterator<T> spliterator, |
|
264 |
* Consumer<T> action, long targetBatchSize) { |
|
265 |
* super(parent); |
|
266 |
* this.spliterator = spliterator; this.action = action; |
|
267 |
* this.targetBatchSize = targetBatchSize; |
|
268 |
* } |
|
269 |
* |
|
270 |
* public void compute() { |
|
271 |
* Spliterator<T> sub; |
|
272 |
* while (spliterator.estimateSize() > targetBatchSize && |
|
273 |
* (sub = spliterator.trySplit()) != null) { |
|
274 |
* addToPendingCount(1); |
|
275 |
* new ParEach<>(this, sub, action, targetBatchSize).fork(); |
|
276 |
* } |
|
277 |
* spliterator.forEachRemaining(action); |
|
278 |
* propagateCompletion(); |
|
279 |
* } |
|
280 |
* }}</pre> |
|
281 |
* |
|
282 |
* @implNote |
|
283 |
* If the boolean system property {@code org.openjdk.java.util.stream.tripwire} |
|
284 |
* is set to {@code true} then diagnostic warnings are reported if boxing of |
|
285 |
* primitive values occur when operating on primitive subtype specializations. |
|
286 |
* |
|
17693
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
287 |
* @param <T> the type of elements returned by this Spliterator |
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
288 |
* |
16929 | 289 |
* @see Collection |
290 |
* @since 1.8 |
|
291 |
*/ |
|
292 |
public interface Spliterator<T> { |
|
293 |
/** |
|
294 |
* If a remaining element exists, performs the given action on it, |
|
295 |
* returning {@code true}; else returns {@code false}. If this |
|
296 |
* Spliterator is {@link #ORDERED} the action is performed on the |
|
297 |
* next element in encounter order. Exceptions thrown by the |
|
298 |
* action are relayed to the caller. |
|
299 |
* |
|
300 |
* @param action The action |
|
301 |
* @return {@code false} if no remaining elements existed |
|
302 |
* upon entry to this method, else {@code true}. |
|
303 |
* @throws NullPointerException if the specified action is null |
|
304 |
*/ |
|
305 |
boolean tryAdvance(Consumer<? super T> action); |
|
306 |
||
307 |
/** |
|
308 |
* Performs the given action for each remaining element, sequentially in |
|
309 |
* the current thread, until all elements have been processed or the action |
|
310 |
* throws an exception. If this Spliterator is {@link #ORDERED}, actions |
|
311 |
* are performed in encounter order. Exceptions thrown by the action |
|
312 |
* are relayed to the caller. |
|
313 |
* |
|
314 |
* @implSpec |
|
315 |
* The default implementation repeatedly invokes {@link #tryAdvance} until |
|
316 |
* it returns {@code false}. It should be overridden whenever possible. |
|
317 |
* |
|
318 |
* @param action The action |
|
319 |
* @throws NullPointerException if the specified action is null |
|
320 |
*/ |
|
321 |
default void forEachRemaining(Consumer<? super T> action) { |
|
322 |
do { } while (tryAdvance(action)); |
|
323 |
} |
|
324 |
||
325 |
/** |
|
326 |
* If this spliterator can be partitioned, returns a Spliterator |
|
327 |
* covering elements, that will, upon return from this method, not |
|
328 |
* be covered by this Spliterator. |
|
329 |
* |
|
330 |
* <p>If this Spliterator is {@link #ORDERED}, the returned Spliterator |
|
331 |
* must cover a strict prefix of the elements. |
|
332 |
* |
|
333 |
* <p>Unless this Spliterator covers an infinite number of elements, |
|
334 |
* repeated calls to {@code trySplit()} must eventually return {@code null}. |
|
335 |
* Upon non-null return: |
|
336 |
* <ul> |
|
337 |
* <li>the value reported for {@code estimateSize()} before splitting, |
|
17693
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
338 |
* must, after splitting, be greater than or equal to {@code estimateSize()} |
2d7cbdb1bb53
8013334: Spliterator behavior for LinkedList contradicts Spliterator.trySplit
psandoz
parents:
17190
diff
changeset
|
339 |
* for this and the returned Spliterator; and</li> |
16929 | 340 |
* <li>if this Spliterator is {@code SUBSIZED}, then {@code estimateSize()} |
341 |
* for this spliterator before splitting must be equal to the sum of |
|
342 |
* {@code estimateSize()} for this and the returned Spliterator after |
|
343 |
* splitting.</li> |
|
344 |
* </ul> |
|
345 |
* |
|
346 |
* <p>This method may return {@code null} for any reason, |
|
347 |
* including emptiness, inability to split after traversal has |
|
348 |
* commenced, data structure constraints, and efficiency |
|
349 |
* considerations. |
|
350 |
* |
|
351 |
* @apiNote |
|
352 |
* An ideal {@code trySplit} method efficiently (without |
|
353 |
* traversal) divides its elements exactly in half, allowing |
|
354 |
* balanced parallel computation. Many departures from this ideal |
|
355 |
* remain highly effective; for example, only approximately |
|
356 |
* splitting an approximately balanced tree, or for a tree in |
|
357 |
* which leaf nodes may contain either one or two elements, |
|
358 |
* failing to further split these nodes. However, large |
|
359 |
* deviations in balance and/or overly inefficient {@code |
|
360 |
* trySplit} mechanics typically result in poor parallel |
|
361 |
* performance. |
|
362 |
* |
|
363 |
* @return a {@code Spliterator} covering some portion of the |
|
364 |
* elements, or {@code null} if this spliterator cannot be split |
|
365 |
*/ |
|
366 |
Spliterator<T> trySplit(); |
|
367 |
||
368 |
/** |
|
369 |
* Returns an estimate of the number of elements that would be |
|
370 |
* encountered by a {@link #forEachRemaining} traversal, or returns {@link |
|
371 |
* Long#MAX_VALUE} if infinite, unknown, or too expensive to compute. |
|
372 |
* |
|
373 |
* <p>If this Spliterator is {@link #SIZED} and has not yet been partially |
|
374 |
* traversed or split, or this Spliterator is {@link #SUBSIZED} and has |
|
375 |
* not yet been partially traversed, this estimate must be an accurate |
|
376 |
* count of elements that would be encountered by a complete traversal. |
|
377 |
* Otherwise, this estimate may be arbitrarily inaccurate, but must decrease |
|
378 |
* as specified across invocations of {@link #trySplit}. |
|
379 |
* |
|
380 |
* @apiNote |
|
381 |
* Even an inexact estimate is often useful and inexpensive to compute. |
|
382 |
* For example, a sub-spliterator of an approximately balanced binary tree |
|
383 |
* may return a value that estimates the number of elements to be half of |
|
384 |
* that of its parent; if the root Spliterator does not maintain an |
|
385 |
* accurate count, it could estimate size to be the power of two |
|
386 |
* corresponding to its maximum depth. |
|
387 |
* |
|
388 |
* @return the estimated size, or {@code Long.MAX_VALUE} if infinite, |
|
389 |
* unknown, or too expensive to compute. |
|
390 |
*/ |
|
391 |
long estimateSize(); |
|
392 |
||
393 |
/** |
|
394 |
* Convenience method that returns {@link #estimateSize()} if this |
|
395 |
* Spliterator is {@link #SIZED}, else {@code -1}. |
|
396 |
* @implSpec |
|
17920
eef25bc37ccd
8014732: Minor spec issue: java.util.Spliterator.getExactSizeIfKnown
psandoz
parents:
17694
diff
changeset
|
397 |
* The default implementation returns the result of {@code estimateSize()} |
eef25bc37ccd
8014732: Minor spec issue: java.util.Spliterator.getExactSizeIfKnown
psandoz
parents:
17694
diff
changeset
|
398 |
* if the Spliterator reports a characteristic of {@code SIZED}, and |
eef25bc37ccd
8014732: Minor spec issue: java.util.Spliterator.getExactSizeIfKnown
psandoz
parents:
17694
diff
changeset
|
399 |
* {@code -1} otherwise. |
16929 | 400 |
* |
401 |
* @return the exact size, if known, else {@code -1}. |
|
402 |
*/ |
|
403 |
default long getExactSizeIfKnown() { |
|
404 |
return (characteristics() & SIZED) == 0 ? -1L : estimateSize(); |
|
405 |
} |
|
406 |
||
407 |
/** |
|
408 |
* Returns a set of characteristics of this Spliterator and its |
|
409 |
* elements. The result is represented as ORed values from {@link |
|
410 |
* #ORDERED}, {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED}, |
|
411 |
* {@link #NONNULL}, {@link #IMMUTABLE}, {@link #CONCURRENT}, |
|
412 |
* {@link #SUBSIZED}. Repeated calls to {@code characteristics()} on |
|
413 |
* a given spliterator should always return the same result. |
|
414 |
* |
|
415 |
* <p>If a Spliterator reports an inconsistent set of |
|
416 |
* characteristics (either those returned from a single invocation |
|
417 |
* or across multiple invocations), no guarantees can be made |
|
418 |
* about any computation using this Spliterator. |
|
419 |
* |
|
420 |
* @return a representation of characteristics |
|
421 |
*/ |
|
422 |
int characteristics(); |
|
423 |
||
424 |
/** |
|
425 |
* Returns {@code true} if this Spliterator's {@link |
|
426 |
* #characteristics} contain all of the given characteristics. |
|
427 |
* |
|
428 |
* @implSpec |
|
429 |
* The default implementation returns true if the corresponding bits |
|
430 |
* of the given characteristics are set. |
|
431 |
* |
|
18796
486b43748d9b
8020294: Fix doclint issues in java.util.Spliterator
darcy
parents:
17920
diff
changeset
|
432 |
* @param characteristics the characteristics to check for |
16929 | 433 |
* @return {@code true} if all the specified characteristics are present, |
434 |
* else {@code false} |
|
435 |
*/ |
|
436 |
default boolean hasCharacteristics(int characteristics) { |
|
437 |
return (characteristics() & characteristics) == characteristics; |
|
438 |
} |
|
439 |
||
440 |
/** |
|
441 |
* If this Spliterator's source is {@link #SORTED} by a {@link Comparator}, |
|
442 |
* returns that {@code Comparator}. If the source is {@code SORTED} in |
|
17190 | 443 |
* {@linkplain Comparable natural order}, returns {@code null}. Otherwise, |
16929 | 444 |
* if the source is not {@code SORTED}, throws {@link IllegalStateException}. |
445 |
* |
|
446 |
* @implSpec |
|
447 |
* The default implementation always throws {@link IllegalStateException}. |
|
448 |
* |
|
449 |
* @return a Comparator, or {@code null} if the elements are sorted in the |
|
450 |
* natural order. |
|
451 |
* @throws IllegalStateException if the spliterator does not report |
|
452 |
* a characteristic of {@code SORTED}. |
|
453 |
*/ |
|
454 |
default Comparator<? super T> getComparator() { |
|
455 |
throw new IllegalStateException(); |
|
456 |
} |
|
457 |
||
458 |
/** |
|
459 |
* Characteristic value signifying that an encounter order is defined for |
|
460 |
* elements. If so, this Spliterator guarantees that method |
|
461 |
* {@link #trySplit} splits a strict prefix of elements, that method |
|
462 |
* {@link #tryAdvance} steps by one element in prefix order, and that |
|
463 |
* {@link #forEachRemaining} performs actions in encounter order. |
|
464 |
* |
|
465 |
* <p>A {@link Collection} has an encounter order if the corresponding |
|
466 |
* {@link Collection#iterator} documents an order. If so, the encounter |
|
467 |
* order is the same as the documented order. Otherwise, a collection does |
|
468 |
* not have an encounter order. |
|
469 |
* |
|
470 |
* @apiNote Encounter order is guaranteed to be ascending index order for |
|
471 |
* any {@link List}. But no order is guaranteed for hash-based collections |
|
472 |
* such as {@link HashSet}. Clients of a Spliterator that reports |
|
473 |
* {@code ORDERED} are expected to preserve ordering constraints in |
|
474 |
* non-commutative parallel computations. |
|
475 |
*/ |
|
476 |
public static final int ORDERED = 0x00000010; |
|
477 |
||
478 |
/** |
|
479 |
* Characteristic value signifying that, for each pair of |
|
480 |
* encountered elements {@code x, y}, {@code !x.equals(y)}. This |
|
481 |
* applies for example, to a Spliterator based on a {@link Set}. |
|
482 |
*/ |
|
483 |
public static final int DISTINCT = 0x00000001; |
|
484 |
||
485 |
/** |
|
486 |
* Characteristic value signifying that encounter order follows a defined |
|
487 |
* sort order. If so, method {@link #getComparator()} returns the associated |
|
488 |
* Comparator, or {@code null} if all elements are {@link Comparable} and |
|
489 |
* are sorted by their natural ordering. |
|
490 |
* |
|
491 |
* <p>A Spliterator that reports {@code SORTED} must also report |
|
492 |
* {@code ORDERED}. |
|
493 |
* |
|
494 |
* @apiNote The spliterators for {@code Collection} classes in the JDK that |
|
495 |
* implement {@link NavigableSet} or {@link SortedSet} report {@code SORTED}. |
|
496 |
*/ |
|
497 |
public static final int SORTED = 0x00000004; |
|
498 |
||
499 |
/** |
|
500 |
* Characteristic value signifying that the value returned from |
|
501 |
* {@code estimateSize()} prior to traversal or splitting represents a |
|
502 |
* finite size that, in the absence of structural source modification, |
|
503 |
* represents an exact count of the number of elements that would be |
|
504 |
* encountered by a complete traversal. |
|
505 |
* |
|
506 |
* @apiNote Most Spliterators for Collections, that cover all elements of a |
|
507 |
* {@code Collection} report this characteristic. Sub-spliterators, such as |
|
508 |
* those for {@link HashSet}, that cover a sub-set of elements and |
|
509 |
* approximate their reported size do not. |
|
510 |
*/ |
|
511 |
public static final int SIZED = 0x00000040; |
|
512 |
||
513 |
/** |
|
514 |
* Characteristic value signifying that the source guarantees that |
|
515 |
* encountered elements will not be {@code null}. (This applies, |
|
516 |
* for example, to most concurrent collections, queues, and maps.) |
|
517 |
*/ |
|
518 |
public static final int NONNULL = 0x00000100; |
|
519 |
||
520 |
/** |
|
521 |
* Characteristic value signifying that the element source cannot be |
|
522 |
* structurally modified; that is, elements cannot be added, replaced, or |
|
523 |
* removed, so such changes cannot occur during traversal. A Spliterator |
|
524 |
* that does not report {@code IMMUTABLE} or {@code CONCURRENT} is expected |
|
525 |
* to have a documented policy (for example throwing |
|
526 |
* {@link ConcurrentModificationException}) concerning structural |
|
527 |
* interference detected during traversal. |
|
528 |
*/ |
|
529 |
public static final int IMMUTABLE = 0x00000400; |
|
530 |
||
531 |
/** |
|
532 |
* Characteristic value signifying that the element source may be safely |
|
533 |
* concurrently modified (allowing additions, replacements, and/or removals) |
|
534 |
* by multiple threads without external synchronization. If so, the |
|
535 |
* Spliterator is expected to have a documented policy concerning the impact |
|
536 |
* of modifications during traversal. |
|
537 |
* |
|
538 |
* <p>A top-level Spliterator should not report {@code CONCURRENT} and |
|
539 |
* {@code SIZED}, since the finite size, if known, may change if the source |
|
540 |
* is concurrently modified during traversal. Such a Spliterator is |
|
541 |
* inconsistent and no guarantees can be made about any computation using |
|
542 |
* that Spliterator. Sub-spliterators may report {@code SIZED} if the |
|
543 |
* sub-split size is known and additions or removals to the source are not |
|
544 |
* reflected when traversing. |
|
545 |
* |
|
546 |
* @apiNote Most concurrent collections maintain a consistency policy |
|
547 |
* guaranteeing accuracy with respect to elements present at the point of |
|
548 |
* Spliterator construction, but possibly not reflecting subsequent |
|
549 |
* additions or removals. |
|
550 |
*/ |
|
551 |
public static final int CONCURRENT = 0x00001000; |
|
552 |
||
553 |
/** |
|
554 |
* Characteristic value signifying that all Spliterators resulting from |
|
555 |
* {@code trySplit()} will be both {@link #SIZED} and {@link #SUBSIZED}. |
|
556 |
* (This means that all child Spliterators, whether direct or indirect, will |
|
557 |
* be {@code SIZED}.) |
|
558 |
* |
|
559 |
* <p>A Spliterator that does not report {@code SIZED} as required by |
|
560 |
* {@code SUBSIZED} is inconsistent and no guarantees can be made about any |
|
561 |
* computation using that Spliterator. |
|
562 |
* |
|
563 |
* @apiNote Some spliterators, such as the top-level spliterator for an |
|
564 |
* approximately balanced binary tree, will report {@code SIZED} but not |
|
565 |
* {@code SUBSIZED}, since it is common to know the size of the entire tree |
|
566 |
* but not the exact sizes of subtrees. |
|
567 |
*/ |
|
568 |
public static final int SUBSIZED = 0x00004000; |
|
569 |
||
570 |
/** |
|
17694 | 571 |
* A Spliterator specialized for primitive values. |
572 |
* |
|
573 |
* @param <T> the type of elements returned by this Spliterator. The |
|
574 |
* type must be a wrapper type for a primitive type, such as {@code Integer} |
|
575 |
* for the primitive {@code int} type. |
|
576 |
* @param <T_CONS> the type of primitive consumer. The type must be a |
|
577 |
* primitive specialization of {@link java.util.function.Consumer} for |
|
578 |
* {@code T}, such as {@link java.util.function.IntConsumer} for |
|
579 |
* {@code Integer}. |
|
580 |
* @param <T_SPLITR> the type of primitive Spliterator. The type must be |
|
581 |
* a primitive specialization of Spliterator for {@code T}, such as |
|
582 |
* {@link Spliterator.OfInt} for {@code Integer}. |
|
583 |
* |
|
584 |
* @see Spliterator.OfInt |
|
585 |
* @see Spliterator.OfLong |
|
586 |
* @see Spliterator.OfDouble |
|
16929 | 587 |
* @since 1.8 |
588 |
*/ |
|
17694 | 589 |
public interface OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>> |
590 |
extends Spliterator<T> { |
|
16929 | 591 |
@Override |
17694 | 592 |
T_SPLITR trySplit(); |
16929 | 593 |
|
594 |
/** |
|
595 |
* If a remaining element exists, performs the given action on it, |
|
596 |
* returning {@code true}; else returns {@code false}. If this |
|
597 |
* Spliterator is {@link #ORDERED} the action is performed on the |
|
598 |
* next element in encounter order. Exceptions thrown by the |
|
599 |
* action are relayed to the caller. |
|
600 |
* |
|
601 |
* @param action The action |
|
602 |
* @return {@code false} if no remaining elements existed |
|
603 |
* upon entry to this method, else {@code true}. |
|
604 |
* @throws NullPointerException if the specified action is null |
|
605 |
*/ |
|
17694 | 606 |
boolean tryAdvance(T_CONS action); |
16929 | 607 |
|
608 |
/** |
|
609 |
* Performs the given action for each remaining element, sequentially in |
|
610 |
* the current thread, until all elements have been processed or the |
|
611 |
* action throws an exception. If this Spliterator is {@link #ORDERED}, |
|
612 |
* actions are performed in encounter order. Exceptions thrown by the |
|
613 |
* action are relayed to the caller. |
|
614 |
* |
|
615 |
* @implSpec |
|
616 |
* The default implementation repeatedly invokes {@link #tryAdvance} |
|
617 |
* until it returns {@code false}. It should be overridden whenever |
|
618 |
* possible. |
|
619 |
* |
|
620 |
* @param action The action |
|
621 |
* @throws NullPointerException if the specified action is null |
|
622 |
*/ |
|
17694 | 623 |
default void forEachRemaining(T_CONS action) { |
624 |
do { } while (tryAdvance(action)); |
|
625 |
} |
|
626 |
} |
|
627 |
||
628 |
/** |
|
629 |
* A Spliterator specialized for {@code int} values. |
|
630 |
* @since 1.8 |
|
631 |
*/ |
|
632 |
public interface OfInt extends OfPrimitive<Integer, IntConsumer, OfInt> { |
|
633 |
||
634 |
@Override |
|
635 |
OfInt trySplit(); |
|
636 |
||
637 |
@Override |
|
638 |
boolean tryAdvance(IntConsumer action); |
|
639 |
||
640 |
@Override |
|
16929 | 641 |
default void forEachRemaining(IntConsumer action) { |
642 |
do { } while (tryAdvance(action)); |
|
643 |
} |
|
644 |
||
645 |
/** |
|
646 |
* {@inheritDoc} |
|
647 |
* @implSpec |
|
648 |
* If the action is an instance of {@code IntConsumer} then it is cast |
|
649 |
* to {@code IntConsumer} and passed to |
|
650 |
* {@link #tryAdvance(java.util.function.IntConsumer)}; otherwise |
|
651 |
* the action is adapted to an instance of {@code IntConsumer}, by |
|
652 |
* boxing the argument of {@code IntConsumer}, and then passed to |
|
653 |
* {@link #tryAdvance(java.util.function.IntConsumer)}. |
|
654 |
*/ |
|
655 |
@Override |
|
656 |
default boolean tryAdvance(Consumer<? super Integer> action) { |
|
657 |
if (action instanceof IntConsumer) { |
|
658 |
return tryAdvance((IntConsumer) action); |
|
659 |
} |
|
660 |
else { |
|
661 |
if (Tripwire.ENABLED) |
|
662 |
Tripwire.trip(getClass(), |
|
663 |
"{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)"); |
|
664 |
return tryAdvance((IntConsumer) action::accept); |
|
665 |
} |
|
666 |
} |
|
667 |
||
668 |
/** |
|
669 |
* {@inheritDoc} |
|
670 |
* @implSpec |
|
671 |
* If the action is an instance of {@code IntConsumer} then it is cast |
|
672 |
* to {@code IntConsumer} and passed to |
|
673 |
* {@link #forEachRemaining(java.util.function.IntConsumer)}; otherwise |
|
674 |
* the action is adapted to an instance of {@code IntConsumer}, by |
|
675 |
* boxing the argument of {@code IntConsumer}, and then passed to |
|
676 |
* {@link #forEachRemaining(java.util.function.IntConsumer)}. |
|
677 |
*/ |
|
678 |
@Override |
|
679 |
default void forEachRemaining(Consumer<? super Integer> action) { |
|
680 |
if (action instanceof IntConsumer) { |
|
681 |
forEachRemaining((IntConsumer) action); |
|
682 |
} |
|
683 |
else { |
|
684 |
if (Tripwire.ENABLED) |
|
685 |
Tripwire.trip(getClass(), |
|
686 |
"{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)"); |
|
687 |
forEachRemaining((IntConsumer) action::accept); |
|
688 |
} |
|
689 |
} |
|
690 |
} |
|
691 |
||
692 |
/** |
|
693 |
* A Spliterator specialized for {@code long} values. |
|
694 |
* @since 1.8 |
|
695 |
*/ |
|
17694 | 696 |
public interface OfLong extends OfPrimitive<Long, LongConsumer, OfLong> { |
16929 | 697 |
|
698 |
@Override |
|
699 |
OfLong trySplit(); |
|
700 |
||
17694 | 701 |
@Override |
16929 | 702 |
boolean tryAdvance(LongConsumer action); |
703 |
||
17694 | 704 |
@Override |
16929 | 705 |
default void forEachRemaining(LongConsumer action) { |
706 |
do { } while (tryAdvance(action)); |
|
707 |
} |
|
708 |
||
709 |
/** |
|
710 |
* {@inheritDoc} |
|
711 |
* @implSpec |
|
712 |
* If the action is an instance of {@code LongConsumer} then it is cast |
|
713 |
* to {@code LongConsumer} and passed to |
|
714 |
* {@link #tryAdvance(java.util.function.LongConsumer)}; otherwise |
|
715 |
* the action is adapted to an instance of {@code LongConsumer}, by |
|
716 |
* boxing the argument of {@code LongConsumer}, and then passed to |
|
717 |
* {@link #tryAdvance(java.util.function.LongConsumer)}. |
|
718 |
*/ |
|
719 |
@Override |
|
720 |
default boolean tryAdvance(Consumer<? super Long> action) { |
|
721 |
if (action instanceof LongConsumer) { |
|
722 |
return tryAdvance((LongConsumer) action); |
|
723 |
} |
|
724 |
else { |
|
725 |
if (Tripwire.ENABLED) |
|
726 |
Tripwire.trip(getClass(), |
|
727 |
"{0} calling Spliterator.OfLong.tryAdvance((LongConsumer) action::accept)"); |
|
728 |
return tryAdvance((LongConsumer) action::accept); |
|
729 |
} |
|
730 |
} |
|
731 |
||
732 |
/** |
|
733 |
* {@inheritDoc} |
|
734 |
* @implSpec |
|
735 |
* If the action is an instance of {@code LongConsumer} then it is cast |
|
736 |
* to {@code LongConsumer} and passed to |
|
737 |
* {@link #forEachRemaining(java.util.function.LongConsumer)}; otherwise |
|
738 |
* the action is adapted to an instance of {@code LongConsumer}, by |
|
739 |
* boxing the argument of {@code LongConsumer}, and then passed to |
|
740 |
* {@link #forEachRemaining(java.util.function.LongConsumer)}. |
|
741 |
*/ |
|
742 |
@Override |
|
743 |
default void forEachRemaining(Consumer<? super Long> action) { |
|
744 |
if (action instanceof LongConsumer) { |
|
745 |
forEachRemaining((LongConsumer) action); |
|
746 |
} |
|
747 |
else { |
|
748 |
if (Tripwire.ENABLED) |
|
749 |
Tripwire.trip(getClass(), |
|
750 |
"{0} calling Spliterator.OfLong.forEachRemaining((LongConsumer) action::accept)"); |
|
751 |
forEachRemaining((LongConsumer) action::accept); |
|
752 |
} |
|
753 |
} |
|
754 |
} |
|
755 |
||
756 |
/** |
|
757 |
* A Spliterator specialized for {@code double} values. |
|
758 |
* @since 1.8 |
|
759 |
*/ |
|
17694 | 760 |
public interface OfDouble extends OfPrimitive<Double, DoubleConsumer, OfDouble> { |
16929 | 761 |
|
762 |
@Override |
|
763 |
OfDouble trySplit(); |
|
764 |
||
17694 | 765 |
@Override |
16929 | 766 |
boolean tryAdvance(DoubleConsumer action); |
767 |
||
17694 | 768 |
@Override |
16929 | 769 |
default void forEachRemaining(DoubleConsumer action) { |
770 |
do { } while (tryAdvance(action)); |
|
771 |
} |
|
772 |
||
773 |
/** |
|
774 |
* {@inheritDoc} |
|
775 |
* @implSpec |
|
776 |
* If the action is an instance of {@code DoubleConsumer} then it is |
|
777 |
* cast to {@code DoubleConsumer} and passed to |
|
778 |
* {@link #tryAdvance(java.util.function.DoubleConsumer)}; otherwise |
|
779 |
* the action is adapted to an instance of {@code DoubleConsumer}, by |
|
780 |
* boxing the argument of {@code DoubleConsumer}, and then passed to |
|
781 |
* {@link #tryAdvance(java.util.function.DoubleConsumer)}. |
|
782 |
*/ |
|
783 |
@Override |
|
784 |
default boolean tryAdvance(Consumer<? super Double> action) { |
|
785 |
if (action instanceof DoubleConsumer) { |
|
786 |
return tryAdvance((DoubleConsumer) action); |
|
787 |
} |
|
788 |
else { |
|
789 |
if (Tripwire.ENABLED) |
|
790 |
Tripwire.trip(getClass(), |
|
791 |
"{0} calling Spliterator.OfDouble.tryAdvance((DoubleConsumer) action::accept)"); |
|
792 |
return tryAdvance((DoubleConsumer) action::accept); |
|
793 |
} |
|
794 |
} |
|
795 |
||
796 |
/** |
|
797 |
* {@inheritDoc} |
|
798 |
* @implSpec |
|
799 |
* If the action is an instance of {@code DoubleConsumer} then it is |
|
800 |
* cast to {@code DoubleConsumer} and passed to |
|
801 |
* {@link #forEachRemaining(java.util.function.DoubleConsumer)}; |
|
802 |
* otherwise the action is adapted to an instance of |
|
803 |
* {@code DoubleConsumer}, by boxing the argument of |
|
804 |
* {@code DoubleConsumer}, and then passed to |
|
805 |
* {@link #forEachRemaining(java.util.function.DoubleConsumer)}. |
|
806 |
*/ |
|
807 |
@Override |
|
808 |
default void forEachRemaining(Consumer<? super Double> action) { |
|
809 |
if (action instanceof DoubleConsumer) { |
|
810 |
forEachRemaining((DoubleConsumer) action); |
|
811 |
} |
|
812 |
else { |
|
813 |
if (Tripwire.ENABLED) |
|
814 |
Tripwire.trip(getClass(), |
|
815 |
"{0} calling Spliterator.OfDouble.forEachRemaining((DoubleConsumer) action::accept)"); |
|
816 |
forEachRemaining((DoubleConsumer) action::accept); |
|
817 |
} |
|
818 |
} |
|
819 |
} |
|
820 |
} |