0101011001010111

Kotlin - 컬렉션/ list, set, map / listOf, setOf, mapOf / mutableListOf, ArrayList, mutableMapOf,mutableSetOf/contains/ union,intersect,subtract 본문

Kotlin/스파르타_코틀린 문법

Kotlin - 컬렉션/ list, set, map / listOf, setOf, mapOf / mutableListOf, ArrayList, mutableMapOf,mutableSetOf/contains/ union,intersect,subtract

[진주] 2023. 8. 3. 13:46
728x90
반응형

컬렉션 : 

개발에 유용한 자료구조를 제공해요.


- 코틀린에서는 리스트, 맵, 집합 자료구조를 지원해요.

- 리스트는 읽기전용과 수정가능한 종류로 구분할 수 있어요.

- 배열(array)와 달리 크기가 정해져 있지 않아 동적으로 값을 추가할 수 있어요.

 ㄴ 배열처럼 똑같이 연속적인 값을 저장할 수 있긴 하지만, 크기가 정해져 있지 않아 동적으로 값 추가가능

 ㄴ 배열같은 경우에 처음에 5개 만들었으면, 총 5개 까지만 넣을 수 있는데요.

 ㄴ Array와 달리 List는 처음에 정한 갯수보다 더 넣을 수 있어요. (동적으로)


▼ 어떻게 하는지 살펴보자.

List

fun main() {
// 읽기전용 리스트입니다
// 0번, 1번, 2번 인덱스에 접근해서 값을 변경할 수 없습니다
    var scores1 = listOf(값1, 값2, 값3)

// 수정가능 리스트입니다
// 0번, 1번, 2번 인덱스에 접근해서 값을 변경할 수 있습니다
    var scores2 = mutableListOf(값1, 값2, 값3)
    scores2.set(인덱스, 값)

// 수정가능 리스트입니다
// 0번, 1번, 2번 인덱스에 접근해서 값을 변경할 수 있습니다
// array로 데이터들을 저장하는 ArrayList도 mutableListOf와 동일하게 사용할 수 있어요
// 저장할 데이터의 자료형을 < > 안에 지정해야 사용할 수 있어요
    var scores3 = ArrayList<자료형>(값1, 값2, 값3)
    scores3.set(인덱스, 값)
}

 

var scores1 = listOf(값1, 값2, 값3)

읽기전용 리스트는 listOf

값1,값2,값3 이런 식으로 넣어서 scores1이라는 리스트를 만들었고요. 

- 읽기전용은 예를 들어, 첫번째 있는 값1을 값5로 바꾼다던가 할 수가 없어요. (읽기전용은 수정불가)

 

 

 

var scores2 = mutableListOf(값1, 값2, 값3)
scores2.set(인덱스, 값)

수정 가능 리스트 mutableListOf

mutableListOf로 값1 값2 값3을 넣고, 

바꾸려면 변수이름 ( 위에는 scores2로 되어있다.) scores2.set 메소드를 불러서 

(인덱스번호, 바꿀값) 몇번째 인덱스에, 무슨 값으로 바꾸겠다. 

하면 됩니다..

 

 

 

 

var scores3 = ArrayList<자료형>(값1, 값2, 값3)
scores3.set(인덱스, 값)

 

수정 가능 리스트 ArrayList

- mutableListof 랑 ArrayList은 똑같이 수정 가능한 리스트이긴 한데 

 ㄴ ArrayList 같은 경우에는 내부에 값들을 저장할때 nutableListOf와 다르게

 ㄴ array형태, 즉 배열형태로 차곡차곡 저장하기 때문에 우리는 실제로 코딩할 때, ArrayList라는 걸 많이 사용하게 될 거에요.

 ㄴ 사용하는 방식은 똑같습니다.

 ㄴ set써서 인텍스의 값을 수정하거나, 할 수 있습니다.


맵 Map

- 맵은 키와 값의 쌍으로 이루어진 자료형이예요.

- 읽기전용과 수정 가능한 종류로 구분 할 수 있어요.

 

▼예시 / map

fun main() {
    // 읽기전용 맵입니다
    // 변수명[키]로 데이터에 접근할 수 있습니다
    var scoreInfo1 = mapOf("kor" to 94, "math" to 90, "eng" to 92)
    println(scoreInfo1["kor"])

    // 수정가능 맵입니다
    // 변수명[키]로 데이터에 접근할 수 있습니다
    var scoreInfo2 = mutableMapOf("kor" to 94, "math" to 90)
    scoreInfo2["eng"] = 92
    println(scoreInfo2["eng"])

    // 맵의 키와 값을 동시에 추출해서 사용할 수 있습니다
    for((k,v) in scoreInfo2) {
        println("${k}의 값은 ${v}입니다")
    }
}

위 코드의 결과값.

 

읽기전용 맵 : mapOf

즉, kor라는 키에 94라는 값을 매핑을 한 거구요. // 각각 위와 같이 mapping을 해줌.

println(scoreInfo1["kor"])

그래서 kor을 프린트한 결과는 

이다.

 


수정가능한 맵 : mutableMapOf

var scoreInfo2 = mutableMapOf("kor" to 94, "math" to 90)

수정 가능한 맵도, 읽기전용과 똑같이 형식은 만든다.

// 다만 mapOf가 아니라 mutableMapOf이고 

mutable = 변할 수 있는, 잘 변하는
scoreInfo2["eng"] = 92

scoreInfo2에서 "eng"의 점수를 92점으로 추가 // 처음 지정할때 없었던 내용을 추가한 부분이다.

 

println(scoreInfo2["eng"])

그리고 출력하면,

 

가 나오게 된다.

 

 

 

for ((k, v) in scoreInfo2) {
    println("${k}의 값은 ${v}입니다")
}

map같은 부분을 for문을 돌려 어떻게 효율적으로 탐색할까요?

ㄴ 맵에 키와 값을 동시에 추출해서 사용할 수  있어요.

 

코틀린에서는 in하고 맵변수(위코드에서는 scoreInfo2)를 넣어주면,

(k,v) << 키와 값을 묶어서(순서대로) 리턴을 해주고, 

 

println("${k}의 값은 ${v}입니다")

한꺼번에 출력 가능합니다.

 

 

 

<< 출력값.

 

 


Set의 활용

- Set은 순서가 존재하지 않고 중복없이 데이터를 관리하는 집합 자료형이에요. (교집합/차집합/합집합 같은 집합자료형!)

- 읽기전용과 수정가능한 종류로 구분할 수 있어요.

- 다른 컬렉션들은 요소를 찾는데에 집중하지만, Set요소는 요소가 존재하는지에 집중해요. 

 

package com.example.myapplication


fun main() {
//  읽기전용 Set입니다.
    var birdSet = setOf("닭", "참새", "비둘기")

//  수정가능 Set입니다.
//  var mutableBirdSet = mutableSetOf("닭", "참새", "비둘기")
//  mutableBirdSet.add("꿩")
//  mutableBirdSet.remove("꿩")
    println("집합의 크기는 ${birdSet.size} 입니다")

    var findBird = readLine()!!

    if(birdSet.contains(findBird)) {
        println("${findBird} 종류는 존재합니다.")
    } else {
        println("${findBird}는 존재하지 않습니다.")
    }
}

 

var birdSet = setOf("닭", "참새", "비둘기")

 

읽기전용 setOf

읽기전용은 setOf로 만든다 ( 읽기전용은 수정 불가능)

//  수정가능 Set입니다.
//  var mutableBirdSet = mutableSetOf("닭", "참새", "비둘기")
//  mutableBirdSet.add("꿩")
//  mutableBirdSet.remove("꿩")

수정 가능 mutableSetOf

수정가능한 set은 mutableSetOf로 만들 수 있고,

요소를 추가하려면 변수이름.add(추가할거)

지우려면 변수이름.remove(지울거)

하면된다.

println("집합의 크기는 ${birdSet.size} 입니다")

집합의 크기구하기 

집합의 크기란 이 집합에 몇개의 요소가 들어있는지 확인할 수 있다.

.size를 쓴다.


var findBird = readLine()!!

if(birdSet.contains(findBird)) {
    println("${findBird} 종류는 존재합니다.")
} else {
    println("${findBird}는 존재하지 않습니다.")
}
var findBird = readLine()!!

여기서 !! <<null이 아님을 단언하는 연산자

를 쓴것은 그저 코드를 빨리 확인해보기 위함이다. (평소에 추천x)

 


 

if(birdSet.contains(findBird))

여기서 궁금한게 많을텐데.

var findBird = readLine()!!

readLine()!! 으로 입력한게 예를들어서 '꿩'이라고 쳐보자.

그럼 이 '꿩'이 findBird에 들어있고, 

var birdSet = setOf("닭", "참새", "비둘기")

birdSet에는 닭 참새 비둘기가 있는데, 

 

그럼 birdSet에 '꿩'이 있는지 contains라는 메소드로 검사를하고.

ㄴ contains도 기본기능인듯 하다. 

ㄴ contains에 대해 정리해보자 : https://vjinjoov.tistory.com/15

contains는 

Kotlin의 컬렉션 타입인 Set, List, Map 등에서 사용되는 함수 주어진 요소 해당 컬렉션에 포함되는지 확인하는 역할을 합니다.

 


5:23

교집합, 차집합, 합집합으로 간편하게 요소들을 추출할 수 있어요.

package com.example.myapplication


fun main() {
    // 귀여운 새의 집합
    var birdSet = setOf("닭", "참새", "비둘기", "물오리")

    // 날수있는 새의 집합
    var flyBirdSet = setOf("참새", "비둘기", "까치")

    // 모든 새의 집합 (합집합)
    var unionBirdSet = birdSet.union(flyBirdSet)

    // 귀엽고 날수있는 새의 집합 (교집합)
    var intersectBirdSet = birdSet.intersect(flyBirdSet)

    // 귀여운 새들중에서 날수없는 새의 조합 (차집합)
    var subtractBirdSet = birdSet.subtract(flyBirdSet)

    println("=====합집합=====")
    println("모든 새의 집합 : ${unionBirdSet}")

    println("=====교집합=====")
    println("귀엽고 날수있는 새의 집합 : ${intersectBirdSet}")

    println("=====차집합=====")
    println("귀엽고 날수없는 새의 집합 : ${subtractBirdSet}")
}

일단 먼저, 

집합을 만들때 자료구조는 이렇다.

먼저, 합집합을 보자. union

var unionBirdSet = birdSet.union(flyBirdSet)

birdSet + flyBirdset 

"닭", "참새", "비둘기", "물오리" + "참새", "비둘기", "까치"

니까, 중복된것은 1개로 합치면

= 모든 새의 집합 : [닭, 참새, 비둘기, 물오리, 까치]

가 되게 된다.

 


교집합 ( 두 집합에서 중복되는 것만 찾아내는 기능) intersect 

var intersectBirdSet = birdSet.intersect(flyBirdSet)

"닭", "참새", "비둘기", "물오리"  교집합  "참새", "비둘기", "까치"

=====교집합=====
귀엽고 날수있는 새의 집합 : [참새, 비둘기]


차집합 ( 메인집합에서 계산될 집합을 빼준다.) subtract 

birdSet - flyBirdset 

"닭", "참새", "비둘기", "물오리" - "참새", "비둘기", "까치"

=====차집합=====
귀엽고 날수없는 새의 집합 : [닭, 물오리]

 

로 결과값을 볼 수 있다.

 


이쯤 헷갈리니 한 번 더 정리.

  1. List:
    • List는 순서가 있는 컬렉션입니다. 즉, 요소들이 입력된 순서대로 유지됩니다.
    • 중복된 요소를 허용합니다. 따라서 동일한 요소가 여러 번 포함될 수 있습니다.
    • 인덱스를 사용하여 요소에 접근할 수 있습니다. 첫 번째 요소는 인덱스 0, 두 번째 요소는 인덱스 1과 같이 접근할 수 있습니다.
    • List는
    • listOf()    // 읽기전용
    • 수정가능한 것은 : mutableListOf와, ArrayList가 있는데 보통 ArrayList를 더 많이사용함 ( 왜냐면 내부의 값을 차곡차곡 저장하기 때문
  2. Set:
    • Set은 순서가 없는 컬렉션입니다. 따라서 요소들이 순서에 상관없이 저장됩니다.
    • 중복된 요소를 허용하지 않습니다. 각 요소는 유일해야 합니다.
    • Set은 주로 고유한 요소들을 관리하거나 중복을 피해야하는 상황에서 사용됩니다.
    • Set은
    • setOf()  // 읽기전용
    • mutableSetOf  //수정가능
    • 집합 : union(합집합), intersect(교집합), subtract(차집합)
  3. Map:
    • Map은 Key-Value 쌍으로 이루어진 컬렉션입니다. 각 Key는 유일해야하고, 각 Key에 해당하는 Value를 저장합니다.
    • 순서가 없으며, Key를 통해 Value에 접근할 수 있습니다.
    • Key는 중복될 수 없으며, 하나의 Key에는 하나의 Value만 매핑됩니다.
    • Map은
    • mapOf() //읽기전용
    • mutableMapOf //수정가능

간단히 말해서,

List는 순서가 있고 중복을 허용하며,

Set은 순서가 없고 중복을 허용하지 않습니다.

 

Map은 Key-Value 쌍을 사용하여 데이터를 관리하는데,

각 Key는 유일하고 중복이 없어야 하며, 각 Key에는 하나의 Value가 매핑됩니다.

 

따라서 각 컬렉션은 다른 용도와 특징을 가지고 있으며, 상황에 맞게 적절히 사용해야 합니다.

 


마지막, 정리를 위해 예제 하나만 더 보도록 하자 ▼

 

package com.example.myapplication
fun main() {
    var students = mutableListOf<Student>()
    var averages = mutableMapOf<String, Int>()

    for(idx in 0..2) {
        println("학생의 이름을 입력하세요")
        var name = readLine()!!

        println("국어 점수를 입력하세요")
        var kor = readLine()!!.toInt()

        println("수학 점수를 입력하세요")
        var math = readLine()!!.toInt()

        println("영어 점수를 입력하세요")
        var eng = readLine()!!.toInt()

        var average = (kor + math + eng) / 3
        var tempStudent = Student(name, kor, math, eng)

        students.add(tempStudent)
        averages[name] = average
    }

    for(student in students) {
        var average = averages[student.name]
        student.displayInfo()
        println("평균점수는 ${average} 입니다")
    }
}

class Student(name:String, kor:Int, math:Int, eng:Int) {
    var name:String
    var kor:Int
    var math:Int
    var eng:Int

    init {
        this.name = name
        this.kor = kor
        this.math = math
        this.eng = eng
    }

    fun displayInfo() {
        println("이름: $name")
        println("국어: $kor")
        println("수학: $math")
        println("영어: $eng")
    }
}

 

 

 

 

 

 

728x90
반응형