배열 외에도 가장 자주 사용하는 자료 구조인 List, Set, Map도 공부를 안할 수 없죠. 오늘은 이것들을 어떻게 사용하는지 알아봅시다.
List
배열이 정해져있는 공간이라면, List는 삽입, 삭제 등을 할 수 있는 자료 구조 입니다...만 코틀린에서는 독특하게도 Immutable (읽기 전용) 한 리스트와 Mutable (읽기, 쓰기 가능) 한 리스트가 따로 존재하네요. 리스트엔 다양한 기능이 있겠지만, 적어도 add, addAll, remove, removeAll, removeAt, retainAll, subList 정도만 알아도 사용하는데 크게 문제는 없을 것이라고 생각합니다.
// 읽기만 가능한 리스트
listOf(1, 2, 3, 4)
// 삽입, 삭제 등이 가능한 리스트
var li1 = mutableListOf<Int>(1, 2, 3, 3, 3, 3, 4, 5, 6)
var li2 = mutableListOf<Int>(5, 6, 7, 8, 9, 10)
var li3 = mutableListOf<Int>(3, 4, 5, 6)
// 맨 뒤에 1을 추가합니다.
li1.add(1)
// 1번째에 3을 추가합니다.
li1.add(1, 3)
// 맨 뒤에 li2의 모든 원소를 추가합니다.
li1.addAll(li2)
// 0번째에 li2의 모든 원소를 추가합니다.
li1.addAll(0, li2)
// 맨 처음에 나오는 1을 제거합니다.
li1.remove(1)
// li2에 있는 모든 원소들을 찾아 전부 제거합니다.
li1.removeAll(li2)
// 0번째 원소를 제거합니다.
li1.removeAt(0)
// li1과 li3에서 공통된 원소는 냅두고 나머지는 전부 제거합니다.
li1.retainAll(li3)
// li1의 0~1번째 원소를 리스트로 묶어서 반환합니다. 즉 현재 li1 = [3, 3, 3, 3, 4]라면 -> li1 = [3, 3]이 됩니다.
// 앞의 0은 포함이고 뒤의 2는 미포함이여서 0 ~ 1입니다.
li1 = li1.subList(0, 2)
Set
set은 배열이나 List와 달리 중복되는 원소를 가지지 않는 자료 구조입니다. set도 리스트와 같이 읽기 전용의 set과 읽기, 쓰기가 가능한 set이 존재합니다. (대체 왜!) 역시 리스트처럼 삽입, 삭제 등이 가능하며 사용법은 리스트와 크게 다르지 않습니다. 이 자료구조가 무엇인지 이해한다면 크게 헷갈릴 일은 없을 것 같네요.
var s1 = setOf(1, 2, 3)
var s2 = mutableSetOf<Int>(1, 2, 3, 4)
var s3 = mutableSetOf<Int>(4, 5, 6, 7)
var s4 = mutableSetOf<Int>(7, 8, 9, 10)
// s2에 3을 추가합니다. 다만 s2에는 이미 3이 있기 때문에 중복 추가는 되지 않습니다.
s2.add(3)
// s2에 5를 추가합니다. 중복되는 원소가 없으니 추가가 됩니다.
s2.add(5)
// 중복되는 원소를 제외하고 s2에 s3의 모든 원소를 추가합니다.
s2.addAll(s3)
// s2에 s4의 모든 원소를 추가합니다.
s2.addAll(s4)
// s2에서 0이 있으면 제거합니다. (0이 없어서 그대로입니다.)
s2.remove(0)
// s2에서 1이 있으면 제거합니다.
s2.remove(1)
// s2에서 s3의 모든 원소를 제거합니다.
s2.removeAll(s3)
// s2와 s3의 공통 원소를 남기고 전부 지워줍니다.
s2.retainAll(s3)
// s2의 모든 원소를 제거합니다.
s2.clear()
Map
마지막으로 map입니다. 개인적으로 가장 많이 사용하는 자료 구조인 것 같습니다. map은 key와 value로 이루어져있는 자료 구조입니다. 예를 들어 [cat, 10마리], [dog, 5마리] 이런 식인 셈이죠. 사전의 단어 - 뜻 관계를 생각한다면 쉽게 이해할 수 있을 것입니다. 놀랍게도! 이 친구도 mutable과 immutable로 나뉘어져 있습니다. 이젠 그러려니 합시다.
var m1 = mapOf("aa" to 1, "bb" to 2, "cc" to 3)
var m2 = mutableMapOf<String, Int>("dd" to 1, "ee" to 2, "ff" to 3)
var m3 = mutableMapOf<String, Int>("gg" to 4, "hh" to 5, "ii" to 6)
// m2의 key 중 "d"의 value를 가져옵니다. 즉 1을 가져오겠죠.
m2.get("dd")
// key로 "gg", value로 10인 쌍을 m2에 추가합니다.
m2.put("gg", 10)
// key가 "dd"인 쌍을 지웁니다.
m2.remove("dd")
// m2에 m3의 모든 key-value 쌍을 추가합니다. 이 때 m2에 gg=10와 m3에 gg=4인 쌍이 각각 존재하는데, 넣어보니까
// m3의 값인 gg=4가 들어가는군요. 추가하는 것을 기준으로 값이 바뀌나 봅니다. 굳이 따지자면 자바의 map["gg"] = 4가
// 적용됐다고 볼 수 있겠네요.
m2.putAll(m3)
마치며..
오늘은 List, Set, Map에 대해서 알아 보았습니다. 다른 언어랑 비교하면서 사용해보니 개인적으론 다른 언어들이 더 편한 것 같습니다. (특히 파이썬이 제일 편한 것 같네요. 제일 오래 쓴 건 자바인데..) 다른 언어들과는 조금 느낌이 달라 어색할 수도 있을 것이라 생각하지만, 적응된다면 이것도 금방 편해질 것입니다.
아직 다른 자료 구조들도 많이 남아 있고, String은 어떻게 처리하는 지, 함수는 어떻게 쓰고 클래스는 어떻게 쓰는 지, 코틀린을 안드로이드에서 어떻게 사용하는 지 공부할 게 산더미네요. 틈 날 때마다 공부한 것을 올려보겠습니다. 다들 즐거운 코딩하세요!
댓글
댓글 쓰기