2017-12-20 18 views
0

私はタイルを取得します。タプルはという種類の値を含むMyClassの値を含んでいます。ボルトの最後には、最初から処理が行われた時刻(startTime)を記録したいと思います。だから私はできる:Kotlin:フィルタリングされた(おそらく空の、多くとも1つの要素の)リストをループする

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を呼び出すことによって例外が発生しますが、最初の解決策は何も例外なく処理されます。これは純粋なロギング目的のためであり、私はそれが例外なくなることを望んでいます。

これを行うより良い方法はありますか?

答えて

1

良い方法があります。 :)

あなたは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) 
} 
+0

あなた最初のソリューションが動作します。 2番目のアプローチでもう1つキャストしなければならなかった: '(input.values.firstOrNull {それはMyClass}ですか?MyClassとして).let ...'。それ以外の場合は 'let'ブロックで' it.startTime'を実行できません。 – breezymri

+0

おっと、申し訳ありませんが、あなたは正しいです。私はスマートキャストで2番目の例を修正しました。あなたはたぶん最初のものと一緒に行く方が良いでしょう。 – zsmb13

関連する問題