Kotlin:循环遍历一个过滤的(可能是空的和至多一个元素)列表

我有一个风暴螺栓,获取包含MyClasstypes值的元组,该元组又包含一个时间字段startTime 。 在bolt的最后,我想记录从头开始处理的时间(用startTime标记)。 所以我可以这样做:

 override fun doExecute(input: Tuple): Boolean { ... // my processing logic input.values.filterIsInstance(MyClass).forEach { val endToEndTime = (System.currentTimeMillis() - it.startTime).toInt() stats.recordExecutionTime("mytag", endToEndTime) } } 

这种方法我真的没有问题。 只是整容明智,它看起来像我可以在元组中有多个MyClass实例(我不这样做)。 所以我想,如果我能从列表中选出第一个:

 override fun doExecute(input: Tuple): Boolean { ... // my processing logic input.values.filterIsInstance(MyClass).first().let { val endToEndTime = (System.currentTimeMillis() - it.startTime).toInt() stats.recordExecutionTime("mytag", endToEndTime) } } 

这似乎更具可读性。 但是,如果filterIsInstance(MyClass)调用返回一个空列表,我通过first调用它来获得一个exception,而第一个解决方案没有任何exception。 由于这是纯粹的日志记录的目的,我希望它是免费的。

有一个更好的方法吗?

有一个更好的方法! 🙂

你可以使用firstOrNull()然后一个安全的调用:

 input.values.filterIsInstance(MyClass).firstOrNull()?.let { val endToEndTime = (System.currentTimeMillis() - it.startTime).toInt() stats.recordExecutionTime("mytag", endToEndTime) } 

您也可以使用带谓词的firstOrNull()的版本替换filterIsInstance调用,如下所示:

 input.values.firstOrNull { it is MyClass }?.let {ű it as MyClass val endToEndTime = (System.currentTimeMillis() - it.startTime).toInt() stats.recordExecutionTime("mytag", endToEndTime) } 
Interesting Posts