728x90
컬렉션 타입
- 코틀린 표준 라이브러리는 기본 컬렉션 타입인 List, Set, Map을 제공한다.
- 컬렉션은 두가지 종류로 나뉜다.
- 불변 컬렉션(Immutable) : 읽기 전용 컬렉션
- 가변 컬렉션(mutable) : 삽입, 수정, 삭제와 같은 쓰기 작업이 가능한 컬렉션

컬랙션 생성 방법
fun main() {
// immutable
val currencyList = listOf("달러", "유로", "원") //한번 생성하면, 쓰기/수정/삭제 할 수 없다
//mutable
/*
val mutableCurrencyList = mutableListOf<String>()
mutableCurrencyList.add("달러")
mutableCurrencyList.add("유로")
mutableCurrencyList.add("원")
*/
val mutableCurrencyList = mutableListOf<String>().apply {
//내부에 참조를 가지고 있어 좀 더 가독성있게 코드를 작성할 수 있다
add("달러")
add("유로")
add("원")
}
//immutable set
val numberSet = setOf(1, 2, 3, 4)
//mutable Set
val mutableNumberSet = mutableSetOf<Int>().apply {
add(1)
add(2)
add(3)
add(4)
}
//immutable map
val numberMap = mapOf("one" to 1, "two" to 2) //중위 표현식
//mutableMap
val mutableNumberMap = mutableMapOf<String, Int>()
mutableNumberMap["one"] = 1
mutableNumberMap["two"] = 2
mutableNumberMap["three"] = 3
// 컬렉션 빌더
// 컬렉션 빌더는 내부에선 mutable 반환은 immutable
val numberList: List<Int> = buildList {
//buildList 내부에서 add를 사용해 값을 넣고 있다(mutableList를 사용해 값을 넣었다는 의미) -> 반환 되는 리스트는 immutable 한 리스트로, 위에서 생성한 것과 차이가 있다.
add(1)
add(2)
add(3)
}
//linkedList
val linkedList = LinkedList<Int>().apply { //각 구현 리스트의 생성자를 통해 리스트를 생성할 수도 있다.
addFirst(3)
add(2)
addLast(1)
}
//arrayList
val arrayList = ArrayList<Int>().apply {
add(1)
add(2)
add(3)
}
}
- 표준 라이브러리 함수를 사용
| immutable | mutable | |
| 리스트 | listOf() | mutableListOf<>() |
| 셋 | setOf() | mutableSetOf<>() |
| 맵 | mapOf(key to value) | mutableMapOf<>() |
- apply를 사용해 가독성 좋게 생성할 수 있다.
- 컬렉션 빌더를 사용해 컬렉션을 생성할 수 있다.
- buildList, buildSet, buildMap 3종류 제공
- build 내부에선 Mutable, 반환할 땐, Immutable이다.
- 특정 구현체를 생성하고 싶을 경우 생성자를 사용한다.
컬렉션 반복하기
fun main() {
//iterator
val iterator = currencyList.iterator()
while (iterator.hasNext()) {
println(iterator.next())
}
println("==================")
//for 문
for (currency in currencyList) {
println(currency)
}
println("==================")
currencyList.forEach { //인라인 함수
println(it)
}
*/
//for loop -> map
val lowerList = listOf("a", "b", "c")
/*
val upperList = mutableListOf<String>()
for(lowerCase in lowerList){
upperList.add(lowerCase.uppercase())
}
*/
val upperList =
lowerList.map { it.uppercase() } //map, filter 와 같은 인라인 함수를 사용해 개발자가 직접 코드를 작성하지 않아도 된다
//println(upperList)
/*
val filterList = mutableListOf<String>()
for(upperCase in upperList){
if(upperCase == "A" || upperCase == "C"){ // a, c 만 filter를 통해 값을 넣고 싶다
filterList.add(upperCase)
}
}
*/
//val filterList = upperList.filter { it == "A" || it == "C" }
//java8 stream 과 인라인 함수의 차이 : 자바8 stream은 터미널 오퍼레이터로, 최종 연산자가 실행이 되어야지만, 실행이 되지만 코틀린은 바로 실행이 된다.
//val filterList = upperList.stream().filter { it == "A" || it == "C" }.collect(Collectors.toList())
/*
val filterList = upperList
.asSequence() //자바8의 stream()과 같은 역할을 한다고 보면된다.
.filter { it == "A" || it == "C" }
.toList() //최종적으로 toList가 실행이 되어야지 모든 연산이 실행이된다
*/
//만약 대량의 데이터를 filter를 통해 만들게 된다면, 매번 인라인 함수를 사용할 떄마다 list를 만들기 떄문에 많은 리스트에 의해 OOM이 발생할 수도 있다.
val filterList = upperList
.asSequence()
.filter { it == "A" || it == "C" }
.filter { it == "A" }
.filter { it == "A" }
.filter { it == "A" }
.filter { it == "A" }
.toList()
println(filterList)
}
- 코틀린 컬렉션은 Iteratable 구현체이므로 순차적 반복이 가능하다.
- 자바에서 foreach를 사용하면 iterable를 구현한 컬렉션을 반복할 수 있다.
- 코틀린은 for loop를 사용하면 암시적으로 이터레이터를 사용하기 때문에 좀 더 쉽게 반복할 수 있다.
- 코틀린 표준 라이브러리에는 자주 사용되는 패턴인 forEach, map, filter와 같은 인라인 함수를 제공한다.
- 자바 8 스트림과 비교
- 자바 8 스트림 : 중간 연산자(map,filter, flatMap...)만 사용했을 때는 아무런 동작하지 않고, 최종 연산자(terminal operator)를 사용해야 동작한다
- 코틀린 : 일반적인 인라인 함수가 동작할 때마다, 조건에 맞는 컬렉션을 반환하고, asSequence를 사용할 때에만, Lazy로 동작해 최종 연산자를 사용해야 동작한다.
- 일반적으로 인라인 함수가 빠르기 때문에 인라인 함수를 쓰고 대량을 데이터를 다룰때는 OOM이 발생할 수 있으므로 시퀀스 API를 사용하자.
728x90