我有一个风暴螺栓,它获得的元组包含MyClass
类型的值,而后者则携带时间字段startTime
。在螺栓的末尾,我想记录处理从头开始的时间(由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
得到一个异常,而第一个解决方案没有任何异常就完成了。由于这是为了纯日志目的,我希望它是免除例外的。
有一个更好的方法吗?
有一个更好的方法! :)
您可以使用firstOrNull()
然后安全通话:
input.values.filterIsInstance(MyClass).firstOrNull()?.let {
val endToEndTime = (System.currentTimeMillis() - it.startTime).toInt()
stats.recordExecutionTime("mytag", endToEndTime)
}
您还可以使用带有谓词的filterIsInstance
版本替换firstOrNull()
调用,如下所示:
input.values.firstOrNull { it is MyClass }?.let {ű
it as MyClass
val endToEndTime = (System.currentTimeMillis() - it.startTime).toInt()
stats.recordExecutionTime("mytag", endToEndTime)
}