[Kotlin] Ch5-1. 컬렉션 구조와 기본

leeeha·2022년 9월 3일
0

코틀린

목록 보기
24/28
post-thumbnail

출처: https://www.boostcourse.org/mo234/lecture/154314?isDesc=false

컬렉션

컬렉션이란 자주 사용되는 기초적인 자료구조를 모아놓은 일종의 프레임워크로, 코틀린에서 표준 라이브러리로 제공된다.

cf) 프레임워크와 라이브러리의 차이점: https://cocoon1787.tistory.com/745

코틀린의 컬렉션

컬렉션의 종류로는 List, Set, Map 등이 있으며 자바와는 다르게 불변형 (immutable)과 가변형 (mutable)으로 나눠서 컬렉션을 다룰 수 있다.


컬렉션 인터페이스

다이어그램의 가장 상위에 있는 Iterable 인터페이스는 컬렉션이 연속적인 요소를 표현할 수 있게 한다.

Collection

  • Iterable로부터 확장
  • 불변형이므로 Collection으로부터 확장된 Set과 List는 읽기 전용의 컬렉션

MutableIterable, MutableCollection

  • 가변형 컬렉션을 지원하기 위해 준비된 인터페이스
  • 요소를 추가 및 삭제할 수 있다.


List

  • 순서에 따라 정렬된 요소를 가지는 컬렉션 (가장 많이 사용되는 컬렉션 중에 하나)
  • 값을 변경할 수 없는 불변형 List를 만들기 위해 헬퍼 함수인 listOf() 사용
  • 값을 변경할 수 있는 가변형을 표현하기 위해서는 mutableListOf() 사용
  • 인자는 원하는 만큼의 가변 인자를 가지도록 vararg로 선언 가능

cf) 헬퍼 함수: 객체 생성 시 요소를 직접 선언하기 보다는 특정 함수의 도움을 통해 생성


불변형 List 생성

public fun <T> listOf(vararg elements: T): List<T>

  • vararg는 가변 인자이므로 원하는 만큼 요소를 지정할 수 있다.
  • 값을 반환할 때는 List<T>를 사용
  • 형식 매개변수 T에 원하는 자료형을 지정하여 선언 (사용하지 않으면 <Any>가 디폴트여서 어떤 자료형이든 혼합하여 사용 가능)
val numbers: List<Int> = listOf(1, 2, 3, 4, 5)
val names: List<String> = listOf("one", "two", "three")

컬렉션에 접근

package chap05.section1

fun main() {
    val fruits = listOf("apple", "banana", "kiwi")
    
    for(item in fruits){
        println(item)
    }
    
    for(i in fruits.indices){ // 인덱스도 같이 출력 
        println("fruits[$i] = ${fruits[i]}")
    }
}

apple
banana
kiwi
fruits[0] = apple
fruits[1] = banana
fruits[2] = kiwi

기타 List 생성 함수

package chap05.section1

fun main() {
    val emptyList: List<String> = emptyList()
    println(emptyList) // 비어있는 리스트 

    val nonNullList: List<Int> = listOfNotNull(2, 45, 2, null, 5, null)
    println(nonNullList) // 널을 제외한 리스트  
}

[]
[2, 45, 2, 5]

val names: List<String> = listOf("one", "two", "three")
println(names.size)
println(names[0])
println(names.indexOf("two"))
println(names.contains("three"))

가변형 List 생성

public fun <T> arrayListOf(vararg elements: T): ArrayList<T>

  • 가변형 헬퍼 함수를 사용하면 손쉽게 요소를 추가 및 삭제할 수 있다.
  • arrayListOf()는 가변형 List를 생성하지만, 반환 자료형은 자바의 ArrayList
package chap05.section1

fun main() {
    val stringList: ArrayList<String> = arrayListOf("Hello", "Kotlin", "Wow")
    stringList.add("Java")
    stringList.remove("Hello")
    println(stringList)
}

[Kotlin, Wow, Java]

MutableList 인터페이스를 이용하는 헬퍼 함수

public fun <T> mutableListOf(vararg elements: T): MutableList<T>

  • 요소의 추가, 삭제, 교체를 위해 mutableListOf() 사용
  • 반환 자료형은 MutableList
package chap05.section1

fun main() {
    val mutableList: MutableList<String> = mutableListOf("Kildong", "Dooly", "Chelsu")
    mutableList.add("Ben")
    mutableList.removeAt(1)
    mutableList[0] = "Sean"
    println(mutableList)

	// 자료형의 혼합 
    val mutableListMixed = mutableListOf("Android", "Apple", 5, 6, 'X')
    println(mutableListMixed)
}

[Sean, Chelsu, Ben]
[Android, Apple, 5, 6, X]

불변형에서 가변형으로

package chap05.section1

fun main() {
    val names: List<String> = listOf("one", "two", "three")
    val mutableNames = names.toMutableList() // 새로운 가변형 리스트 생성 
    mutableNames.add("four")
    println(mutableNames)
}

리스트의 요소를 변경할 일이 별로 없으면, 불변형으로 사용하는 것이 더 안전하다.


List와 배열의 차이

  • Array 클래스에 의해 생성되는 배열 객체는 내부 구조상 고정된 크기를 가진다. (불변형)
  • 코틀린의 List<T>와 MutableList<T>는 인터페이스로 설계되어 있고 이것을 하위에서 특정한 자료구조로 구현한다. 즉, 고정된 크기의 메모리가 아니기 때문에 자료구조에 따라 늘리거나 줄이는 것이 가능하다.
val list1: List<Int> = LinkedList<Int>()
val list2: List<Int> = ArrayList<Int>() 

cf) 배열과 달리, 연결 리스트는 메모리 상에 데이터들이 연속적으로 위치하지 않는다. 연결 리스트의 각 노드는 포인터로 연결되어 있다.

  • Array<T>는 제네릭 관점에서 상하위 자료형 관계가 성립하지 않는 무변성이다.
  • List<T>는 공변성이기 때문에 List<Int>가 List<Number>에 지정될 수 있다.

cf) 무변성과 공변성?

profile
꾸준히!

0개의 댓글