본문 바로가기

공부 자료/코틀린[Kotlin]

[Atomic 24] 리스트 (feat. List / MutableList)

 

다른 객체를 담는 객체 컨테이너, List

 

 

이번 학습은 리스트에 대한 아톰이다. 자바에서는 리스트 보다는 배열은 우선으로 하여 배웠는데, 코틀린에서는 리스트를 먼저 배운다.

기본적인 컨테이너가 필요할 때 List를 사용한다고 하는데 오늘은 코틀린에서 List는 어떻게 쓰이는지 학습할 예정이다.

 

* 컨테이너 : Spring에서 말했던 컨테이너와는 다른 개념으로 데이터를 담거나 관리하는 객체를 말함

 


 

 

[ List ]

 

List

: 표준 코틀린 패키지에 포함되어 있는 것으로 import하지 않아도 사용 가능

: 표준 라이브러리 함수 listOf(), mutableListOf()가 존재

: 자기 자신을 표시할 때 각괄호([])를 사용

: 각 괄호는 인덱스를 사용해 List의 원소를 읽으며, 인덱스는 0부터 시작

(인덱스를 벗어나게 될 경우 ArrayIndexOutOfBoundException 발생)

: 타입 파라미터는 홑화살괄호(<>)를 사용

: List 타입 추론도 가능하나, List로 타입을 명시할 경우 해당 List 타입 파라미터 표시를 반드시 명시해야 함

import atomictest.eq

fun main {
	val ex1 = listOf(1,2,3,4,5) // list 초기화 및 호출
    
    var listText = ""
    for(i in ex1){
    	listText += "$i" // listText 결과 : 12345
    }
    listText eq "12345"
    
    ex1[4]  eq 5
}

 

 

 

List 연산

- list.sum() : list의 원소들의 합

- list.sorted() : 원소에 따라 정해지는 대소 비교에 따라 정렬한 새로운 List를 생성

- list.reversed() : 리스트의 원소 순서를 반대로 변경해 새로운 List를 생성

- list.first() : 맨 처음 원소 출력

- list.takeLast(n) : list의 원소 중 끝에서 n개 출력

 

* 원본 객체를 그대로 두고 새로운 객체를 만드는 경향이 존재하며, 이는 코틀린에서 계속 보임

 

import atomictest.eq

fun main(){
	val doubles = listOf(1.1, 2.2, 3.3, 4.4)
    doubles.sum() eq 11.0 // True
    
   	val strings = listOf("one", "two", "three")
    strings.sorted() eq listOf("one", "three", "two") // True
    
    strings.reversed() eq listOf("three", "two", "one") // True
    
    strings.first() eq listOf("one") // True
    
    strings.takeLast(2) eq listOf("two", "three") // True
}

 

- sorted(), reversed()가 새로운 객체를 생성하기 때문에 strings 리스트에 변화가 없음

 


[ 읽기 전용 List / 가변 List ]

읽기 전용 List

: listOf()

: 상태를 변화시키는 함수가 들어있지 않은 읽기 전용 List

* listOf의 경우 위의 List 설명과 동일하게 사용 가능하며, 아래와 같이 변경은 불가능

 

 

가변 List

: mutableListOf()

: 변경 가능 List

: 원소가 없을 경우 변수 타입 추론이 불가하기 때문에 타입 명시 필수

import atomictest.eq

fun main(){
	val list = mutableListOf<Int>() // 원소가 없을 경우 타입 명시 필수
    
    list.add(1)
    list.addAll(listOf(2,3))
    list += 4
    
    list eq listOf(1,2,3,4) // True
}

 

 

- 가변과 불변 List 사이의 상호작용

import atomictest.eq

fun getList():List<Int>{
	return mutableListOf(1,2,3)
}

fun main(){
	val list = getList() // mutableList를 List로 취급(반환 타입 지정)
    //list += 3 // 생성은 mutableList이지만 List로 반환되었기에 내용 변경 불가
}

: mutableList의 경우 List로 취급 가능하며, 이 경우 내용 변경은 불가

: 읽기 전용 List는 mutableList로 취급 불가

 

import atomictest.eq

fun main(){
	val first = mutableListOf(1)
    val second:List<Int> = first // mutableList를 List로 참조
    
    first += 2 // mutableList로 변경 가능
    // second += 3 // List로 변경 불가능
    
    second eq listOf(1,2) // first와 같은 객체를 참조하기 때문에 변경된 내용을 참조
}

: mutableList에 대한 참조를 유지했다가 가변 List에 대한 참조를 통해 원소 변경 시 읽기 전용에도 변경 내용 반영

 


[ val / var과 가변/불변 List의 조합 ]

 

+= 연산자를 쓸 경우 불변 리스트이지만 가변 리스트처럼 사용이 가능한 것 처럼 보이는 경우가 있는데,

그것은 var / val과의 조합으로 인해 불변성을 위배하고 있는 것 처럼 보일 수 있다.

 

 

1) val / var에 가변 리스트

import atomictest.eq

fun main(){
	val list1 = mutableListOf(1,2)
    var list2 = mutableListOf('a', 'b')
    
    // list가 가변이므로 수정 가능
    list1 += 3
    list2 += 'c'
    
    list1 eq listOf(1,2,3) // True
    list2 eq listOf('a', 'b', 'c') // True
}

 

: 가변 객체의 리스트이기 때문에 제자리에서 변경 가능

: 가변 객체이기 때문에 인텔리J는 val을 권장

 

 

2) val에 불변 리스트

import atomictest.eq

fun main(){
	val list1 = listOf(1,2)
    
    // list가 불변이므로 수정 불가
    //list1 += 3
    
    list1 eq listOf(1,2) // True
}

 

 

3) var에 불변 리스트

import atomictest.eq

fun main(){
    var list1 = listOf(1,2)
    
    // list가 불변이지만 수정 가능
    list1 += 3
    // 위 코드는 val newList = list1 + 3; list3 = newList; 가 된 상황
    
    list1 eq listOf(1,2,3) // True
}

 

: var로 컴파일러는 list에 재대입 가능

: 이전의 내용을 잃어버리고 list1이 수정된 것 처럼 보이지만 실상은 새로운 newLsit가 대치되면서 변경된 것

 

3번과 같이 += 키워드에 의한 동작은 다른 컬렉션에서도 마찬가지이기에 혼란을 방지할 수 있어,

이러한 혼란을 방지하기 위해 var보다는 val를 써야 하는 이유가 될 수 있음

 

 


 

[ 오늘의 학습 소감 ]

 

오늘은 List에 대해서 학습을 했는데 생각보다 많고 새로운 내용이 머리속에 들어와서인지 읽고 블로깅을 작성하면서도 시간이 꽤 걸린 것 같다. 마지막의 결론처럼 var보다는 val을 써야 하는 이유에 대해서도 다시 상기시킨 아톰이 아닐까 싶다. 코틀린 학습을 시작할 당시 var보다는 val을 쓰는 것이 좋고 앞으로는 var만 쓰이게 된다고 했었는데 List를 학습하고 이를 var/val과 함께 사용해보니 그 이유를 알게 되어 오늘의 아톰 학습 중 가장 큰 비중이지 아니었을까 싶다. (물론 list도 중요하다.) 

'공부 자료 > 코틀린[Kotlin]' 카테고리의 다른 글