반응형
Kotlin은 이미 많은 곳에서 사용하여 기본적인 문법에 대해선 다들 아실 것이라 생각합니다. :) 이미 많은 곳에서 Kotlin을 도입했거나 도입중 일 것입니다. 그리하여 이번 글에서는 Kotlin은 Tip의 관한 내용을 정리해보려합니다. 이 글은 Kotlin 홈페이지에서 Kotlin tips 의 내용을 정리한 글입니다. 좀 더 자세한 내용을 원하신다면 링크를 참조해주세요.
1. Timing Code
메서드 혹은 로직의 실행시간을 측정하려면 기존에는 System 시간을 가져와서 빼거나 StopWatch를 이용해서 start하고 stop하는 불편함을 감수했었습니다. 하지만 kotlin에서 지원하는 measureTimedValue 를 사용한다면 쉽게 실행시간과 반환 값을 구할 수 있습니다.
@OptIn(ExperimentalTime::class) // 필수
@Test
fun `times`() {
val (value, time) = measureTimedValue { longOperation() } // use
println("It took $time to caculate $value.")
}
fun longOperation(): String {
repeat(20) {
print(".")
}
return "DONE"
}
// response
....................It took 4.713ms to caculate DONE.
비슷한 메서드로 아래와 같이 지원합니다. 메서드의 이름만 봐도 어떤 결과값을 반환할지 알 수 있네요.
2. Improving loop
Kotlin의 Loop를 개선하는 방법을 알아보겠습니다. 아래와 같은 Loop가 있습니다.
val fruits = listOf("Apple", "Banana", "Cherry", "Durian")
@Test
fun `improving loop`() {
for (index in 0 .. fruits.size -1) {
val fruit = fruits[index]
println("$index: $fruit")
}
}
// print
0: Apple
1: Banana
2: Cherry
3: Durian
덤으로 체크하고 넘어가자
0..5 | 0 <= .. <= 5 |
0 until 5 | 0 <= .. < 5 |
개선해보자
2-1. lastIndex
for (index in 0 .. fruits.lastIndex) {
val fruit = fruits[index]
println("$index: $fruit")
}
// code
public val <T> List<T>.lastIndex: Int
get() = this.size - 1
2-2. indices
for (index in fruits.indices) {
val fruit = fruits[index]
println("$index: $fruit")
}
// code
public val Collection<*>.indices: IntRange
get() = 0..size - 1
2-3. withIndex, forEachIndexed
for ((index, fruit) in fruits.withIndex()) {
println("$index: $fruit")
}
fruits.forEachIndexed { index, fruit ->
println("$index: $fruit")
}
3. Strings
아래의 객체로 예제코드를 작성해보겠습니다.
data class Cat(val name: String, val sound: String, val photo: String)
val cats = listOf(
Cat("Momo", "meow", "momo_dancing.jpg"),
Cat("", "purr", "cat_sleeping.jpg"),
Cat("Bella", "MEOW", "bella_hunting.jpg"),
)
3-1. removePrefix, removeSuffix, removeSurrounding
cats.map { it.photo.removeSuffix(".jpg") }
// [momo_dancing, cat_sleeping, bella_hunting]
"__MEOW__".removeSurrounding("__")
// MEOW
3-2. ifEmpty, ifBlank
cats.map { if(it.name.isBlank()) "the Cat" else it.name }
cats.map { it.name.ifBlank { "the Cat" } } // Good!
// [Momo, the Cat, Bella]
3-3. equals(ignoreCase = ... )
// cat first sound: meow
// cat last sound: MEOW
cats.first().sound.lowercase() == cats.last().sound.lowercase()
// true
cats.first().sound.equals(cats.last().sound , ignoreCase = true)
// true
4. Doing more with the Elvis operator
Elvis operator: ?:
특정 메서드에서 반환 된 값이 null 이라면 default값을 주고 싶은 경우가 있을 것 입니다. 이런 경우는 간단하게 엘비스 연산자를 이용해 풀 수 있습니다.
fun getName(): String? {
return null
}
val greeting = getName() ?: "undefined" // log를 남기고 싶다면?
하지만 null을 반환했으니 log를 남기고 싶다면 아래와 같이 할 수 있습니다.
val greeting = getName() ?: run {
println("Oops, name was not set.")
"undefined"
}
5. Kotlin Collections
아래의 데이터로 예시를 작성해보겠습니다.
data class Fruit(val name: String, val sugar: Int)
val fruits = listOf(
Fruit("banana", 12),
Fruit("apple", 10),
Fruit("orange", 9),
Fruit("pineapple", 10),
Fruit("peach", 8),
Fruit("lemon", 2),
Fruit("mango", 13),
).sortedBy(Fruit::sugar)
5-1. take, takeFirst, drop, dropLast
fruits.take(2)
// [Fruit(name=lemon, sugar=2), Fruit(name=peach, sugar=8)]
// 앞의 2개
fruits.takeLast(3)
// [Fruit(name=pineapple, sugar=10), Fruit(name=banana, sugar=12), Fruit(name=mango, sugar=13)]
// 뒤의 3개
fruits.drop(2)
// [Fruit(name=orange, sugar=9), Fruit(name=apple, sugar=10), Fruit(name=pineapple, sugar=10), Fruit(name=banana, sugar=12), Fruit(name=mango, sugar=13)]
// 앞의 2개 삭제
fruits.dropLast(3)
// [Fruit(name=lemon, sugar=2), Fruit(name=peach, sugar=8), Fruit(name=orange, sugar=9), Fruit(name=apple, sugar=10)]
// 뒤의 3개 삭제
결과값으로 확인할 수 있듯이 기존의 리스트가 아닌 새로운 리스트를 반환한다.
5-2. Partition
val (sweet, superSweet) = fruits.partition { it.sugar < 10 }
// sweet: [Fruit(name=lemon, sugar=2), Fruit(name=peach, sugar=8), Fruit(name=orange, sugar=9)]
// superSweet: [Fruit(name=apple, sugar=10), Fruit(name=pineapple, sugar=10), Fruit(name=banana, sugar=12), Fruit(name=mango, sugar=13)]
// sweet: 10보다 작은 객체들
// superSweet: 10보다 크거나 같은 객체들
5-3. JoinToString
fruits.reversed().joinToString(
separator = " + ",
prefix = "GoodKotlin = [",
postfix = "]",
limit = 3,
truncated = "MORE.."
) { it.name }
// GoodKotlin = [mango + banana + pineapple + MORE..]
같이 Kotlin 멋지게 써봐요. :)
반응형
'Develop > kotlin' 카테고리의 다른 글
[Kotlin] Application 설정값 가져오는 방법 - ConfigurationProperties로 구성 (1) | 2021.05.17 |
---|---|
Querydsl-JPA 코틀린스럽게 작성하기 ( 설정 포함 ) (1) | 2021.04.29 |