min과 minOrNull 모두 컬렉션에서 최소값을 찾기 위해 사용되는 함수이다.
블로그 포스팅을 보면 어떤 글에서는 .min()을 단독으로 사용하고, 어떤 글에서는 .minOrNull()을 사용한다.왜 그러는걸까? 본 파트에서는 위의 두 방법에 차이점에 대해 기술한다.
- 컬렉션이 최소값이 있다고 가정하고 값을 반환한다.
- Non-Nullable한 결과를 반환한다.
- 최소값이 존재하지 않을 경우 NoSuchElementException을 발생시킨다.
- 컬렉션이 비어있을 경우 null을 반환한다.
val numbers = listOf(3, 1, 4, 1, 5, 9, 2, 6) val minValue = numbers.min() println("최솟값: $minValue") // 출력: 1
- 참고로 기존의 min은 코틀린 버전 1.4.0에서부터 minOrNull로 바뀌었고, min을 가져다 쓰려면 import kotlin.math를 해줘야한다.
- 컬렉션에 최소값이 있으면 반환하고, 비어있으면 null을 반환한다.
- 즉, Nullable한 결과를 반환한다.
- 예외를 발생시키지 않으므로, 컬렉션이 비어있을 때 사용하기 편리하다.
val numbers = listOf(3, 1, 4, 1, 5, 9, 2, 6) val minValueOrNull = numbers.minOrNull() println("최솟값 또는 null: $minValueOrNull") // 출력: 1
!!, ?: 0 은 Nullable한 값을 다룰 때 사용되는 것들이다. 둘 다 Nullable한 상황에서 Non-Nullable한 결과를 얻고자 할 때 사용하는 것 같다. 특히 최근에 minOrNull()을 쓰다보면 !!, ?: 0를 함께 써야하는 경우들이 있었다. 둘 다 null safety와 관련된 내용인 것 같기는 하지만 명확하게 구분이 되지 않아 정리해본다.
- 단언 연산자로, 해당 값이 절대로 null이 아님을 확신할 때 사용한다.
- 만약 해당 값이 null이라면 NullPointerException이 발생된다.
val numbers: List<Int>? = null val size: Int = numbers!!.size // NonNull 단언 연산자 사용
- numberrk null이기 때문에 size에 접근할 때 NullPointerException이 발생된다.
- Null 병합 연산자로, Nullable한 값을 Non-Nullable로 바꾸기 위해 사용된다.
- 만약 Nullable한 값이 null이라면 우측의 기본값(0또는 다른 지정 값)을 사용한다.
val numbers: List<Int>? = null val size: Int = numbers?.size ?: 0 // Null 병합 연산자 사용
- numbers가 null이기 때문에 size에는 0이 할당된다(별도의 예외가 발생하지 않음).
val numbers: List<Int> = listOf(4, 2, 7, 1, 9) // Case 1: Non-null 단언 연산자 (!!) val minValueNotNull: Int = numbers.minOrNull()!! // Case 1: Null 병합 연산자 (?:) val minValueWithDefault: Int = numbers.minOrNull() ?: 0
[TIL-240307]