2017-12-20 21 views
0

나는 이라는 시간 필드를 갖는 MyClass 유형의 값을 포함하는 튜플을 얻는 스톰 볼트가 있습니다. 볼트 끝 부분에서 처리가 처음부터 걸린 시간 (startTime으로 표시)을 기록하고 싶습니다. 그래서 나는 할 수 있었다 :Kotlin : 필터링 된 (가능하면 비어 있고 하나의 요소 일 수도 있음) 목록

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

귀하 첫 번째 솔루션이 작동합니다. 나는 두 번째 접근법으로 '(input.values.firstOrNull {this is MyClass}? MyClass) .let ...'과 같은 캐스트를 하나 더해야했다. 그렇지 않으면'let' 블록에서'it.startTime'을 할 수 없습니다. – breezymri

+0

죄송합니다, 당신 말이 맞아요. 두 번째 예제를 스마트 캐스트로 수정했습니다. 당신은 아마도 첫 번째 것을 가지고가는 것이 나을 것입니다. – zsmb13