Search

Ordering

요소의 순서는 특정 컬렉션 타입에서 중요한 측면이다.
예를 들어, 동일한 요소로 구성된 두 개의 List는 요소의 순서가 다르면 같지 않다.

Comparator

Kotlin에서는 객체의 순서를 여러 가지 방법으로 정의할 수 있다.
자연 순서는 Comparable 인터페이스의 구현체에 대해 정의되고 다른 순서가 지정되지 않은 경우 이를 정렬하는데 사용된다.
대부분의 기본 타입은 비교 가능하다.
숫자 타입은 전통적인 수치 순서를 사용한다.
Char와 String은 사전식 순서를 사용한다.
사용자 정의 타입의 자연 순서를 정의하려면 해당 타입이 Comparable 인터페이스를 구현하도록 하면 된다.
이는 compareTo() 함수를 구현해야 하며 이 함수는 동일한 타입의 다른 객체를 인수로 받아들이고 두 객체를 비교하여 정수 값을 반환한다.
양수 : 수신 객체가 더 큼
음수 : 수신 객체가 더 작음
0 : 두 객체가 같음
class Version(val major: Int, val minor: Int): Comparable<Version> { override fun compareTo(other: Version): Int = when { this.major != other.major -> this.major compareTo other.major // compareTo()를 인픽스 형식으로 사용 this.minor != other.minor -> this.minor compareTo other.minor else -> 0 } } fun main() { println(Version(1, 2) > Version(1, 3)) println(Version(2, 0) > Version(1, 5)) }
Kotlin
복사
사용자 정의 순서를 통해 어떤 타입의 인스턴스도 원하는 방식으로 정렬할 수 있다.
특히, 비교 가능하지 않은 객체에 대한 순서를 정의하거나 비교 가능 타입에 대해 자연 순서와 다른 순서를 정의할 수 있다.
타입의 사용자 정의 순서를 정의하려면 Comparator를 생성하면 된다.
Comparator는 compare() 함수를 포함하며 compareTo()와 동일하게 두 인스턴스를 인수로 받아들이고 두 객체 간의 비교 결과를 정수로 반환한다.
val lengthComparator = Comparator { str1: String, str2: String -> str1.length - str2.length } println(listOf("aaa", "bb", "c").sortedWith(lengthComparator))
Kotlin
복사
lengthComparator 를 사용하면 기본 사전식 순서 대신 문자열을 길이에 따라 정렬할 수 있다.
println(listOf("aaa", "bb", "c").sortedWith(compareBy { it.length }))
Kotlin
복사
Comparator를 정의하는 더 간단한 방법은 표준 라이브러리의 compareBy() 함수를 사용하는 것이다.
compareBy()는 인스턴스에서 Comparable 값을 생성하는 람다 함수를 인수로 받아들이고 생성된 값의 자연 순서로 사용자 정의 순서를 정의한다.

자연 순서

val numbers = listOf("one", "two", "three", "four") println("오름차순 정렬: ${numbers.sorted()}") println("내림차순 정렬: ${numbers.sortedDescending()}")
Kotlin
복사
기본 함수인 sorted()sortedDescending() 은 컬렉션의 요소를 자연 순서에 따라 오름차순 및 내림차순으로 정렬하여 반환한다.
이 함수는 Comparable 요소로 구성된 컬렉션에 적용된다.

사용자 정의 순서

val numbers = listOf("one", "two", "three", "four") val sortedNumbers = numbers.sortedBy { it.length } println("길이 기준 오름차순 정렬: $sortedNumbers") val sortedByLast = numbers.sortedByDescending { it.last() } println("마지막 글자 기준 내림차순 정렬: $sortedByLast")
Kotlin
복사
사용자 정의 순서로 정렬하거나 비교 가능하지 않은 객체를 정렬하기 위해 sortedBy()sortedByDescending() 함수를 사용할 수 있다.
이 함수들은 컬렉션 요소를 Comparable 값으로 매핑하는 선택자 함수를 사용하여 컬렉션을 해당 값의 자연 순서로 정렬한다.
val numbers = listOf("one", "two", "three", "four") println("길이 기준 오름차순 정렬: ${numbers.sortedWith(compareBy { it.length })}")
Kotlin
복사
컬렉션 정렬을 위한 사용자 정의 순서를 정의하려면 고유한 Comparator를 제공하여 sortedWith() 함수를 호출할 수 있다.

역순

val numbers = listOf("one", "two", "three", "four") println(numbers.reversed()) // [four, three, two, one]
Kotlin
복사
reversed() 함수를 사용하여 컬렉션을 역순으로 가져올 수 있다.
reversed() 는 요소의 복사본으로 새로운 컬렉션을 반환하므로 원본 컬렉션을 변경하더라도 영향을 주지 않는다.
val numbers = listOf("one", "two", "three", "four") val reversedNumbers = numbers.asReversed() println(reversedNumbers) // [four, three, two, one]
Kotlin
복사
asReversed() 는 동일한 컬렉션 인스턴스의 역순 뷰를 반환하므로 원본 컬렉션이 변경되지 않을 경우 더 가벼우며 바람직하다.
val numbers = mutableListOf("one", "two", "three", "four") val reversedNumbers = numbers.asReversed() println(reversedNumbers) // [four, three, two, one] numbers.add("five") println(reversedNumbers) // [five, four, three, two, one]
Kotlin
복사
원본 컬렉션이 가변적이라면 모든 변경 사항이 역순 뷰에 반영되며 그 반대도 마찬가지이다.
컬렉션의 가변성을 알 수 없거나 List가 아닐 경우 reversed()의 결과가 이후에 변경되지 않는 복사본이기 때문에 더 바람직하다.

무작위 순서

val numbers = listOf("one", "two", "three", "four") println(numbers.shuffled())
Kotlin
복사
shuffled() 함수는 컬렉션 요소를 무작위 순서로 포함하는 새로운 리스트를 반환한다.