문제 상황
서버 통신으로 차트 데이터를 받아올 때, 데이터를 가공하면서 Map 자료구조를 사용하게 되었습니다. 그래서 Map 자료구조으로 변환하는 방법과 map으로 데이터 구조를 변경하는데 순서의 문제가 없는지 정리해봤습니다. 제가 알기로는 map은 데이터의 순서가 없고, list는 데이터의 순서가 있는데, list를 map으로 바꿨다가 다시 list로 바꾸는 경우 순서가 변경되는지를 중점으로 둔 조사입니다.
Map에서의 순서
리스트를 맵으로 변환할 때 순서의 유지는 변환 방법과 사용하는 맵의 종류에 따라 달라집니다. Kotlin에서 일반적인 Map 인터페이스는 순서를 유지하지 않습니다. 그러나 LinkedHashMap이나 SortedMap 같은 특정 타입의 맵을 사용하면 순서를 유지하거나 정렬 상태를 유지할 수 있습니다.
Kotlin에서 리스트를 맵으로 변환할 때 자주 사용되는 associate, associateWith, associateBy 함수들은 내부적으로 LinkedHashMap을 사용하여 결과를 반환합니다. 이는 LinkedHashMap이 삽입된 순서대로 요소를 유지하기 때문입니다. 반면, 일반적인 HashMap은 순서를 보장하지 않습니다.
순서를 중요시한다면, LinkedHashMap을 직접 사용하거나, 키 기반으로 정렬이 필요한 경우 SortedMap을 사용해야 합니다. 순서가 중요하지 않은 상황에서는 성능 상의 이점을 위해 HashMap을 사용할 수 있습니다.
순서를 유지하기 위한 방법
val map = list.associate { it.second }
Kotlin에서 일반적인 Map을 사용할 경우, 예를 들어 toMap()을 통해 List에서 Map으로 변환하는 경우, LinkedHashMap을 반환합니다. LinkedHashMap은 삽입 순서를 유지합니다. 하지만 만약 HashMap을 사용하거나 명시적으로 순서를 유지하지 않는 맵을 사용한다면, 순서는 유지되지 않을 것입니다.
위 코드에서 associate는 각 아이템을 키와 값의 쌍으로 변환하고, 결과적으로 LinkedHashMap을 반환하여 순서를 유지합니다.
결론
모든 Iterable 타입의 컬렉션, 즉 리스트, 셋 등에 적용되는 내용입니다.
우리가 보통 변환을 위해서 사용하는 toMap은 새 맵을 반환하며, 원래 컬렉션의 순서가 보장됩니다. 또한 만약 두 쌍 중 어느 하나라도 동일한 키를 가지면 마지막 쌍이 맵에 추가됩니다. 그리고 associate 또한 순서가 보장됩니다.
키 기반으로 정렬이 필요한 경우 SortedMap을 사용해야 합니다. 순서가 중요하지 않은 상황에서는 성능 상의 이점을 위해 HashMap을 사용할 수 있습니다.
테스트 코드
fun main() {
val list = listOf("apple", "banana", "cherry")
val hashMap = list.associateWith { it.length }.toMap(HashMap())
val hashMapToList = hashMap.toList()
println("List: $list")
println("hashMapToList: $hashMapToList")
}
// hashMapToList: [(banana, 6), (apple, 5), (cherry, 6)]
fun main() {
val list = listOf("apple", "banana", "cherry")
val linkedHashMap = list.associateWith { it.length }
val linkedHashMapToList = linkedHashMap.toList()
println("List: $list")
println("linkedHashMapToList: $linkedHashMapToList")
}
// linkedHashMapToList: [(apple, 5), (banana, 6), (cherry, 6)]
참고 링크
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-map.html
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/associate.html
'질문 정리' 카테고리의 다른 글
Compose Snackbar 알림 관리를 위한 Utils (0) | 2024.06.20 |
---|---|
Intent 정리: 문의하기 클릭 시 이메일 앱으로만 연결 (0) | 2024.06.19 |
안드로이드 알림 구현(헤드업 알림 포함) (0) | 2024.06.17 |
Compose BackHander, 앱 종료가 안되는 이유 (0) | 2024.06.05 |
State와 StateFlow 차이 (0) | 2024.05.30 |