T
--元素类型返回此spliterator
public interface Spliterator<T>
Collection
,IO通道,或一个函数发生器。
一个spliterator可以遍历元素单独(tryAdvance()
)或按体积(forEachRemaining()
)。
一个spliterator也隔断了它的一些元素(使用trySplit()
)作为另一个spliterator,用于可能的并行操作。使用spliterator不能分割操作,或是以一种极不平衡的或低效的方式,是不太可能受益于并行。遍历和分裂排气元件;每个spliterator是有用的单体计算。
一个spliterator还报告了一组的结构,characteristics()
源,并从中ORDERED
,DISTINCT
,SORTED
,SIZED
,NONNULL
,IMMUTABLE
,CONCURRENT
元素,和SUBSIZED
。这些可以被用来控制spliterator客户,专门或简化计算。例如,一个Collection
spliterator SIZED
会报告,一个Set
spliterator会报告DISTINCT
,和一个SortedSet
spliterator也报告SORTED
。特点是报告为一个简单的结合点集。另外一些特征约束法的行为;例如,如果ORDERED
,遍历方法必须符合他们的记录排序。新特性可以定义在未来,所以用户不应分配的含义未列出的值。
A Spliterator that does not report IMMUTABLE
or CONCURRENT
is expected to have a documented policy concerning: when the spliterator binds to the element source; and detection of structural interference of the element source detected after binding.后期绑定spliterator结合在第一次遍历,点源元素第一次分裂,或先查询估计的大小,而不是在时间的spliterator创建。一个spliterator不是后期绑定的结合在施工或任何方法首先调用点元素的来源。修改后的源代码之前,结合反映当spliterator遍历。结合spliterator应后,在尽最大努力的基础上的,如果结构检测干扰,把ConcurrentModificationException
。spliterators,我们称之为快速失败。大部分的遍历方法(forEachRemaining()
)一spliterator可以优化结构干扰遍历和检查后的所有元素都被遍历,而不是检查每个元素和未立即。
spliterators可以提供估计的剩余数量的元素通过estimateSize()
方法。理想的情况是,所反映的特征SIZED
,这个值是完全对应的元素,将在一个成功的穿越中遇到的数。然而,即使不完全知道,估计的值可能仍然是有用的,在源上执行的操作,如帮助,以确定是否最好是进一步分裂或遍历剩余的元素。
尽管他们在并行算法明显的效用,spliterators预计不会是线程安全的;相反,实现并行算法的spliterators应确保spliterator是唯一使用的一个线程在一个时间。这通常是容易实现通过串行线程限制,这往往是一个自然的后果,典型的并行算法,通过递归分解的工作。一个线程可以调用trySplit()
交回到spliterator到另一个线程,从而可以遍历或进一步分裂,Spliterator。如果两个或多个线程同时运行在同一spliterator分裂和遍历的行为是未定义的。如果原始线程手中的spliterator去处理另一个线程,最好是如果切换发生在任何元素被tryAdvance()
,一定保证(如SIZED
spliterators的estimateSize()
精度)是唯一有效的遍历前已经开始。
原始型专业Spliterator
提供int
,long
,和double
值。亚型的默认实现的tryAdvance(java.util.function.Consumer)
和forEachRemaining(java.util.function.Consumer)
箱原始值及其对应的包装类的实例。这样的拳击可以破坏任何性能上的优势,利用原始的专业了。为了避免拳击,应使用相应的基于原始的方法。例如,Spliterator.OfInt.tryAdvance(java.util.function.IntConsumer)
和Spliterator.OfInt.forEachRemaining(java.util.function.IntConsumer)
应优先用于Spliterator.OfInt.tryAdvance(java.util.function.Consumer)
和Spliterator.OfInt.forEachRemaining(java.util.function.Consumer)
。用拳击方法tryAdvance()
和forEachRemaining()
并不影响该值的顺序遍历原始值,转换为装箱的值,遇到。
spliterators,像Iterators
s,是穿越一个源元素。的Spliterator
API被设计为支持除顺序遍历高效并行遍历,通过支持分解以及单元迭代。此外,通过spliterator访问元素的协议是为了征收每元的开销比Iterator
更小,并避免参与有hasNext()
和next()
固有的种族分离的方法。
易变的来源,如果来源是任意的和非结构的干扰可能发生确定性行为(元素的添加、更换,或删除)之间的时间,spliterator绑定到数据源和遍历结束。例如,这种干扰会产生任意的,非确定性的结果时java.util.stream
框架。
一个源的结构干扰可以以以下方式进行管理(以减少可取性的近似顺序):
CopyOnWriteArrayList
源。一个spliterator创建源报道IMMUTABLE
特征。ConcurrentHashMap
键是一个同步源。一个spliterator创建源报道CONCURRENT
特征。ConcurrentModificationException
遍历结构干扰。例如,ArrayList
,和许多其他非并发Collection
班在JDK,提供后期绑定,快速失败spliterator。ConcurrentModificationException
由于潜在干扰窗口的可能性大。例子.这里是一类(不是很有用,除了插图),维持一个数组中的实际数据,甚至在地方举办,和无关的标签数据是奇怪的地点举行。其spliterator忽略标签。
class TaggedArray<T> {
private final Object[] elements; // immutable after construction
TaggedArray(T[] data, Object[] tags) {
int size = data.length;
if (tags.length != size) throw new IllegalArgumentException();
this.elements = new Object[2 * size];
for (int i = 0, j = 0; i < size; ++i) {
elements[j++] = data[i];
elements[j++] = tags[i];
}
}
public Spliterator<T> spliterator() {
return new TaggedArraySpliterator<>(elements, 0, elements.length);
}
static class TaggedArraySpliterator<T> implements Spliterator<T> {
private final Object[] array;
private int origin; // current index, advanced on split or traversal
private final int fence; // one past the greatest index
TaggedArraySpliterator(Object[] array, int origin, int fence) {
this.array = array; this.origin = origin; this.fence = fence;
}
public void forEachRemaining(Consumer<? super T> action) {
for (; origin < fence; origin += 2)
action.accept((T) array[origin]);
}
public boolean tryAdvance(Consumer<? super T> action) {
if (origin < fence) {
action.accept((T) array[origin]);
origin += 2;
return true;
}
else // cannot advance
return false;
}
public Spliterator<T> trySplit() {
int lo = origin; // divide range in half
int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even
if (lo < mid) { // split out left half
origin = mid; // reset this Spliterator's origin
return new TaggedArraySpliterator<>(array, lo, mid);
}
else // too small to split
return null;
}
public long estimateSize() {
return (long)((fence - origin) / 2);
}
public int characteristics() {
return ORDERED | SIZED | IMMUTABLE | SUBSIZED;
}
}
}
作为一个例子,一个并行计算框架,如java.util.stream
包,会在一个并行计算使用spliterator,这里是实现相关平行foreach方法之一,表明分拆任务主要使用成语直到工作估计量是足够小的执行顺序。在这里,我们假设在任务处理顺序无关紧要;不同(叉)的任务可能会进一步分化,同时在待定订单流程元素。这个例子使用一个CountedCompleter
;类似的用法适用于其他并行任务结构。
static <T> void parEach(TaggedArray<T> a, Consumer<T> action) {
Spliterator<T> s = a.spliterator();
long targetBatchSize = s.estimateSize() / (ForkJoinPool.getCommonPoolParallelism() * 8);
new ParEach(null, s, action, targetBatchSize).invoke();
}
static class ParEach<T> extends CountedCompleter<Void> {
final Spliterator<T> spliterator;
final Consumer<T> action;
final long targetBatchSize;
ParEach(ParEach<T> parent, Spliterator<T> spliterator,
Consumer<T> action, long targetBatchSize) {
super(parent);
this.spliterator = spliterator; this.action = action;
this.targetBatchSize = targetBatchSize;
}
public void compute() {
Spliterator<T> sub;
while (spliterator.estimateSize() > targetBatchSize &&
(sub = spliterator.trySplit()) != null) {
addToPendingCount(1);
new ParEach<>(this, sub, action, targetBatchSize).fork();
}
spliterator.forEachRemaining(action);
propagateCompletion();
}
}
org.openjdk.java.util.stream.tripwire
设置
true
然后诊断警告报告如果原始值时发生的操作对原始型拳击专业。
Collection
Modifier and Type | Interface and Description |
---|---|
static interface |
Spliterator.OfDouble
一个spliterator专门为
double 值。
|
static interface |
Spliterator.OfInt
一个spliterator专门为
int 值。
|
static interface |
Spliterator.OfLong
一个spliterator专门为
long 值。
|
static interface |
Spliterator.OfPrimitive<T,T_CONS,T_SPLITR extends Spliterator.OfPrimitive<T,T_CONS,T_SPLITR>>
一个spliterator专门为原始值。
|
Modifier and Type | Field and Description |
---|---|
static int |
CONCURRENT
特征值表示元素源可以安全地同时修改(允许添加、替换和/或清除)由多个线程不同步。
|
static int |
DISTINCT
特征值表示,每对遇到的元素
x, y ,
!x.equals(y) 。
|
static int |
IMMUTABLE
特征值表示元素源不能结构改性;即不能将元素添加、更换,或删除,这样的改变不会发生在遍历。
|
static int |
NONNULL
特征值表示,遇到元素不会
null 源保证。
|
static int |
ORDERED
特征值表示一遇到命令定义的元素。
|
static int |
SIZED
特征值表示返回的值
estimateSize() 遍历或分裂之前是一个有限大小的,在结构修改源的情况下,代表元素,将由一个完全遍历遇到数的精确计算。
|
static int |
SORTED
特征值表示遇到如下定义的排序顺序。
|
static int |
SUBSIZED
|
Modifier and Type | Method and Description |
---|---|
int |
characteristics()
返回一组这spliterator及其元素的特征。
|
long |
estimateSize()
返回的元素,将由一个
forEachRemaining(java.util.function.Consumer<? super T>) 遍历遇到的估计值,或者返回
Long.MAX_VALUE 如果无限的,未知的,或过于昂贵的计算。
|
default void |
forEachRemaining(Consumer<? super T> action)
对每个剩余元素执行给定的操作,在当前线程中顺序执行,直到所有的元素都被处理或操作抛出异常。
|
default Comparator<? super T> |
getComparator()
|
default long |
getExactSizeIfKnown()
|
default boolean |
hasCharacteristics(int characteristics)
返回
true 如果这Spliterator的
characteristics() 包含所有给定的特性。
|
boolean |
tryAdvance(Consumer<? super T> action)
如果剩余的元素存在,执行特定动作的话,还
true ;否则返回
false 。
|
Spliterator<T> |
trySplit()
如果这spliterator可以分割,返回一个spliterator覆盖的元素,将这一方法,在回归,不是这个spliterator覆盖。
|
static final int ORDERED
trySplit()
将严格前缀的元素,这种方法
tryAdvance(java.util.function.Consumer<? super T>)
步骤由一个元素在前缀的秩序,这
forEachRemaining(java.util.function.Consumer<? super T>)
执行命令的行动遭遇。
一个Collection
遇到了一个订单如果对应的Collection.iterator()
文件命令。如果是这样的话,遇到的顺序是相同的记录的顺序。否则,集合没有遇到顺序。
List
索引顺序。但没有秩序是保证基于散列的集合如
HashSet
。一个spliterator报告
ORDERED
将保存在非交换的并行计算排序约束客户。
static final int DISTINCT
static final int SORTED
getComparator()
返回相关的比较,或
null
如果所有的元素都是
Comparable
和由他们的自然顺序排序。
一个spliterator报告SORTED
也必须报告ORDERED
。
Collection
班在JDK实现
NavigableSet
或
SortedSet
报告
SORTED
。
static final int SIZED
estimateSize()
遍历或分裂之前是一个有限大小的,在结构修改源的情况下,代表元素,将由一个完全遍历遇到数的精确计算。
Collection
报告这一特点。子spliterators,比如
HashSet
,盖的一个子集的元素和近似的报道规模不。
static final int NONNULL
null
源保证。(这适用于,例如,大多数并发集合,队列,和Map。)
static final int IMMUTABLE
IMMUTABLE
或
CONCURRENT
预计将有一个文件化的政策(例如投掷
ConcurrentModificationException
)关于遍历期间结构干涉检测。
static final int CONCURRENT
一个顶级的spliterator不应该报告CONCURRENT
和SIZED
,由于有限的大小,如果知道的话,可如果是在遍历的同时修改变化。这样的spliterator是不一致的,无法保证任何计算,spliterator。子spliterators可能如果分裂的大小是已知的,添加或移除的来源不是体现在穿越报告SIZED
。
static final int SUBSIZED
trySplit()
所有spliterators将
SIZED
和
SUBSIZED
。(这意味着所有的孩子spliterators,无论是直接的还是间接的,都会
SIZED
一个spliterator不报告SIZED
SUBSIZED
要求不一致,无法保证任何计算,spliterator。
SIZED
但不
SUBSIZED
,由于一般都知道整个树的子树的大小而不是确切的大小。
boolean tryAdvance(Consumer<? super T> action)
action
-行动
false
如果没有剩余的元素存在在进入这个方法,其他
true
。
NullPointerException
-如果指定动作是无效的
default void forEachRemaining(Consumer<? super T> action)
ORDERED
,行动中遇到的顺序进行。由操作引发的异常被传递给调用方。
tryAdvance(java.util.function.Consumer<? super T>)
反复调用返回之前
false
。它应该被尽可能的。
action
-行动
NullPointerException
-如果指定动作是无效的
Spliterator<T> trySplit()
如果这spliterator是ORDERED
,返回的spliterator必须盖严前缀的元素。
除非这spliterator涵盖无限数量的元素,重复调用trySplit()
最终要回归null
。非零返回:
estimateSize()
分裂之前,必须经过分裂,可大于或等于estimateSize()
这和返回的spliterator;和SUBSIZED
,然后estimateSize()
这spliterator分裂之前必须经过分裂等于这和返回的spliterator estimateSize()
总和。这种方法可能会返回null
以任何理由,包括空虚,无力分裂后遍历开始,数据结构约束和效率方面的考虑。
trySplit
方法有效(不完全遍历)分一半的元素,允许平衡的并行计算。许多偏离这个理想仍然是非常有效的,例如,只有约分裂一个约平衡的树,或一棵树,叶节点可能包含一个或两个元素,未能进一步分裂这些节点。然而,在平衡和/或过于低效
trySplit
力学通常导致并行性能差的大偏差。
Spliterator
覆盖部分的元素,或
null
如果这spliterator无法拆分
long estimateSize()
forEachRemaining(java.util.function.Consumer<? super T>)
遍历遇到的估计值,或者返回
Long.MAX_VALUE
如果无限的,未知的,或过于昂贵的计算。
如果这spliterator是SIZED
尚未部分遍历或分裂,或这spliterator是SUBSIZED
尚未部分走过,这个估计必须的元素,将由一个完全遍历遇到一个准确的计数。否则,这个估计可能是任意的不准确,但必须指定在调用trySplit()
减少。
Long.MAX_VALUE
如果无限的,未知的,或过于昂贵的计算。
default long getExactSizeIfKnown()
SIZED
特有的默认实现将返回
estimateSize()
的结果,和
-1
否则。
-1
。
int characteristics()
ORDERED
,
DISTINCT
,
SORTED
,
SIZED
,
NONNULL
,
IMMUTABLE
,
CONCURRENT
,
SUBSIZED
。
characteristics()
一再呼吁在一个给定的spliterator,之前或在电话
trySplit
之间,应始终返回相同的结果。
如果一个spliterator报道特点一致(或从一个单一的调用或跨多个调用返回),无法保证任何计算这spliterator。
SIZED
,
SUBSIZED
和
CONCURRENT
。
default boolean hasCharacteristics(int characteristics)
true
如果这Spliterator的
characteristics()
包含所有给定的特性。
characteristics
-检查的特点
true
如果所有指定的特征是存在的,否则
false
default Comparator<? super T> getComparator()
Comparator
SORTED
,返回
Comparator
。如果源是
SORTED
在
natural order,返回
null
。否则,如果来源是不是
SORTED
,抛出
IllegalStateException
。
IllegalStateException
。
null
如果元素的自然顺序排序。
IllegalStateException
-如果spliterator不报告
SORTED
特征。
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.