Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.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
使用scala中while循环内队列的结果填充列表_Scala_Functional Programming - Fatal编程技术网

使用scala中while循环内队列的结果填充列表

使用scala中while循环内队列的结果填充列表,scala,functional-programming,Scala,Functional Programming,我试图在scala中以函数的方式编写一个while循环。我想做的是用队列中的消息填充一个列表(在本例中是Kafka,但实际上并不重要) 我这样做是为了集成测试,因为当测试在CI中运行时Kafka正在远程运行,所以测试有时会失败,因为Kafka不返回任何消息。因此,我编写了一个循环,它将查询Kafka,直到我返回我期望的所有结果(否则测试将在一段时间后超时并失败)。我现在有这个: var result = List[Int]() while (result.size < expectedNu

我试图在scala中以函数的方式编写一个while循环。我想做的是用队列中的消息填充一个列表(在本例中是Kafka,但实际上并不重要)

我这样做是为了集成测试,因为当测试在CI中运行时Kafka正在远程运行,所以测试有时会失败,因为Kafka不返回任何消息。因此,我编写了一个循环,它将查询Kafka,直到我返回我期望的所有结果(否则测试将在一段时间后超时并失败)。我现在有这个:

var result = List[Int]()
while (result.size < expectedNumberOfMessages) {
    result = result ++ kafkaConsumer.poll(Duration.ofSeconds(10)).records(KAFKA_TOPIC).iterator().toList.map(_.value.getPayload)
}
var result=List[Int]()
while(result.size

这很好,但我觉得很可怕。另外,如果它是生产代码,它也将是低效的。有人能提出一种更好的功能实现方法吗?

如果您打算在
的同时保持
循环,我首先建议您使用
scala.collection.mutable.ListBuffer
而不是不可变的
列表。这将防止在每次迭代时在内存中复制整个列表

如果您希望以更“功能性”的方式编写上述代码,同时保留消费者API(而不是Kafka Streams API),则可以手动定义scala
,如下所示:

导入scala.util.Random
//模拟卡夫卡的“轮询”,返回随机数目的整数(最多10)
def poll():列表[Int]={
val size=Random.nextInt(10)
println(“获取消息”)
线程。睡眠(1000)
(1到大小).map(=>Random.nextInt(10)).toList
}
lazy val s:Stream[Int]=Stream.continuously(poll()).flatten
//s现在是一个流,当请求一定数量的消息时将对其进行评估
//例如,获取40个结果:
/*
scala>s.take(40.toList)
获取消息
获取消息
获取消息
获取消息
获取消息
获取消息
获取消息
获取消息
获取消息
res0:List[Int]=List(3,6,2,7,7,8,0,4,6,2,0,3,8,9,5,8,2,9,2,7,9,2,6,1,6,7,2,4,4,6,6,3,5,7,2,0,9,4)
*/

如果您计划在循环期间保持
,我首先建议您使用
scala.collection.mutable.ListBuffer
而不是不可变的
列表。这将防止在每次迭代时在内存中复制整个列表

如果您希望以更“功能性”的方式编写上述代码,同时保留消费者API(而不是Kafka Streams API),则可以手动定义scala
,如下所示:

导入scala.util.Random
//模拟卡夫卡的“轮询”,返回随机数目的整数(最多10)
def poll():列表[Int]={
val size=Random.nextInt(10)
println(“获取消息”)
线程。睡眠(1000)
(1到大小).map(=>Random.nextInt(10)).toList
}
lazy val s:Stream[Int]=Stream.continuously(poll()).flatten
//s现在是一个流,当请求一定数量的消息时将对其进行评估
//例如,获取40个结果:
/*
scala>s.take(40.toList)
获取消息
获取消息
获取消息
获取消息
获取消息
获取消息
获取消息
获取消息
获取消息
res0:List[Int]=List(3,6,2,7,7,8,0,4,6,2,0,3,8,9,5,8,2,9,2,7,9,2,6,1,6,7,2,4,4,6,6,3,5,7,2,0,9,4)
*/

也许是这样的

def pollKafka = kafkaConsumer.poll(Duration.ofSeconds(10)).records(KAFKA_TOPIC).iterator.map(_.value.getPayload)

Iterator
  .continually(pollKafka)
  .flatten
  .take(expectedNumberOfMessages)
  .toList
Iterator
在内部是可变的,但是如果您使用它的高级功能接口,并且不重用
Iterator
,它就完全可以了


如果你想一直沿用函数流,你可以考虑一个像FS2这样的库。

也许是这样的?

def pollKafka = kafkaConsumer.poll(Duration.ofSeconds(10)).records(KAFKA_TOPIC).iterator.map(_.value.getPayload)

Iterator
  .continually(pollKafka)
  .flatten
  .take(expectedNumberOfMessages)
  .toList
Iterator
在内部是可变的,但是如果您使用它的高级功能接口,并且不重用
Iterator
,它就完全可以了

如果你想一直沿用函数流,你可以考虑像FS2这样的库。