일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 안드로이드 라이선스
- Rxjava Observable
- 안드로이드 레트로핏 crud
- 객체
- 서비스 vs 쓰레드
- android ar 개발
- ar vr 차이
- android retrofit login
- 클래스
- 안드로이드 레트로핏 사용법
- 안드로이드 os 구조
- rxjava hot observable
- rxjava disposable
- 서비스 쓰레드 차이
- 2022 플러터 안드로이드 스튜디오
- 스택 큐 차이
- 안드로이드 라이선스 종류
- 2022 플러터 설치
- 자바 다형성
- 멤버변수
- rxjava cold observable
- jvm 작동 원리
- ANR이란
- jvm이란
- 큐 자바 코드
- 안드로이드 유닛테스트란
- 안드로이드 유닛 테스트
- 플러터 설치 2022
- 스택 자바 코드
- 안드로이드 유닛 테스트 예시
- Today
- Total
나만을 위한 블로그
[Kotlin] 컬렉션 정렬 함수 정리 본문
코틀린에는 Immutable, mutable 2가지 속성이 있고 컬렉션도 이 속성에 따라 2가지로 나눠진다. 이 포스팅에선 리스트를 통해 코틀린에 존재하는 컬렉션 정렬 함수를 확인한다.
sort() / sorted()
먼저 sort()와 sorted()다. 두 함수는 하는 일은 같은 것 같은데 이름이 나눠져 있다. 각 함수에 대한 코틀린 공식 홈페이지의 설명은 아래와 같다.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sort.html
배열을 제자리에서 정렬한다
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/sorted.html
자연 정렬 순서에 따라 정렬된 이 시퀀스의 요소를 생성하는 시퀀스를 반환한다. 정렬이 안정적이다. 이는 동일한 요소가 정렬 후 서로 상대적인 순서를 유지함을 의미한다. 작업은 중간 상태(intermediate)이며 상태 저장(stateful)이다
설명을 봐도 애매하다. IDE에서 sort()와 sorted()의 원형을 확인하면 두 함수의 위치와 리턴형이 다른 걸 확인할 수 있다.
/**
* Sorts elements in the list in-place according to their natural sort order.
*
* The sort is stable. It means that equal elements preserve their order relative to each other after sorting.
*
* @sample samples.collections.Collections.Sorting.sortMutableList
*/
public actual fun <T : Comparable<T>> MutableList<T>.sort(): Unit {
if (size > 1) java.util.Collections.sort(this)
}
/**
* Returns a list of all elements sorted according to their natural sort order.
*
* The sort is stable. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun <T : Comparable<T>> Iterable<T>.sorted(): List<T> {
if (this is Collection) {
if (size <= 1) return this.toList()
@Suppress("UNCHECKED_CAST")
return (toTypedArray<Comparable<T>>() as Array<T>).apply { sort() }.asList()
}
return toMutableList().apply { sort() }
}
sort()는 _Collections.kt에 속하고 sorted()는 MutableCollectionsJVM.kt에 속한다.
그리고 sort()는 아무것도 리턴하지 않지만 sorted()는 List<T>를 리턴한다. IDE에서 대충 리스트를 만든 뒤 두 함수를 사용하면 더 확실하게 알 수 있다.
val list = arrayListOf(2, 4, 1, 3, 5)
val a = list.sort()
println(a) // kotlin.Unit
val b = list.sorted()
println(b) // [1, 2, 3, 4, 5]
제자리에서 정렬한다는 것은 정렬 후 리턴값이 없다는 뜻으로 보면 될 것 같다.
sort()를 먹인 list 안의 값을 출력하려면 아래와 같이 하면 된다.
var list = arrayListOf(2, 4, 1, 3, 5)
list.sort()
println(list)
list = arrayListOf(2, 4, 1, 3, 5)
val a = list.sorted()
println(a)
위와 같이 하면 list, a 모두 정렬된 값들을 출력하는 걸 볼 수 있다.
두 함수의 좀 더 정확한 용례는 아래의 블로그에서 설명하고 있다.
sorted()는 데이터 변경이 안 되는 Immutable List를 정렬 시 사용한다. sorted()는 리스트의 원본을 변경하지 않고 정렬된 리스트를 생성해서 리턴한다...(중략)...sort()는 데이터 변경이 가능한 Mutable List를 정렬할 때 사용한다. 리스트 자신이 가진 요소의 순서를 변경한다.
reverse() / reversed() / asReversed()
순차 정렬을 확인했으니 이번엔 역순 정렬이다. 그런데 역순 정렬 함수는 3종류가 있다.
fun main() {
var list = arrayListOf(2, 4, 1, 3, 5)
list.sort()
list.reverse()
println(list)
list = arrayListOf(2, 4, 1, 3, 5)
val a = list.sorted().reversed()
println(a)
list = arrayListOf(2, 4, 1, 3, 5)
val b = list.sorted().asReversed()
println(b)
}
// [5, 4, 3, 2, 1]
// [5, 4, 3, 2, 1]
// [5, 4, 3, 2, 1]
reverse()와 reversed()는 각각 Immutable, Mutable에 따라 용법이 달라지는 건 알겠는데 asReversed()는 무엇인가?
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/as-reversed.html
원래 리스트의 반전된 읽기 전용 보기(read-only view)를 반환한다. 원래 목록의 모든 변경사항은 반전된 리스트에 반영된다
두 함수만 있어도 충분할 것 같은데 asReversed()가 필요한 이유는 뭘까?
https://stackoverflow.com/questions/57115611/asreversed-vs-reversed-in-kotlin
reversed() : 요소가 역순으로 있는 List만 반환한다. 배열, 리스트 같은 다른 객체에 이 확장에 대한 여러 정의가 있다
asReversed() : List에만 적용 가능하며 원래 리스트의 반전된 읽기 전용 보기를 반환한다. 원래 리스트의 모든 변경사항은 반전된 목록에 반영된다
이 답변대로 reverse()와 reversed()는 여러 배열에 사용할 수 있지만 asReversed()는 List에만 적용할 수 있다. 아래는 asReversed()의 원형이다.
public fun <T> List<T>.asReversed(): List<T> = ReversedListReadOnly(this)
sortedWith() / sortWith()
sortedWith()은 Immutable List, sortWith()은 Mutable List에 사용할 수 있다.
맨 위의 sort()들과 다른 것은 sortedWith()은 Comparator라는 걸 사용해서 정렬 조건을 설정할 수 있다는 것이다.
fun main() {
val list = listOf("aaaaa", "bbbb", "ccc", "dd", "e")
val comparator: Comparator<String> = compareBy { it.length }
val lengthOrder = list.sortedWith(comparator)
println("문자열 길이 순 정렬 : $lengthOrder")
}
// 문자열 길이 순 정렬 : [e, dd, ccc, bbbb, aaaaa]
문자열 뿐 아니라 객체도 정렬할 수 있다. 아래는 월별로 분류하고 나서 일별로 분류하는 예제다. comparator 프로퍼티를 만들지 않고 sortWith() 안에서 만들어 사용한다.
fun main() {
val dates = mutableListOf(
Dates(8, 19),
Dates(5, 16),
Dates(1, 29),
Dates(5, 10),
Dates(8, 3),
)
dates.sortWith(compareBy<Dates> { it.month }.thenBy { it.day })
dates.forEach {
println(it)
}
}
data class Dates(
val month: Int,
val day: Int
)
/*
Dates(month=1, day=29)
Dates(month=5, day=10)
Dates(month=5, day=16)
Dates(month=8, day=3)
Dates(month=8, day=19)
*/
'개인 공부 > Kotlin' 카테고리의 다른 글
[Kotlin] inline, noinline, crossline이란? (0) | 2023.03.13 |
---|---|
[Kotlin] 무공변성, 공변성, 반공변성과 in / out (0) | 2023.02.22 |
[Kotlin] deferred란? (0) | 2022.10.10 |
[Kotlin] 범위 지정 함수(let, with, run, apply, also)란? (0) | 2022.05.01 |
[Kotlin] 코루틴(Coroutine)이란? (0) | 2022.04.27 |