개발에 유용한 자료구조와 Collection 함수에 대해 알아보자. Collection에는 크게 List, Map, Set이 있다.
1. List (리스트)
List는 데이터가 저장되거나 삭제될 때 순서를 지키는 컬렉션 타입으로, 배열(array)과 달리 크기가 정해져있지 않기 때문에 동적으로 값을 추가할 수 있다.
index를 통해 순차적으로 진행되며, 중간 데이터가 삭제되더라도 나머지 데이터는 순서를 유지한다. 또한 포인터로 불연속적인 메모리에 접근하기 때문에 메모리 관리에 용이하다는 특징이 있다.
- 읽기전용 리스트 : listOf()
- 수정가능 리스트 : mutableListOf(), ArrayList<자료형>()
// 읽기 전용 리스트
var scores1 = listOf(값1, 값2, 값3)
scores1.size //리스트 사이즈
scores1.indexOf("값2") //값2의 index
scores1.get(2) //인덱스 2의 값
// 수정 가능 리스트
var scores2 = mutableListOf(값1, 값2, 값3)
var scores2 = ArrayList<자료형>(값1, 값2, 값3)
scores2.add("값4") //값 추가
scores2.remove("값4") //값 삭제
scores2.removeAt(1) //인덱스 1의 값 삭제
scores2.addAll(scores1) //scores1 리스트 추가
의문점) val 로 설정해도 수정이 가능한 이유?
참조값(주소) 자체는 변하지 않기 때문에 val로 선언되어있더라도 수정이 가능함
(예시(?) _ 철수집의 구성원은 들어갔다 나왔다 하지만, 집 주소가 바뀌지는 않는다.)
val arrayList = arrayListOf<Int>()
arrayList.add(10) //수정 가능
arrayList = arrayListOf<Any>() //Error (참조값이 바뀌기 때문)
2. Map (맵)
Map은 Key와 Value가 쌍으로 이루어진 자료형으로, Key는 중복이 될 수 없기 때문에 기존에 존재하는 Key로 값을 저장하면 새로운 값으로 갱신된다.
- 읽기전용 맵 : mapOf(“key” to value, “key” to value …)
- 수정가능 맵 : mutableMapOf(“key” to value, “key” to value ...)
//읽기 전용 맵
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
//Key, Value 동시 출력
for((key, value) in scoreInfo2) {
println("${key}, ${value}")
}
- Map의 자료구조 : HashMap, SortedMap, LinkedHashMap
val hashMap = HashMap<Int, String>(1 to "b", 3 to "c", 2 to "a")
println(hashMap.keys) // [1, 3, 2]
println(hashMap.values) // [b, c, a]
println(hashMap.containsKey(2)) // true
println(hashMap.containsValue("d")) // false
println(hashMap.toSortedMap()) // {1="b", 2="a", 3="c"}
3. Set (셋)
Set은 중복 데이터 없이 데이터를 관리하는 집합 자료형으로, 여러개의 값이 순서가 정해져 있지 않은 채로 저장된다. 다른 컬렉션들은 요소를 찾는데 집중하는 반면 Set은 요소의 존재여부에 집중한다는 특징이 있다.
- 읽기전용 셋 : setOf()
- 수정가능 셋 : mutableSetOf()
//읽기 전용 셋
var birdSet1 = setOf("닭", "참새", "비둘기")
//수정 가능 셋
var birdSet2 = setOf("닭", "참새")
birdSet2.add("꿩")
birdSet2.remove("꿩")
if(birdSet2.contains("꿩")) println("존재") else println("없음")
- 합집합 / 교집합 / 차집합 : union / intersect / subtract
var birdSet = setOf("닭", "참새", "비둘기", "물오리")
var flyBirdSet = setOf("참새", "비둘기", "까치")
var unionBirdSet = birdSet.union(flyBirdSet) // 합집합
var intersectBirdSet = birdSet.intersect(flyBirdSet) // 교집합
var subtractBirdSet = birdSet.subtract(flyBirdSet) // 차집합
- Set의 자료구조
HashSet (자바 HashSet 기반) : 순서와 중복된 요소를 무시하며 정렬을 지원하지 않는다는 특징이 있으며 해시값을 통해 값을 찾아내어 검색 속도가 빠르다는 장점이 있다.
SortedSet (자바 TreeSet 기반) : 오름차순으로 정렬된 상태로 반환하며 정렬에 있어 강점이 있는 자료구조이다.
LinkedSet : 각 노드가 다음 연결 노드 포인터를 가지고있어, 자료의 추가와 삭제 있어 강점이 있으며 비어있는 공간을 참조하는 방법으로 효율적인 메모리 관리가 가능하다.
val hashSet: HashSet<Int> = hashSetOf(1, 3, 2, 4)
println(hashSet) // [2, 1, 3, 4]
val sortedSet: TreeSet<Int> = sortedSetOf(1, 3, 2, 4)
println(sortedSet) // [1, 2, 3, 4]
val linkedSet: LinkedHashSet<Int> = linkedSetOf(1, 3, 2, 4)
println(linkedSet) // [1, 3, 2, 4]
4. Collection 함수
- 순회 함수
forEach(), forEachIndexed() : 각 요소에 접근하여 Value 혹은 Index, Value 반환
onEach(), onEachIndexed() : 각 요소에 접근하여 Value 혹은 Index, Value 반환. 수행한 List를 다시 반환
val list = listOf(1, 2, 3, 4)
list.forEach { println( it * 2 ) } // [2, 4, 6, 8]
list.forEachIndexed { index, value -> ... }
val onEachList = list.onEach { println( it * 2 ) } // 2468
val onEachIndexedList = list.onEachIndexed { index, value -> ... }
- 매핑 함수
map() : 모든 요소에 적용할 함수 전달. 함수의 반환값과 각 요소의 Value는 같은 자료형. (인덱스를 포함하는 mapIndexed(), null을 제외하고 특정 식을 수행하는 mapNotNull() 이 있음)
flatMap() : 모든 요소에 적용할 함수 전달. 함수의 반환값은 iterable 객체. 새로운 컬렉션 반환.
groupBy() : 입력한 식에 따라 요소를 그룹화하여 Map으로 변환
val list = listOf(1, 2, 3, 4)
val listWithNull = listOf(1, null, 2, null, 3)
val twiceList = list.map { it * 2 } // [2, 4, 6, 8]
val listWithNotNull = listWithNull.mapNotNull { it?.times(2) } // [2, 4, 6]
val listWithJ = list.flatMap { listOf(it * 3, it * 4) } // [3, 4, 6, 8, 9, 12, 12, 16]
val groupMap = list.groupBy { it % 2 == 0 } // {false=[1, 3, 5], true=[2, 4]}
- 필터링 함수
filter() : 식에 부합하는 요소를 골라내어 컬렉션 반환
filterNot() : 식에 부합하지 않은 요소를 골라내어 컬렉션 반환
filterNotNull() : null을 걸러내어 컬렉션 반환
이외에도, 원하는 자료형을 골라내는 filterIsInstance(), 인덱스를 함께 추출하는 filterIndexed(), 반환하는 filterIndexedTo() 가 있다.
val list = listOf(1, 2, 3, 4)
val listWithNull = listOf(1, null, 2, null, 3)
val twiceList = list.filter { it % 2 == 0 } // [2, 4]
val noTwiceList = list.filterNot { it % 2 == 0 } // [1, 3]
val notNullList = listWithNull.filterNotNull() // [1, 2, 3]
'안드로이드 > Kotlin' 카테고리의 다른 글
[안드로이드][Kotlin] Scope Functions (Apply, Also, Let, With, Run 함수) (0) | 2023.08.03 |
---|---|
[안드로이드][Kotlin] Null Safety 와 지연초기화 (0) | 2023.08.03 |
[안드로이드][Kotlin] 액티비티 간의 데이터 전달 (+registerForActivityResult() 사용) (1) | 2023.08.01 |
[안드로이드][Kotlin] Firebase SDK 추가 (0) | 2023.02.23 |