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