Mig*_*boa 5 java-8 java-stream
java.lang.OutOfMemoryError: Java heap space
当我使用AbstractSpliterator
实现时,我有一个报告未知大小的实现.
在这种情况下,我定义了一个类StreamCollapse
,它AbstractSpliterator
在tryAdvance()
实现中扩展和合并一系列相邻元素.它的构造函数将超级构造函数调用为super(Long.MAX_VALUE, source.characteristics())
.
关于API文档,我期望使用a Long.MAX_VALUE
表示未知大小.但是,它似乎正在尝试分配具有该大小的内存.
为什么要分配那个空间?我应该使用什么价值估算大小?
这是一个示例测试:
Stream<Integer> nrs = Stream.of(3, 3, 5, 5, 3, 3, 3, 4, 4, 4 ,5 , 5);
Integer [] expected = {3, 5, 3, 4, 5};
Object[] actual = collapse(nrs).toArray();
assertEquals(actual, expected);
Run Code Online (Sandbox Code Playgroud)
和collapse()
方法实现:
static <T> Stream<T> collapse(Stream<T> source) {
return StreamSupport.stream(
new StreamCollapse<T>(source.spliterator()), false);
}
class StreamCollapse<T> extends AbstractSpliterator<T> implements Consumer<T> {
private final Spliterator<T> source;
private T curr = null;
StreamCollapse(Spliterator<T> source) {
super(Long.MAX_VALUE, source.characteristics());
this.source = source;
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
T prev = curr;
boolean hasNext;
while ((hasNext = source.tryAdvance(this)) && curr.equals(prev)) { }
if(hasNext) action.accept(curr);
return hasNext;
}
@Override
public void accept(T item) {
curr = item;
}
}
Run Code Online (Sandbox Code Playgroud)
您应该从合成的分裂器中删除特征,例如:
// an unknown spliterator shouldn't having SIZED | SUBSIZED characteristics
// v
super(Long.MAX_VALUE, source.characteristics() & (~(SIZED | SUBSIZED)));
Run Code Online (Sandbox Code Playgroud)
当 Spliteartor是SIZED Spliteartor时,Spliterator#getExactSizeIfKnown将由stream用于创建数组.
表示从遍历或分裂
estimateSize()
之前返回的值表示有限大小的特征值,在没有结构源修改的情况下,表示完整遍历将遇到的元素数量的精确计数.
如果流并行运行,则Stream#toArray将抛出一个IllegalArgumentException
如果estimateSize > = Long.MAX_VALUE - 8
.
如果流是顺序流,则Stream#toArray将其内部数组容量增加到estimateSize.
归档时间: |
|
查看次数: |
128 次 |
最近记录: |