Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.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
Kotlin 如果在并行流上运行,collect是否返回列表快照?_Kotlin_Java 8_Java Stream - Fatal编程技术网

Kotlin 如果在并行流上运行,collect是否返回列表快照?

Kotlin 如果在并行流上运行,collect是否返回列表快照?,kotlin,java-8,java-stream,Kotlin,Java 8,Java Stream,我有一个单元测试,仅在Circle CI上开始失败。在这个(Kotlin)示例中,它在最后一行失败: generator.generateNames(50)//返回列表 .parallelStream() .map{name-> val playerId=“${name.firstName.toLowerCase()}” 玩家(playerId=playerId) }.collect(Collectors.toList()).last() 引发:的原因:java.util.NoSuchElem

我有一个单元测试,仅在Circle CI上开始失败。在这个(Kotlin)示例中,它在最后一行失败:

generator.generateNames(50)//返回列表
.parallelStream()
.map{name->
val playerId=“${name.firstName.toLowerCase()}”
玩家(playerId=playerId)
}.collect(Collectors.toList()).last()
引发:
的原因:java.util.NoSuchElementException

如果我不使用并行流,它总是在我的本地机器或Circle CI上工作。我的理论是,
collect
调用返回一个列表快照(在列表完全填满之前,它实际上不会阻塞),并且CI没有足够的CPU来收集其他线程中的单个元素


但是,我的流是有序的,收集器是否正确?这甚至是并行收集吗?

您得到的异常可能包含一条消息,而不仅仅是异常的名称。该消息很可能会告诉您错误。例如,代码的最后一部分调用Kotlin扩展函数
last()
,该函数在实现中:

public fun <T> List<T>.last(): T {
    if (isEmpty())
        throw NoSuchElementException("List is empty.")
    return this[lastIndex]
}
public fun List.last():T{
if(isEmpty())
抛出NoSuchElementException(“列表为空”)
返回此[lastIndex]
}
因此,如果您在
java.util.NoSuchElementException
的堆栈跟踪中看到“List is empty”消息,那么这就是原因

此外,如果您共享堆栈跟踪,您实际上可以看到引发异常的原因。但看看你的代码,这是唯一可能的候选人


接下来的问题是,“为什么最后的列表是空的?!”。。。
generateNames(50)
在这种环境中的工作方式是否不同?问题不在于提供同步结果的
collect(Collectors.toList())

返回的列表是否确实包含元素
.last()
如果为空,则将抛出
NoTouchElementException
。就像我说的,在我的开发机器上运行代码不变总是有效的。在CI上,如果我将并行流转换为顺序流,它会起作用。我不太确定Kotlin做了什么,但如果将事情顺序化似乎是目前唯一的解决方案。然后我建议尝试
collector(Collectors.toList())
as
Player
list,并将获取最后一部分分为两个步骤。类似于以下内容:
List playerList=generator.generateNames(50)//返回List.parallelStream().map(name->new Player(name.getFirstName.toLowerCase())}.collect(Collectors.toList());Player lastplayer=playerList.get(playerList.size()-1);
。请注意,对于您的代码,这不应该在Circle CI上起作用。我不明白,在这方面,“Circle CI”与此操作有什么关系。唯一看起来不像标准Java或普通操作的是
生成器。generateNames(50)
。如果此方法返回一个标准的
列表
实现,应该没有问题。但是,它可能返回某种非线程安全的惰性列表实现?您在两台机器上使用的JDK的风格和版本是什么?经过一些调查,结果表明运行并行流耗尽了JedisPool。我排除了上面的那一行,因为我认为它与此无关。有点遗憾的是,耗尽的池也返回了一个
NoSuchElementException
。这让我走错了方向。但基本上你回答了我的问题:何时
收集(Collectors.toList())
返回时,
列表始终完全填充-使用并行流时也是如此。
public fun <T> List<T>.last(): T {
    if (isEmpty())
        throw NoSuchElementException("List is empty.")
    return this[lastIndex]
}