Kotlin - 리스트 정렬 방법 (sort, sortBy, sortWith)

코틀린에서 리스트를 정렬하는 다양한 방법을 소개합니다.

1. Immutable 리스트 정렬

sorted()는 데이터 변경이 안되는 리스트(Immutable list)를 정렬할 때 사용합니다. sorted()는 리스트의 원본을 변경하지 않고, 정렬된 리스트를 생성하여 리턴합니다.

다음은 Immutable 리스트를 sorted()로 정렬하는 예제입니다.

fun main(args: Array<String>){

    val list = listOf(10, 100, 50, 2, 77, 4)

    val sorted = list.sorted()
    println("sorted: $sorted")
}

Output:

sorted: [2, 4, 10, 50, 77, 100]

2. Mutable 리스트 정렬

sort()는 데이터 변경이 가능한 리스트(Mutable list)의 요소들을 정렬합니다. 리스트 자신이 갖고 있는 요소의 순서를 변경합니다.

다음은 Mutable 리스트를 sort()로 정렬하는 예제입니다.

fun main(args: Array<String>){

    val list = mutableListOf(10, 100, 50, 2, 77, 4)

    list.sort()
    println("sorted: $list")
}

Output:

sorted: [2, 4, 10, 50, 77, 100]

3. 역순으로 정렬 (오름차순, 내림차순)

Mutable, Immutable 리스트에 따라서 역순으로 정렬하는 메소드가 다릅니다.

  • reversed() : Immutable 리스트에서 사용합니다. 역순으로 변경된 리스트를 생성하고 리턴합니다.
  • reverse() : Mutable 리스트에서 사용되며, 리스트 자신의 요소 순서를 반대로 변경합니다.

다음과 같이 Mutable 또는 Immutable 리스트를 역순으로 정렬할 수 있습니다.

fun main(args: Array<String>){

    // 1. immutable list
    val list = listOf(10, 100, 50, 2, 77, 4)
    val sorted = list.sorted().reversed()
    println("sorted : $sorted")

    // 2. mutable list
    val list2 = mutableListOf(10, 100, 50, 2, 77, 4)
    list2.sort()
    list2.reverse()
    println("sorted : $list2")
}

Output:

sorted : [100, 77, 50, 10, 4, 2]
sorted : [100, 77, 50, 10, 4, 2]

4. sortedWith(), sortWith()

sortWith()는 정렬 규칙인 Comparator를 변경합니다. 즉, Comparator를 변경하여 자신이 원하는 방식으로 리스트를 정렬할 수 있습니다.

Mutable, Immutable에 따라서 사용하는 메소드가 다릅니다.

  • sortedWith() : Immutable list에서 사용
  • sortWith() : Mutable list에서 사용

String을 sorted()로 정렬하면 기본적으로 문자열의 ASCII 값을 비교하여 정렬합니다. 만약 문자열의 길이로 정렬하고 싶을 때 Comparator를 직접구현하여 sortedWith()에 인자로 전달할 수 있습니다. Comparator를 생성할 때는 compareBy의 Lambda에 비교할 객체가 리턴되도록 만들면 됩니다.

다음은 문자열의 길이로 정렬하는 예제입니다. sorted()sortedWith()로 정렬되는 결과들을 비교할 수 있습니다.

fun main(args: Array<String>){

    val list = listOf("apple", "banana", "kiwi", "orange", "watermelon")

    val alphabetOrder = list.sorted()
    println("Alphabet order: $alphabetOrder")

    val comparator : Comparator<String> = compareBy { it.length }
    val lengthOrder = list.sortedWith(comparator)
    println("Length order: $lengthOrder")
}

Output:

Alphabet order: [apple, banana, kiwi, orange, watermelon]
Length order: [kiwi, apple, banana, orange, watermelon]

Example 2 : 좀 더 구체적인 Comparator 정의

Comparator로 객체를 비교할 때, 두개의 객체가 동일할 때, 다른 조건으로 비교하고 싶을 때가 있습니다.

아래 예제에서 Comparator는 먼저 year로 비교를 하고, year가 같으면 month, day 순서로 비교합니다.

import java.util.*

fun main(args: Array<String>){
    val dates = mutableListOf(
        Date(2020, 4, 3),
        Date(2021, 5, 16),
        Date(2020, 4, 29)
    )

    dates.sortWith(compareBy<Date> { it.year }.thenBy { it.month }.thenBy { it.day })

    dates.forEach { println(it) }
}

Output:

Mon May 03 00:00:00 KST 3920
Sat May 29 00:00:00 KST 3920
Thu Jun 16 00:00:00 KST 3921

5. sortedBy(), sortBy()

sortBy()는 리스트의 요소가 1개의 데이터 타입으로 이루어지지 않고, 내부에 여러 객체를 갖고 있는 타입일 때, 어떤 객체를 비교하여 정렬할 지 결정할 때 사용합니다.

  • sortedBy() : Immutable list에서 사용
  • sortBy() : Mutable list에서 사용

아래 예제에서 list는 Pair를 요소로 갖고 있습니다. Pair는 첫번째와 두번째 요소를 갖고 있는데, 어떤 요소를 정렬할 때 사용할지 sortBy()로 선택할 수 있습니다. 아래 코드에서 sortBy { it.first }는 Pair의 첫번째 요소로 정렬을 하고, sortBy { it.second }는 두번째 요소로 정렬을 합니다.

fun main(args: Array<String>){

    val list = mutableListOf("d" to 4, "a" to 10, "c" to 8, "h" to 5)
    println("list: $list")

    list.sortBy { it.first }
    println("sortByFirst: $list")

    list.sortBy { it.second }
    println("sortBySecond: $list")
}

Output:

list: [(d, 4), (a, 10), (c, 8), (h, 5)]
sortByFirst: [(a, 10), (c, 8), (d, 4), (h, 5)]
sortBySecond: [(d, 4), (h, 5), (c, 8), (a, 10)]

References

Loading script...
codechachaCopyright ©2019 codechacha