사실 제목만큼 Map에 대한 모든걸 기록할 순 없지만.. 알고리즘 공부를 하거나 프로젝트를 할 때 항상 사용했던 Map에 대해서 뭔가 아직 이해가 부족하고 확장함수에 대해서 모르는게 많은거 같아서 정리를 해보려고한다.
key와 value(키-값 쌍)으로 저장하기 위한 Collection이다.key는 유일하며, 각 키는 하나의 값에 매핑된다.수정가능한 Map(mutable Map)과 수정이 불가능한 Map(immutable Map)이 있다.그럼 Map은 어떤 상황에 사용하면 될까?
Map은 key-value의 쌍으로 데이터를 저장하는 구조이기 때문에 key를 통해서 value에 접근할 수 있기 때문에 데이터를 빠르게 조회, 갱신, 삭제해야 하는 상황에서 유용하게 쓰일 수 있다고 한다.
또한, 특정 속성에 따라 데이터를 그룹화할 경우 특정 속성을 key로 두고 해당 그룹의 데이터를 value로 지정한다.
그럼 일단 한번 사용하는 코드를 보자
val mutableMap = mutableMapOf(1 to "one", 2 to "two", 3 to "three")
// 값 추가
mutableMap[4] = "four"
// 값 수정
mutableMap[2] = "TWO"
// 값 삭제
mutableMap.remove(1)
println("MutableMap: $mutableMap") // MutableMap: {2=TWO, 3=three, 4=four}
mutableMapOf()를 통해서 쉽게 수정가능한 Map을 만들 수 있다.
val immutableMap = mapOf(1 to "one", 2 to "two", 3 to "three")
mutableMap[4] = "four" // Error
mutableMap[2] = "TWO" // Error
mutableMap.remove(1) // Error
println("ImmutableMap: $immutableMap") // ImmutableMap: {1=one, 2=two, 3=three}
mapOf()를 통해서 쉽게 수정불가능한 Map을 만들 수 있다.
사실 내가 Map에 대해서 정리하는 가장 큰 이유중에 하나이다. Kotlin에서 Map을 내가 의도한대로 다루기 위해서는 확장 메서드를 알아둘 필요가 있다는 생각이 들어서 이번 글을 쓰게되었기 때문이다.
물론 모든 확장 메서드를 정리하는건 어렵겠지만, 내가 지금까지 썼던 메서드나 또는 앞으로 쓰게 될거같은 메서드를 몇개 정리해두려고 한다.
val mutableMap = mutableMapOf(1 to "one", 2 to "two", 3 to "three")
getOrDefault
해당 key가 map에 존재하면 매핑된 value를 반환하고 그렇지 않으면 설정한 기본값을 반환하다.
mutableMap.getOrDefault(1, "Default") // one
mutableMap.getOrDefault(4, "Default") // Default
getOrElse
해당 key가 map에 존재하면 매핑된 value를 반환하고 그렇지 않으면 람다로 설정한 기본값을 반환하다.
getOrDefault와는 다르게 람다로 설정한 기본값을 반환한다.
mutableMap.getOrElse(1) { "Default" } // one
mutableMap.getOrElse(4) { "Default" } // Default
putIfAbsent
입력한 key값이 존재하지 않는 경우에만 map에 추가한다.
mutableMap.putIfAbsent(4, "four")
mutableMap.putIfAbsent(2, "TWO")
// {1=one, 2=two, 3=three, 4=four}
getOrPut
입력한 key에 대한 값이 존재하면 해당 값을 반환하고 존재하지 않는다면 새로운 값을 추가하고 해당 값을 반환한다.
mutableMap.getOrPut(2) {"Default"} // two
mutableMap.getOrPut(4) {"Four"} // Four
// {1=one, 2=two, 3=three, 4=Four}
mapKeys
기존 map의 key를 변환하여 새로운 map을 생성
val newMap = mutableMap.mapKeys { it.key * 10 }
//newMap = {10=one, 20=two, 30=three}
mapValues
기존 map의 value를 변환하여 새로운 map을 생성
val newMap = mutableMap.mapValues { it.value.toUpperCase() }
//newMap = {1=ONE, 2=TWO, 3=THREE}
filterKeys
특정 조건을 만족하는 key만 포함하는 새로운 map 생성
val filteredMap = mutableMap.filterKeys { it % 2 != 0 }
// filteredMap = {1=one, 3=three}
filterValues
특정 조건을 만족하는 value만 포함하는 새로운 map 생성
val filteredMap = mutableMap.filterValues { it.length > 3 }
//filteredMap = {3=three}
forEach
map의 각 엔트리에 대해 지정한 액션을 수행한다.
엔트리란? map에 저장된 각 key-value쌍을 말한다.
mutableMap.forEach { (key, value) ->
println("Key: $key, Value: $value")
}
일단 이정도만 정리 해두고 만약에 내가 map을 사용하다가 새로운 함수를 쓰거나 새롭게 알게되는 함수가 있다면 추후에 다시 정리를 하던지 해야겠다.
hashMap에 관해서는 다음에 다시 공부한뒤에 정리해보도록 하겠다.
map을 공부하면서 찾아보기로는 순서가 없고, 해시 테이블 구조로 데이터를 저장한다. 이정도였는데
나중에 시간이 될 때 좀 더 공부하고 써봐야겠다.
사실 알고리즘을 공부하면서는 hashMapOf()를 더 자주 썼던거같긴한데..