본문 바로가기

Study/Kotlin Study

[Kotlin] 컬렉션 타입

+ 항공대학교 김철기 교수님의 객체 지향 프로그래밍 과목 내용를 정리한 글입니다.

배열 Array

C언어의 배열과 비슷한 특성을 갖는다.

- 크기가 정해져 있다.

- 원소의 삽입, 삭제가 불가능하다.

- 원소의 대치는 가능하다. (원소 변경)

 

Java의 기본 자료형이다.

- Java와의 호환을 위해 Kotlin의 collection 관련 class를 상속 받지 않는다.

 

iterator()를 제공한다.

- for문을 통해 원소를 차례로 방문할 수 있게 한다.

fun main() {
    val arr = arrayOf("Hello", "World", "Kotlin")

    for (elem in arr) {
        println(elem)
    }
}

 

Java와의 호환 및 성능을 위해 기본 자료형 별 Array 클래스가 있다.

ex) IntArray, ByteArray 등

 

만드는 방법이 다양하다.

1. arrayOf(...)

2. Array() {}

3. intArrayOf(...), byteArrayOf(...) 등

4. IntArray(){}, ByteArray(){} 등

fun main() {
    val arr = IntArray(10) {it * it}

    for (elem in arr) {
        println(elem)
    }
}

ArrayList (kotlin.collections 패키지)

배열을이용한 MutableList이다.

- O(1)의 원소 검색/대치

- O(n)의 원소 삽입/삭제 (굉장히 번거로운 작업)

 

List란?= 순서(index)를 가지는 원소들의 집단 (Set과 반대)

 

MutableList란?= 원소의 삽입/삭제/대치가 가능한 List이다. (List의 하위 클래스)

 

Collection이란?= List (원소들의 집단)의 상위 클래스이다. (하위 클래스로 List, Set이 있다.)

 

Iterable이란?= Collection의 상위 클래스이다.

ArrayList의 상속 관계

 

< arrayListOf를 이용한 배열 생성 >

fun main() {
    val list = arrayListOf(1, 2, 3, 4, 5)

    list.add(2, 8) // 2번 인덱스에 8 삽입
    println(list.joinToString()) // 1, 2, 8, 3, 4, 5

    list.removeAt(0) // 0번 인덱스 값 삭제
    println(list.joinToString()) // 2, 8, 3, 4, 5
}

 

< ArrayList를 이용한 빈 배열 생성 >

fun main() {
    val list = ArrayList<String>(100) // String타입 원소를 저장하는 빈 ArrayList 생성
    // 추가적으로 빈 ArrayList를 생성할 때는 임으로 크기를 잡아주는 것이 좋다. ( 너무 작게 잡아서 array를 복사하는 일이 빈번해질 수 있다. )

    list.add("Hello")
    list.add("World") // 파이썬의 append와 같이 동작 (뒤에 삽입)
    list.add(1, "this")  // 1번 인덱스에 "this" 삽입
    println(list) // [Hello, this, World]
}

LinkedList (java.util 패키지)

index를 통해 방문하는데 걸리는 시간: O(n)

 

맨 앞, 맨 뒤로의 원소 삽입/삭제에 걸리는 시간: O(1)

- Stack, Queue로 활용하기 좋다.

 

import java.util.LinkedList

fun main() {
    val list = LinkedList<Int>() // 빈 LinkedList 인스턴스 생성

    list.add(1)
    list.addFirst(3) // 맨 앞에 원소 3 추가
    list.add(2) // 맨 뒤에 원소 2 추가
    println(list) // [3, 1, 2]

    list.removeLast() // 맨 뒤에 있는 원소 2 삭제
    list.removeFirst() // 맨 앞에 있는 원소 3 삭제
    println(list) // [1]
}

HashSet (kotlin.collections 패키지)

hashCode() 함수를 이용한 MutableSet이다.

- hashCode(): 내용이 같으면 같은 코드를 반환하는 함수

 

Set이란?

= 중복되지 않은 원소들의 집합

 

MutableSet이란?

= 원소의 삽입/삭제가 가능한 Set

 

HashSet의 상속 관계

원소 삽입/삭제/검색 에 걸리는 시간: O(1)

 

 LinkedHashSet을 이용하면 HashSet이면서 원소 삽입 순서대로 LinkedList를 유지할 수 있다. 

fun main() {
    val s1 = hashSetOf("apple", "orange", "mango")
    println(s1.contains("apple")) // true ("apple"이 HashSet에 들어있으므로)
    println(s1.contains("사과")) // false ("사과"가 HashSet에 들어있지 않으므로)

    println(s1) // [orange, apple, mango] (순서가 해쉬 코드에 따라 결정)

    val s2 = linkedSetOf("apple", "orange", "mango") // LinkedHashSet 생성
    println(s2) // [apple, orange, mango]

    s2.remove("orange")
    s2.add("orange")
    println(s2) // [apple, mango, orange] ("orange"가 나갔다가 들어왔기 때문에 맨 뒤에 위치)
}

TreeSet (java.util 패키지)

검색 tree를 이용한 집합이다.

 

검색(비교)를 해야하기 때문에 Comparable을 구현한 원소만 타입으로 가질 수 있다.

- compareTo(other: T) 메소드가 구현되어 있다.

- 아니면 별도의 Comparator을 제공해야한다.

 

원소의 검색/삽입/삭제에 걸리는 시간: O(log n)

 

순서 상 특정 원소 바로 앞/뒤의 원소를 검색 가능하다.

 

< 이미 Comparable이 구현된 타입(String)의 원소를갖는 TreeSet >

import java.util.TreeSet

fun main() {
    val s = sortedSetOf("apple", "orange", "mango")
    println(s) // [apple, mango, orange] (알파벳 순서)

    // 근처에 무슨 원소가 있는지 검색 가능
    println(s.lower("mango")) // apple (망고보다 작은 바로 다음 값)
    println(s.higher("mango")) // orange (망고보다 큰 바로 다음 값)
}

 

< Comparable을 직접 구현한 타입(class)의 원소를갖는 TreeSet >

import java.util.TreeSet

// toString 함수이 구현된 data class 사용
data class Person(val firstName: String, val familyName: String, val age: Int) : Comparable<Person> {
    val fullName get() = "$firstName $familyName $age"
    // age를 빼면 이름이 같고 나이가 달라도 같다고 판별하는 오류가 발생한다.

    // other의 fullname과 비교해서 크면 양수, 작으면 음수, 같으면 0을 반환하는 함수
    override fun compareTo(other: Person): Int = fullName.compareTo(other.fullName)
}

fun main() {
    val s = sortedSetOf(Person("John", "Doe", 30), Person("Jane", "Doe", 25))
    println(s) // [Person(firstName=Jane, familyName=Doe, age=25), Person(firstName=John, familyName=Doe, age=30)]
    // fullName 변수로 두 인스턴스를 비교하여 정렬하기 때문에 Jane Doe가 더 앞에 위치한다.

    // compareTo 함수에서 fullName 변수로 비교하기 때문에 같다고 출력
    println(s.contains(Person("Jane", "Doe", 25))) // true
    println(s.contains(Person("Jane", "Doe", 30))) // false
}

Map (kotlin.collections 패키지)

Map

- Key와 Value의 쌍으로 이루어진 집합이다.

- Key 검색이 잘 되도록 구성되어 있다.

- Key는 중복될 수 없다.

- Map.Entry: Key와 Value의 쌍을 나타낸다.

 

TreeMap (java.util 패키지)

- tree로 Key를 검색한다.

- TreeSet과 마찬가지로 Key값이 Comparable을 구현한 원소이어야 한다.

fun main() {
    val m = sortedMapOf(1 to "One", 2 to "Two", 3 to "Three")
    println(m) // {1=One, 2=Two, 3=Three}

    m[4] = "Four"
    m[100] = "One Hundred"
    println(m) // {1=One, 2=Two, 3=Three, 4=Four, 100=One Hundred}
    println(m[5]) // null (Key값 5에 해당하는 Value가 존재하지 않으므로)
}

 

HashMap (kotlin.collections 패키지)

- HashSet과 같은 방법으로 Key를 검색한다.

fun main() {
    val m = hashMapOf(1 to "One", 2 to "Two", 3 to "Three")
    println(m) // {1=One, 2=Two, 3=Three}

    m[4] = "Four"
    m[100] = "One Hundred"
    println(m) // {1=One, 2=Two, 3=Three, 4=Four, 100=One Hundred}
    println(m[5]) // null (Key값 5에 해당하는 Value가 존재하지 않으므로)
}

'Study > Kotlin Study' 카테고리의 다른 글

[Kotlin] 파일과 I/O 스트림  (3) 2023.11.27
[Kotlin] 컬렉션 유틸리티  (1) 2023.11.21
[Kotlin] 봉인된 클래스  (1) 2023.11.14
[Kotlin] 부호 없는 정수  (0) 2023.11.14
[Kotlin] data 클래스  (0) 2023.11.14