Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 拆分器并行排序顺序_Java_Java 8_Spliterator - Fatal编程技术网

Java 拆分器并行排序顺序

Java 拆分器并行排序顺序,java,java-8,spliterator,Java,Java 8,Spliterator,我正在实现一个分页拆分器(Java),它应该允许并行访问 我有以下测试用例(测试在Groovy和Spock中进行): def“并行,两页”() { 当:“排序范围从0到6” def fetcher=新的IntegerRangePageFetcher(6) 和:“页面大小为5的拆分器” def拆分器=新页面拆分器(取数器,5) 和:“具有给定范围的流被收集到列表” def result=StreamSupport .流(拆分器,真) .collect(收集器.toList()) 然后:“遵守排序顺

我正在实现一个分页拆分器(Java),它应该允许并行访问

我有以下测试用例(测试在Groovy和Spock中进行):

def“并行,两页”()
{
当:“排序范围从0到6”
def fetcher=新的IntegerRangePageFetcher(6)
和:“页面大小为5的拆分器”
def拆分器=新页面拆分器(取数器,5)
和:“具有给定范围的流被收集到列表”
def result=StreamSupport
.流(拆分器,真)
.collect(收集器.toList())
然后:“遵守排序顺序”
预期结果,包含(0、1、2、3、4、5)
}
此测试用例失败,出现以下错误:

Condition not satisfied:

expect result, contains(0, 1, 2, 3, 4, 5)
|      |
false  [5, 0, 1, 2, 3, 4]

Expected: iterable containing [<0>, <1>, <2>, <3>, <4>, <5>]
     but: item 0: was <5>
当我不使用parallel时,代码可以工作。所以我不明白
的顺序

  • 如果设置了,流框架是否应该保证顺序,并在使用并行生成的块时对结果进行排序?如果是,为什么不在我的案例中进行排序
  • 或者我的
    trySplit
    实现中是否有错误,必须按照给定的顺序进行拆分?(当前我在打开的页面中间拆分,0-mid保留在当前拆分器中,mid-end保留在新创建的拆分器中)
  • 或者我应该在
    collect()
    之前调用
    sort()
    ,因为框架根本不能保证任何顺序
---根据反馈进行更新---

谢谢你的回答,我的代码中有两个逻辑错误。首先是请求的代码段:

@覆盖
公共拆分器trySplit()
{
//第一个问题
if(pageIterator==null){
pageIterator=pageFetcher.fetchNextPage(paginationInfo);
}
//代理拆分决策
var newPaginationInfo=paginationInfo.split();
if(newPaginationInfo==null){
log.info(“*Spliterator返回null”);
返回null;
}
//现在我们分手了
var newSpliterator=new PagedSpliterator(pageFetcher,newPaginationInfo);
返回newSpliterator;
}
公共分页信息拆分()
{
//当开放范围或什么都没有留下时,我们不会分割
如果((endElementIndex=-1)| |!hasNextPage()){
返回null;
}
//计算分裂位置
var firsthallpages=(getEndPageIndex()-getNextPageIndex())/2;
var midElementIndex=(getNextPageIndex()+firstHalfPages)*页面大小;
//创建额外的PaginationInfo并根据拆分位置设置范围
var newPaginationInfo=新的PaginationInfo(此);
newPaginationInfo.firstElementOnNextPageIndex=midElementIndex;
newPaginationInfo.nextElementIndex=midElementIndex;
endElementIndex=中间元素索引;
返回newPaginationInfo;
}
第一个错误:

新创建的拆分器设置为第二个半范围,而不是第一个半范围。我在文档中读到了前缀,但我觉得它很笨拙。我按页面大小进行拆分,以获得多个并行请求。在开始时(第一个spliterator实例),我必须获取第一个页面以获取页面和元素计数器。因此,为了解决顺序问题,我必须将从第一个拆分器获取的数据分发给第二个拆分器,以遵守顺序,这让我感觉非常奇怪,而且不直观

第二个错误:

//第一次查询
if(pageIterator==null){
pageIterator=pageFetcher.fetchNextPage(paginationInfo);
}
所有后续创建的拆分器将从框架接收一个
estimateSize()
和一个
trySplit()
调用。在此调用过程中,我当前获取一个页面,但这将阻止并行性,获取必须稍后在
tryAdvance()
调用中进行


我将实现这些更改,然后返回给您。

是的,您的trySplit中有一个bug。Spliterator.trySplit的文档指定,如果您具有有序特征,则返回的Spliterator必须包含元素前缀。切换返回的拆分器和拆分器的剩余内容。

来自
trySplit
的文档:

如果订购了此拆分器,则返回的拆分器必须包含元素的严格前缀

您的实施:

。。。0-mid停留在当前的拆分器上,mid-end进入新创建的拆分器


你可以从这里连接正确的点

我们应该猜一下您的拆分器是如何实现的吗?我还想知道您是否过度拆分了。你什么时候停止分裂?当存在单个元素时?