Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- cleancode
- Baekjoon
- JPA
- Elasticsearch
- kotlin
- 백준
- 코딩
- 프레임워크
- Spring
- 클린코드
- 엘라스틱서치
- 코드
- ES
- 그리디
- Java
- 자바
- API
- 애자일기법
- spring boot
- 애자일프로그래밍
- framework
- 스프링
- 개발
- database
- 그리디알고리즘
- 읽기쉬운코드
- 코딩테스트
- 알고리즘
- 데이터베이스
- 개발자
Archives
- Today
- Total
튼튼발자 개발 성장기🏋️
Java Optional to Kotlin Nullable Type 본문
반응형
자바에서 코틀린으로 포팅하면서 고려해야할 리팰토링 중 [Optional]부문에 대해서 설명한다.
백문이 불여일견이라고 직접 실습을 통해 차근차근 설명하겠다.
public class Legs {
public static Optional<Leg> findLongestLegOver(
List<Leg> legs,
Duration duration
) {
Leg result = null;
for (Leg leg : legs) {
if (isLongerThan(leg, duration))
if (result == null ||
isLongerThan(leg, result.getPlannedDuration())
) {
result = leg;
}
}
return Optional.ofNullable(result);
}
private static boolean isLongerThan(Leg leg, Duration duration) {
return leg.getPlannedDuration().compareTo(duration) > 0;
}
}
자바 코드를 단순히 코틀린으로 포팅하면 아래와 같다.
object Legs {
fun longestLegOver(
legs: List<Leg>,
duration: Duration
): Leg? {
var result: Leg? = null
for (leg in legs) {
if (isLongerThan(leg, duration))
if (result == null ||
isLongerThan(leg, result.plannedDuration))
result = leg
}
return result
}
private fun isLongerThan(leg: Leg, duration: Duration): Boolean {
return leg.plannedDuration.compareTo(duration) > 0
}
}
원래 자바 메서드가 정적 메서드였기 때문에 이 함수들이 들어갈 무언가가 필요해서 object에 넣었다. 사실 코틀린은 이러한 추가적인 네임스페이스가 불필요하지만 지금은 이해를 돕기 위해 이렇게 하겠다. 이 코드를 한 층 더 개선한다면 Move to top level을 적용하면 된다. 추가로 isLongerThan()메서드에서 단일식 함수 구문을 사용하였으며 코틀린의 자랑인 확장함수를 사용했다.
fun longestLegOver(
legs: List<Leg>,
duration: Duration
): Leg? {
var result: Leg? = null
for (leg in legs) {
if (leg.isLongerThan(duration))
if (result == null ||
leg.isLongerThan(result.plannedDuration))
result = leg
}
return result
}
private fun Leg.isLongerThan(duration: Duration) =
plannedDuration.compareTo(duration) > 0
이제 로직을 리팩토링해보자.
longestLegOver 함수는 가장 긴 구간을 찾고 그 구간이 주어진 기간보다 길다면 그 값을 반환하고 그렇지 않으면 null을 반환한다.
가장 긴 구간은 legs.maxByOrNull 함수로 대체할 수 있다.
fun longestLegOver(
legs: List<Leg>,
duration: Duration
): Leg? {
val longestLeg: Leg? = legs.maxByOrNull(Leg::plannedDuration)
return if (longestLeg != null && longestLeg.plannedDuration > duration)
longestLeg
else
null
}
여기서 또 한 층 개선한다면 엘비스 연산자 혹은 ?.let식, when식, takeIf을 사용할 수도 있다.
(takeIf는 술어가 true이면 수신 객체를 리턴하고 false이면 null을 리턴한다.)
// 엘비스 연산자
fun longestLegOver(
legs: List<Leg>,
duration: Duration
): Leg? {
val longestLeg = legs.maxByOrNull(Leg::plannedDuration) ?:
return null
return if (longestLeg.plannedDuration > duration)
longestLeg
else
null
}
// ?.let식
fun longestLegOver(
legs: List<Leg>,
duration: Duration
): Leg? =
legs.maxByOrNull(Leg::plannedDuration)?.let { longestLeg ->
if (longestLeg.plannedDuration > duration)
longestLeg
else
null
}
// when식
fun longestLegOver(
legs: List<Leg>,
duration: Duration
): Leg? {
val longestLeg = legs.maxByOrNull(Leg::plannedDuration)
return when {
longestLeg == null -> null
longestLeg.plannedDuration > duration -> longestLeg
else -> null
}
}
// takeIf
fun longestLegOver(
legs: List<Leg>,
duration: Duration
): Leg? =
legs.maxByOrNull(Leg::plannedDuration)?.takeIf { longestLeg ->
longestLeg.plannedDuration > duration
}
반응형
'프로그래밍 > Kotlin' 카테고리의 다른 글
Java Collections to Kotlin Collections (1) | 2025.06.15 |
---|---|
Java Bean to Kotlin Value (1) | 2025.06.14 |
Java Class to Kotlin Class (0) | 2025.06.04 |
[Kotlin] 리스트 (1) | 2024.12.08 |
[Kotlin] 재귀와 공재귀 (0) | 2024.12.07 |