[Kotlin] min과 minOrNull의 차이 / !! 와 ?: 0의 차이

neoneoneo·2024년 3월 7일
0

kotlin

목록 보기
24/49

min - minOrNull

min과 minOrNull 모두 컬렉션에서 최소값을 찾기 위해 사용되는 함수이다.
블로그 포스팅을 보면 어떤 글에서는 .min()을 단독으로 사용하고, 어떤 글에서는 .minOrNull()을 사용한다.왜 그러는걸까? 본 파트에서는 위의 두 방법에 차이점에 대해 기술한다.

min

  • 컬렉션이 최소값이 있다고 가정하고 값을 반환한다.
  • 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를 해줘야한다.

minOrNull

  • 컬렉션에 최소값이 있으면 반환하고, 비어있으면 null을 반환한다.
    • 즉, Nullable한 결과를 반환한다.
  • 예외를 발생시키지 않으므로, 컬렉션이 비어있을 때 사용하기 편리하다.
val numbers = listOf(3, 1, 4, 1, 5, 9, 2, 6)
val minValueOrNull = numbers.minOrNull()
println("최솟값 또는 null: $minValueOrNull")  // 출력: 1

!! - ?: 0

!!, ?: 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이 발생된다.

?: 0

  • Null 병합 연산자로, Nullable한 값을 Non-Nullable로 바꾸기 위해 사용된다.
  • 만약 Nullable한 값이 null이라면 우측의 기본값(0또는 다른 지정 값)을 사용한다.
val numbers: List<Int>? = null
val size: Int = numbers?.size ?: 0  // Null 병합 연산자 사용
  • numbers가 null이기 때문에 size에는 0이 할당된다(별도의 예외가 발생하지 않음).

minOrNull 예시

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

정리하자면..

  • 컬렉션의 값이 비어있을 것 같다. -> minOrNull()
  • 비어있지 않는다는 사실을 확신할 수 있다. -> min()
    • 단, min은 math 라이브러리를 import 하여 사용한다.
  • 컬렉션에 절대로 null이 없다. -> !!
  • 컬렉션에 어쩌면 null이 있을 것 같다. -> ?: 0

[TIL-240307]

0개의 댓글