CodeGym /행동 /Kotlin SELF /List gibon jeongnyeol — sorted() / sortedDescending()

List gibon jeongnyeol — sorted() / sortedDescending()

Kotlin SELF
레벨 23, 레슨 1
사용 가능

1. Sogae

Jeongnyeol-eun pilyohan jongileul chatgi jeon, chaeksang wieul jeongdonghaneun geot-gwa gatseumnida. Eopseo-do doendago saenggakhagi swipjyo: “na-neun eodieseotneunji gieokhae”라-go. Hajiman iljuilman jina-do chaeksang-eun yeongsujeung, seutikeo, keibeul-iro gadeukhan “gogohakjeok cheung”i doebnida. Peurogeuraem-do ttokgatseumnida: deiteoneun eotteon sunseo-ro deureo-ojiman, sayongja-neun jaju dareun sunseo—ojeonseung, naerimchasu, “keunjiga wie”, “alphabet sunseo”—reul wonhamnida.

Kotlin-eseo gajang joheun jeom-eun, jeongnyeol-i “list-reul gajyeo-oseo → saeroun jeongnyeoldoen list-reul badneunda” cheoreom boinda-neun geosipnida. Geurigo geuge oneul gang-uiui haeksim idea-imnida: wonbon deiteoreul mangchiji anneunda (즉, source-reul mutate haji anneunda) geot, geurigo gyeolgwa-reul ttaro mandeuneun geosipnida. Ige jom joriryeo deut hajiman, siljeon-eseoneun 디버깅 sigan-eul myeot sigan-ssik jul-yeoju-go, singyeong sey-podeuldo adakhae jubnida.

Gijun-i doel geot-i pilyohani, jageun console peurojekteu-reul baljeon-sikyeo boseumnida (pyeonui sang geureohge bureujyo: ExpensePocket): 지출 geumaek-eul jeojangha-go, ttaeron geuge “chuga-doen daero”ga anira “jeongdon-doen daero” boyeo-jugil wonhaneun mini gasi bu-giromnida.

2. Jayeon jeongnyeol(natural order)gwa Comparable

Kotlin-ege “geunyang list-reul jeongnyeolhae jwo”라고 malhamyeon, Kotlin-eun element-reul eotteohge bigyohaljireul al-aya hamnida. 숫자wa munjayeol-eun jasin-i isseo boijiman (geuraedo “wanjeonhi”neun anigo), eotteon “bokjaphan object” (igeun hu-e jinjja nasseul ttae nolsseumnida)reul daerigo omyeon geureoji anhseumnida.

Kotlin pyojun laibeureori-eseo sorted()wa sortedDescending()gachi jeongnyeolhaneun ham-su-deul-eun, element-ga jayeonseureoun jeongnyeolreul gajigo isseul ttae dongjakhamnida. Hyeongsikjeok-euro malhamyeon: element-ga same type-ui dareun element-wa jasin-eul bigyohal su isseoya hamnida (igeun Comparable inteopeiseuwa yeongyeol-doemnida). Kotlin munseo-edo sorted()wa sortedDescending()ga jayeon jeongnyeol-eul ttareugo, saeroun list-reul banhwanhamyeo wonbon collection-eun bakkugi aneunda-go myeongsi-doeeo itseumnida.

Choboja-eseo-neun ireoke badadeurimyeon pyeonhamnida: “type-i jeongdonhal su isseul geotcheoreom boimyeon, Kotlin-i imi eotteohge halji algo itda.”

Chamgohagi joheun jageun pyo-ipnida:

Element type “Natural order”ga eotteohge boineunga Gyeolgwa yebsi
Int, Long, Double
suchi (numerical value)reul ttareum
1 < 2 < 10
Char
munja code-reul ttareum
'A' < 'B' < 'a'
String
lexicographical (daeche-ro “sajeon sunseo”)
"Ann" < "Bob" < "Charlie"
Boolean
daebucheo
false < true
false, geurigo true

Munjayeol-eun han 가지 seobseun jeom-i itseumnida: peurogeuraeming-eseo “sajeon sunseo”neun daebucheo “Korean/English dictionary”ga anira, munja code bigyo-ibnida. Geuraeseo "10"gwa "2"neun 숫자가 anira munjayeol-lo bigyo-doemnida. Igeun bug-ga anira, deiteoui uimi-ga dareul ppun-imnida.

3. Gibon jeongnyeol: sorted() wa sortedDescending()

sorted() — ojeonseung jeongnyeol

sorted()neun collection-eul bad-a saeroun list-reul banhwanhaneun ham-su-ro, element-deul-i ojeonseung (natural order) sunseo-ro baechidoemnida. Gajang jungyohan saenggak: wonbon list-reul “heundeul-eoseo” bakkuneun geosi anira, gyeolgwa-reul ttaro saengseonghamnida. Kotlin munseo-eseo-do read-only collection-e daehan jeongnyeol-i saeroun collection-euro gyeolgwa-reul dollyeojunda-go myeongsi-doeeo itseumnida.

Gajang dan순han yebsi-ro sijakhae boseumnida — 숫자:

fun main() {
    val xs = listOf(3, 1, 2)
    val sortedXs = xs.sorted()

    println(xs)        // [3, 1, 2]
    println(sortedXs)  // [1, 2, 3]
}

Yeogi-eseo du 가지-reul bol su itseumnida. Cheotjjae, xsneun bakkiji anhassseumnida. Du-beonjjae, gyeolgwa-reul byeonsu-e jeojanghaji anh-eumyeon, jeongnyeol-i “andongjakhan-da”go 느낄 su itseumnida — because wonbon list-reul bakkul su eopgi ttaemun-imnida (siljeon-eseoneun i geosi deo joheun seongjil-imnida).

Da-eum-eun munjayeol:

fun main() {
    val names = listOf("Bob", "Ann", "Charlie")
    val sortedNames = names.sorted()

    println(sortedNames) // [Ann, Bob, Charlie]
}

Jam깐: “amugeotdo il-eonan ji anassda”

Choboja-deul-i jaju ireoke sseumnida:

fun main() {
    val xs = listOf(3, 1, 2)
    xs.sorted()
    println(xs) // [3, 1, 2]
}

Igeon compile error-ga anigo, Kotlin-i 굳이 경고hal piryodo eopseumnida. Danji: “jeongnyeoldoen copy-reul jwo”라고 butaghaja, Kotlin-i junda (geurigo geuge eodiro gassneunga? eopseumnida). Geu daeum-e wonbon-eul print-hae beorin geot-ibnida.

Ireon code-neun coffee-reul jumunha-go coffee shop-eul nawa beorineun geot-gwa gatseumnida. Coffee-neun jinjja itseumnida… geureona ije dangsin geos-i anipnida.

sortedDescending() — naerimchasu jeongnyeol

sortedDescending()neun sorted()wa geoui gatseun il-eul hajiman, sunseo-ga bakkwimnida: meonjeo “keunjiga”, geu daeum “jak-eunjiga”. Geurigo tto: saeroun list-reul banhwanhamyeo, wonbon-eun bakkiji anhseumnida. Kotlin munseo-eseo-do sorted()wa sortedDescending()reul jayeon jeongnyeol-eul ttareuneun gibon jeongnyeol로 나란히 je시hamnida.

숫자 yebsi:

fun main() {
    val scores = listOf(10, 70, 50, 20)
    val sorted = scores.sortedDescending()

    println(scores) // [10, 70, 50, 20]
    println(sorted) // [70, 50, 20, 10]
}

Munjayeol yebsi:

fun main() {
    val words = listOf("one", "two", "three", "four")
    println(words.sortedDescending()) // [two, three, one, four]
}

Gyeolgwa-ga saenggakboda isanghae boinda-myeon, geuge jeongsang-imnida: munjayeol-eun lexicographical-ro jeongnyeol-doego, ttaeron sunseo-ga “dan-eoui gil-i”e daehan 직관-gwa an maj-eul su itseumnida. “길이”reul 기준-euro sseuneun geos-eun 나중-e baeul geos-igo, oneul-eun natural order-e jiphunghamnida.

4. “Source-reul mutate haji anh는다” wonchik

“Source-reul mutate haji mal라”neun mal-eun pure code chaek-eseo naol beop한 조언처럼 들려서 gajang meonjeo 넘겨beoril su itseumnida. Hajiman siljeon-eseoneun, tteugeoun bug-reul magneun boheom-gat-eun yeokhal-eul 합니다—teukhi han peurogeuraem 안에서 gateun list-ga 여러 곳에서 sa-yong-doel ttae-yo.

Kotlin-eun “saeroun gyeolgwa-reul doll-yeojwo” haneun yeonsan-gwa “collection-eul 제자리에서 bakkwo” haneun yeonsan-eul myeonghwakhi gu분hamnida. Munseo-eseo-do collection operations-e daehan seolmyeong-eseo jungyohan saenggak-eul hae-ya 합니다: han 쌍-ui ham-su-ga itneun-de, hana-neun in-place-ro jeongnyeol (sort()), dareun hana-neun saeroun list-reul banhwan (sorted())hamnida. Oneul-eun 의도적으로 sorted() variante-reul yeonseuphaneun-de, i geosi 이해하기 쉽go 더 예측 가능한 code-ro 이어jineun gyeong-u-ga manhgi ttaemun-imnida.

Uri-ui ExpensePocketeseo “chuga sunseo-daero”reul jeojanghan jichul list-ga 있다고 sangsanghae boseyo. I geos-eun hyeonjae까지-ui history-reul boyeo-junineun yuyonghan 정보-imnida: eotteon geos-eul eonje chuga-haessneunji. Geureona ttaeron “gateun 숫ja-deul-eul ojeonseung-ro” tto-neun “naerimchasu-ro” 보고 싶seumnida. 만약 jeongnyeol-i wonbon-eul bakkunda-myeon, chuga history-reul irheobeorilgeos-imnida. Hajiman sorted()reul sseumyeon, du 가지-reul 모두 gajil su itseumnida: history-neun 남겨두고, report-neun ttaro 만듭니다.

Mu엇이 il-eonaneunji-reul bo-yeo-juneun schem-a-imnida:

flowchart LR
    A["Isanghan wonbon jichul list (chuga sunseo)"] --> B["sorted() / sortedDescending()"]
    B --> C["Saeroun list (jeongnyeoldoem)"]
    A --> D["Wonbon list-neun geudaero yujidoem"]

“Du ga-ji 가지”ga boijyo? Ige baro haeksim idea-imnida: jeongnyeol-eun deiteo cheori step이지, memory-reul deop-eo sseuneun geos-i 아닙니다.

5. ExpensePocket peurojekteu-eseo jeongnyeol

Ije jeongnyeol-eul “gongjung”eseo haneun geot-i 아니라, jageun app-ui 일부로 seol계hae boseumnida. Jichul geumaek list (MutableList<Int>)reul jeojangha-go, command-neun: jichul chuga, list 출력. 출력 모드-neun 두 가지: “chuga sunseo-daero”와 “naerimchasu-ro jeongnyeoldoeseo”.

Jichul storage

Jigeum-eun Pair나 “jichul record”ga pilyo eopseumnida — geugeon 나중-e. Oneul-eun gibon jeongnyeol-eul yeonseuphaneun geos-i moksjeok-ini, deiteoreul gajang dan순하게 gajago 갑니다.

import kotlin.system.exitProcess

fun main() {
    val expenses = mutableListOf<Int>()

    while (true) {
        print("Command (add/list/list-desc/exit): ")
        when (readln().trim()) {
            "add" -> addExpense(expenses)
            "list" -> printExpenses(expenses)
            "list-desc" -> printExpensesDesc(expenses)
            "exit" -> exitProcess(0)
        }
    }
}

Jujanghal 점: expensesneun MutableListibnida, ttara서 element-reul chuga할 su itseumnida. Hajiman report용 jeongnyeoleun sorted()/sortedDescending()ro hal geos-imnida. wonbon sunseo-reul mangchiji 않기 위해서-yo.

Jichul chuga

숫ja 입력 function-eul jageun-ge 만들-eo boseyo. Uri-neun 이미 Int parsing과 error 처리 (최소한 toIntOrNull())reul 할 줄 아니까, 간단합니다.

fun addExpense(expenses: MutableList<Int>) {
    print("Expense amount: ")
    val value = readln().trim().toIntOrNull()

    if (value == null) {
        println("Not a number; expense was not added.")
        return
    }

    expenses.add(value)
    println("Added: $value")
}

“Chuga sunseo-daero” 출력

Igeun “history” 모드입니다: list-reul 있는 그대로 보여줍니다.

fun printExpenses(expenses: List<Int>) {
    println("Expenses (as added): $expenses")
}

“Naerimchasu” 출력

Yeogi-eseo oneul juje-ga deureonamnida. Jeongnyeoldoen copy-reul mandeulgo 출력합니다. wonbon list-neun 건드리지 않습니다.

fun printExpensesDesc(expenses: List<Int>) {
    val sorted = expenses.sortedDescending()
    println("Expenses (descending): $sorted")
}

Function-eun 짧지만 의미-ga 큽니다: jeongnyeol-eun “deiteoreul bakkwo라”가 아니라 “jeongnyeoldoen view/reuse-reul mandeul-eo jwo”라는 요청입니다.

Source-reul mangchiji 않는지 hwagin하려면, jam시 debug 출력-eul chugahae-do doemnida:

fun printExpensesDesc(expenses: List<Int>) {
    val sorted = expenses.sortedDescending()

    println("Original: $expenses")
    println("Sorted: $sorted")
}

Jichul-eul 10, 5, 20 순으로 chuga하면, da-eum-gwa 비슷하게 보일 geos-imnida:

Original: [10, 5, 20]
Sorted: [20, 10, 5]

Geu-rigo ige baro “jeongsangjeog-in” app-eseo uri-ga wonhaneun dongjak-imnida.

6. Wae ttaeron jeongnyeol-i list-reul bakkun geotcheoreom 느껴질kka

Ttaeron isanghan neukkim-i deulmida: “na-neun ‘an-eseo’ jeongnyeolhan 적이 eopneunde, wae dareun 곳에서 deiteo-ga dareujyeotji?” Igeun daebucheo sorted() ttaemun-i 아니라, eodienga-eseo gateun mutable list-reul 두 개 ui ireum-euro chamjo (aliasing)hagi ttaemun-imnida. Igeun ije kkaji “value vs reference” juje-eseo iyagihaetdeon geot-gwa yeongyeol-doemnida.

sorted()ga 있으면 이런 surprise-ga 줄어드는 편입니다. saeroun list-reul banhwanhaji, “gateun list-ui view”reul dollyeojuneun geos-i 아니기 때문입니다. Kotlin munseo-eseo-do sorted()ga saeroun collection-eul saengseong한다는 jeom-eul myeonghwakhi ㅎ아고 (mutable collection-eul in-place-ro 바꾸는 작업과 대비해서) seolmyeonghamnida.

Hajiman, dangsin-i surprise-reul 직접 만들 수도 있습니다. 예를 들어:

fun main() {
    val a = mutableListOf(3, 1, 2)
    val b = a

    b.add(10)

    println(a) // [3, 1, 2, 10]
}

Igeun jeongnyeol-gwa sanggwan-eopseumnida — “두 변수, 하나의 list” 문제입니다. Geuraeseo “source-reul mutate haji 않는다” 원칙은 peurogeuraem-i keojil su록 더 좋은 boheom-i 됩니다: eonu가 eodieseo 우연히 gong-yu deiteoreul 바꿨는지에 덜 의존하게 되니까요.

List-wa deungseong(equality): sunseo-neun content-ui 일부

Jeongnyeol-eul 하면 element sunseo-ga 바뀝니다. element set-i “gateun” geotcheoreom bo-yeo-do, sunseo-neun list 내용의 일부로 취급됩니다. Ige j 중요한 이유는, 나중에 list-reul ==로 bigyohago 놀랄 su 있기 때문입니다.

Bo세요:

fun main() {
    val a = listOf(1, 2, 3)
    val b = listOf(3, 2, 1)

    println(a == b) // false
}

사람 눈에는 “gateun 숫자”일 수 있지만, list 입장에서는 “dareun sequence”입니다. 그게 논리적입니다: list는 ordered collection이니까요.

I saenggak-eun 나중에 “mueonga bakkyeotneunga an bakkyeotneunga”reul 검사하고 operation 결과를 비교할 때 도움됩니다.

7. sorted() / sortedDescending() 사용 시 jaju naneun silsu

Silsu 1: sorted()reul call-ha-go, gyeolgwa-reul sseuji 않는다.
Gajang jaju naneun 케이스입니다: xs.sorted()reul 써놓고 xsga jeongnyeoldoel geot-i라고 기대합니다. Hajiman sorted()neun saeroun list-reul banhwanhago, wonbon-eun 바꾸지 않습니다 — read-only collection jeongnyeol-ui gibon contract-imnida. Fix-neun dan순합니다: either val sorted = xs.sorted() cheoreom 저장하든가, 아니면 바로 println(xs.sorted()) 로 출력하면 됩니다.

Silsu 2: jeongnyeol-i “eotteon type-edo 당연히” dongjakhaeya 한다고 saenggak한다.
sorted()와 sortedDescending()는 natural order가 있는 element, 즉 compare 가능(sayong 가능)한 type에 맞춰져 있습니다. Kotlin이 “자체적으로” 비교할 줄 모르는 것을 정렬하려고 하면 type constraint에 걸립니다. 현 단계에서는 정상적인 신호입니다: 지금은 숫자/문자열을 정렬하고, “더 복잡한 것들을 어떻게 정렬할지”는 별도 주제입니다.

Silsu 3: jeongnyeol-gwa reverse-reul hon-dong한다.
Ttaeron sortedDescending()를 “정렬하고 뒤집기”라고 생각해서, “먼저 정렬하고, 또 한 번 정렬하고…” 같은 이상한 조합을 시도하기도 합니다. 의미는 더 단순합니다: sorted()는 오름차순, sortedDescending()는 내림차순입니다. 만약 “추가된 순서를 역순으로” 보여주기만 원한다면, 그건 완전히 다른 문제(다른 연산)이고 값 기준 정렬이 아닙니다.

Silsu 4: “최댓값/최솟값” 논리가 필요한데도 정렬을 써서 불필요한 일을 한다.
Choboja-deul-ege jaju naneun 비효율은 이렇습니다: “max가 필요하다” → “list 전체를 정렬한다” → “첫 번째를 가져온다”. 동작은 하지만, 필요한 것보다 훨씬 많은 작업을 합니다. 지금 단계에서는 최적화를 하지 않지만(이해가 더 중요하니까), “정렬은 무거운 도구”라는 사실은 알아두면 좋습니다.

Silsu 5: wonbon list-eseo “chuga sunseo”reul irheobeorin다 — eodienga-eseo in-place-ro bakkwo beoryeoseo.
Oneul sorted()reul 올바르게 써도, 주변 어딘가에서 MutableList를 바꾸는 다른 연산이 들어올 수 있습니다. Kotlin은 “saeroun gyeolgwa-reul 만든다”와 “collection state-reul 바꾼다”를 명확히 구분하며, 이 차이를 머릿속에 유지하는 게 중요합니다. 시작 단계에서의 좋은 습관은: report는 sorted()/sortedDescending()로 만들고, 원본 데이터는 element를 명시적으로 add/remove 하는 곳에서만 건드리는 것입니다.

1
과제
Kotlin SELF, 레벨 23, 레슨 1
잠금
세 점수 정렬
세 점수 정렬
1
과제
Kotlin SELF, 레벨 23, 레슨 1
잠금
게스트 목록
게스트 목록
1
과제
Kotlin SELF, 레벨 23, 레슨 1
잠금
순위 보존
순위 보존
1
과제
Kotlin SELF, 레벨 23, 레슨 1
잠금
명령 저장소
명령 저장소
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION