본문 바로가기
Kotlin

[ Kotlin ] Map & Pair

by 중곰 2021. 12. 30.
  • 학습 내용
    • Map
    • Pair
  • 학습 목적
    • Key , Value로 데이터를 저장하거나 파리미터로 전달하고 싶을때 적절한 방법을 찾기 위함

Map

  • Map은 Key와 Value로 구성되어있는 dictionary 형태입니다.
  • Key, Value에 한번 지정된 타입은 불변
  • But, Key와 Value는 다른 타입이 가능

  • Key 중복 불가하여 동일한 Key Value를 추가하면 가장 마지막에 선언된 Value값이 저장하게됨

 

// key : String, value : Int
val menu = mapOf("김치찌개" to 7500, "된장찌개" to 7500, "된장찌개" to 8500)
println(menu["김치찌개"])
println(menu.get("된장찌개"))
println(menu.getOrDefalut("순두부찌개",9000))
// 결과 : 7500
// 결과 : 8500
// 결과 : 9000
  • Map 에 접근할때 List와 비슷하다. List는 Index를 넣어줘야하지만, Map은 Key를 넣어야 그에 해당하는 Value가 나옵니다.
  • 만약, 존재하지 않은 Key를 넣을때 null을 반환하는데 이때, 안전한 프로그래밍을 위해서 getOrDefault() 함수 사용 가능합니다. 해당 함수는 Map에 Key, Value가 추가되는것이 아닌 출력을 반환하기 위한 목적으로 사용합니다.
  • 위의 Map은 추가 및 변경을 하지 못합니다. mutableMapOf 를 통해 값을 추가하거나 변경 가능합니다.
  • 여기서 잠깐 !!! HasMap은 MutableMap 인터페이스를 상속받은 구현체입니다.
 val menu = mutableMapOf("김치찌개" to 7500, "된장찌개" to 7500, 
                                                 "차돌순두부찌개" to 8500)
 menu.put("부대찌개" to 8000) // or menu += "부대찌개" to 8000
 println(menu)
 //  결과 : {김치찌개=7500, 된장찌개=7500, 차돌순두부찌개=8500, 부대찌개=8000}
 menu["김치찌개"] = 8000
 println(menu)
 //  결과 : {김치찌개=8000, 된장찌개=7500, 차돌순두부찌개=8500, 부대찌개=8000}
 println(menu + Pair("라면", 3500))
 //  결과 : {김치찌개=8000, 된장찌개=7500, 차돌순두부찌개=8500, 부대찌개=8000, 라면=3500}
 println(menu + setOf("떡라면" to 4000, "치즈라면" to 4000))
 //  결과 : {김치찌개=8000, 된장찌개=7500, 차돌순두부찌개=8500, 부대찌개=8000, 라면=3500
 //           , 떡라면=4000, 치즈라면=4000}
  • Map에 값을 추가 할때 put()과 다른 Collection과 같이 += 연산자를 사용 가능합니다.
  • put() 을 사용할때 이미 Key가 있는 경우 Value가 없데이트 됩니다. 따라서, put()은 추가, 변경이 모두 가능합니다.
  • Map은 단순히 값만 추가할 수도 있지만 다른 Collection를 Map에 추가 가능합니다.
  • Pair()은 Map과 같이 key-value 형태를 가진 함수로 key와 value를 쌍으로 갖기 때문에 Map에 추가 가능
println(setOf("떡라면" to 4000, "치즈라면" to 4000))
	// 결과 : [(떡라면, 4000),(치즈라면, 4000)]
  • Set의 데이터를 저렇게 쌍으로 선언되면 Set 내부적으로 괄호 안에 두 데이터가 저장됩니다. 이는 이차원을 의미하는것이 아닌 하나의 데이터가 Key / Value 형태로 저장된다는걸 의미하며 List 에서도 같은 형식으로 저장 가능합니다.
  • 마지막으로 Map을 생성하기 위한 mapOf stlib에서 아래와 같이 나와있습니다.

  • Map 관련 추가 공부할 내용 URL

  • Pair
    • Map과 동일하게 Key,Value로 이루어져 있으며 다른점은 pair first, second는 모두 value를 뜻합니다.
    • Pair은 코틀린의 표준 라이브러리 클래스로 두 원소로 이러진 순서쌍을 표현합니다.
    • Pair은 동일하거나 다른 데이터 유현의 두 값을 저장하거나 반환하는데 사용합니다. 두 값 사이에는 관계가 있을수도 있고 없을수도 있습니다. 동일하거나 다른 데이터 형이 될 수 있습니다.
 //	Parameters 
 //  A - type of the first value 
 //  B - type of the second value

  data class Pair<out A, out B> : Serializable

 

  • Pair 생성
  • Pair 의 생성자에 전달하면 간단하게 Pair 클래스 객체가 만들어지게 됩니다.

 

val mPair : Pair<Int, String> = Pair(1, "one")
println(mPair.first) // 1
println(mPair.seconde) // "one"

val (number, name) = 1 to "one" //Destructuring Declarations
println(number) // 1
println(name) // "one"
  • pair을 만들때 보통 to라는 infix 함수를 이용하여 생성합니다.

 

/**
 * Creates a tuple of type [Pair] from this and [that].
 *
 * This can be useful for creating [Map] literals with less noise, 
 * for example:
 * @sample samples.collections.Maps.Instantiation.mapFromPairs
 */

 public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that) fun 
 <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
  • infix 함수란 2개의 변수 가운데 오는 함수를 말합니다. 여기서의 to를 보면 제네릭으로 인자를 받고 이루어져 있고 Pair 인스턴스를 반환하게 됩니다.
  • Destructuring Declarations이란?
    • 객체를 여러 변수로 분해
    • 한번에 여러 변수를 만들수 있고 새로운 2가지 변수를 독립적으로 사용할 수 있음을 나타냄
    • pair의 first, pair의 second로 접근하는 것보다 가독성이 있을것 같음
  • Pair 객체에서도 toString()과 같은 일반적인 메서드를 사용 할 수 있습니다.
val pair = Pair("I am a String", listOf(1,2,3))
print(pair.toString())
// 결과 : (I am a String, [1, 2, 3])
  • Pair 객체에서 copy 메서드를 이용할 때 값을 변경할 수도 있지만 변경되는 데이터 형은 기존과 변경 없이 동일해야 합니다.
val pair = Pair("I am a String", listOf(1,2,3))
print(pair)
// 결과 : (I am a String, [1, 2, 3])

val anotherPair = pair.copy(first = "I am new String")
print(anotherPair)
// 결과 : (I am new String, [1, 2, 3])
  • toList 메서드를 사용하여 Pair 객체를 List로 변환한 다음 List의 인덱스를 사용하여 값을 가져오거나 다른 작업을 수행할 수도 있습니다.
val pair = Pair("I am a String", 10)
val list = pair.toList()
    
println(list[0]) // I am a String
println(list.get(1)) // 10

 

 

반응형