•
요소의 순서는 특정 컬렉션 타입에서 중요한 측면이다.
•
예를 들어, 동일한 요소로 구성된 두 개의 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() 함수는 컬렉션 요소를 무작위 순서로 포함하는 새로운 리스트를 반환한다.