Kotlin에서는 데이터를 그룹화해서 효율적으로 사용할 수 있도록 Collection을 제공합니다.

 

Collection type 설명
List
MutableList
순서가 있는 값(item)들의 모음
Set
MutableSet
순서가 없는 값(item)들의 모음. Set 내에서 값(item)이 중첩될 수 없음
Map
MutableMap
key-value pair의 모음. key는 Map 내에서 unique한 값으로 오직 하나의 value로 매핑

 

각 Collection은 mutable 또는 read only 분류됩니다. 즉 변경가능한, 변경불가능한 collection입니다.

 

List

List는 순서대로 값을 저장하며, 저장되는 값이 같더라도 허용합니다.

 

읽기만 가능한 List는 listOf, 변경가능한 MutlableList는 mutableListOf로 생성할 수 있습니다.

위의 예제처럼 List는 변경할 수 없으며, 읽기만 가능합니다. 반면, MutalbleList는 값을 삭제하거나, 변경하거나, 더할 수 있습니다.

 

List는 순서가 있는 구조이기 때문에 indexed acess opertor [] 를 사용할 수 있습니다. 또한 first(), last() function을 이용해서 첫번째 혹은 마지막 값(item)에 접근할 수 있습니다. 그리고 count() funtion을 통해 저장된 값(item)의 갯수를 알 수 있습니다.

val readOnlyFruits = listOf("사과", "귤", "포도")
println("첫 번째 과일은 ${readOnlyFruits[0]}입니다.")
//첫번째 과일은 사과입니다.

println("첫 번째 과일은 ${readOnlyFruits.first()}입니다.")
//첫번째 과일은 사과입니다.

println("마지막 과일은 ${readOnlyFruits.last()}입니다.")
//첫번째 과일은 포도입니다.

println("담겨져있는 과일 종류의 수는 ${readOnlyFruits.count()}개입니다.")
//첫번째 과일은 사과입니다.

 

List안에 특정 값(item)이 포함되어있는지 확인할때는 in operator를 사용합니다.

val readOnlyFruits = listOf("사과", "귤", "포도")
println("포도" in readOnlyFruits) //포도가 있으면 true, 없으면 false
//true

 

MutableList에서 값을 더하기 위해선 add(),삭제하기 위해서는 remove()를 사용합니다.

val fruits = mutableListOf("사과", "귤", "포도")
fruits.add("딸기")
println(fruits)
//[사과, 귤, 포도, 딸기]

fruits.remove("귤")
println(fruits)
//[사과, 포도, 딸기]

 

첨언을 하자면 List, MutableList 모두 val로 선언했습니다. 왜 MutableList는 var이 아닌데 변경 가능한지 헷갈릴 수도 있습니다.

MutalbeList의 내부에 값이 변경되는 것이지 MutableList 자체가 변경되는 것이 아납니다. 다시 말해 그릇은 그대로 있고 그 안의 내용물만 바뀌는 겁니다. val로 선언한 것이 바로 그릇 MutableList이고 변경한것은 그 안의 값(item)들입니다.

아래의 예시가 적절한 예제는 아니지만 개념 이해를 돕는것으로는 도움이 될 것 같습니다.

val valFruits = mutableListOf("사과", "귤", "포도")
//valFruits = mutableListOf("사과", "귤", "포도") //ERROR!! val은 한번 생성하면 변경할 수 없는 값입니다.
    
var varFruits = mutableListOf("사과", "귤", "포도")
varFruits = mutableListOf("사과","귤","포도") //var은 변경할 수 있습니다.

 


Set

List와 유사하지만 다른점이 있다면, Set은 순서를 중요시하지 않습니다. 대신에 중첩된 값을 받아들이지 않습니다.

 

읽기만 가능한 Set은 setOf, 변경가능한 MutlableSetd은 mutableSetOf로 생성할 수 있습니다.

중복 item 정리됨

 

Set과 MutableSet은 item의 순서가 없기때문에 indexed access operator []를 사용할 수 없습니다. 주의하세요!!!

count(), add(), remove() funtion과 in operator는 List와 동일하게 사용가능합니다.


Map

Map은 key-value 쌍을 저장하는데 사용합니다. 

key에서 느껴지듯이 key 값은 Map 내에서 유일(unique)해야합니다. value는 중첩될수 있습니다.

key-value 쌍 예를 들어 보면

kbs1, 9

kbs2, 7 

mbc, 11

sbs, 6

이렇게 예를 들 수 있겠네요.

kbs1은 9번 채널, kbs2는 7번 채널, mbc는 11번 채널, sbs는 6번 채널 입니다.

그럼 이걸 어떻게 표현할까요?

Map 생성을 통해 알아보겠습니다.

 

읽기만 가능한 Map은 mapOf, 변경가능한 MutlableMap은 mutableMapOf로 생성할 수 있습니다.

예를 들어 String을 Key로하고 Int를 Value로 하는 경우 < >을 사용하여 data sturcture을 명시할 수 있습니다.

Map<String, Int>, MutableMap<String, Int>

 

가장 쉬운 key-value pair 생성 방식은 to 를 사용하는 방법입니다.

// Read-only map
val readOnlyChannel = mapOf("KBS1" to 9, "MBC" to 11, "SBS" to 5)
println(readOnlyChannel)
// {KBS1=9, MBC=11, SBS=5}

// Mutable map with explicit type declaration
val channel: MutableMap<String, Int> = mutableMapOf("KBS1" to 9, "MBC" to 11, "SBS" to 5)
println(channel)
// {apple=100, kiwi=190, orange=100}

 

List와 동일하게 Map의 value에 접근하는 방법은 indexed access operator []을 사용하는 것입니다. count()의 사용법도 List와 동일합니다. 

 

Map에서는 key-value pair 추가를 위해 put(), 삭제를 위해 remove() function을 사용합니다.

val channel = mutableMapOf("KBS1" to 9, "MBC" to 11, "SBS" to 5)
channel.put("KBS2", 7)
println(channel)
// {KBS1=9, MBC=11, SBS=5, KBS2=7}

channel.remove("SBS") // key를 사용하여 삭제
println(channel)
// {KBS1=9, MBC=11, KBS2=7}

 

Map에서 key를 포함하고 있는지 확인하는 function containsKey()를 제공합니다. 

val channel = mutableMapOf("KBS1" to 9, "MBC" to 11, "SBS" to 5)
println(channel.containsKey("MBC")) //key가 존재하면 true, 없으면 false
// true

 

Map에서 key와 value를 각각 확인할 수도 있습니다. keys와 values를 사용하여 얻을 수 있습니다.

val channel = mutableMapOf("KBS1" to 9, "MBC" to 11, "SBS" to 5)
println(channel.keys)
// [KBS1, MBC, SBS]
println(channel.values)
// [9,11,5]

 

SW사업의 투입인력 기준 대가산정을 위해 한국소프트웨어산업협회 KOSA에서 매해 공표하는 평균임금입니다.

 

[자료실]_유의사항_및_일러두기_20231219.hwp
0.01MB
[자료실]_2024년_적용_SW기술자_평균임금_공표_20231219.hwp
0.11MB
[자료실]_2024년_적용_SW기술자_평균임금_공표_20231219.xlsx
0.08MB

 

Kotlin 기본 Data Types에 대한 정리가 끝나가네요.

 

Array(배열)은 지금까지의 기본 Daya Types과는 조금 다릅니다.

Array는 Data Type보다는 Data Structure라고 표현하는 것이 맞습니다.

Array는 index와 value 쌍으로 조합된 값을 할당할 수 있는 데이터 구조를 가지고 있기 때문입니다.

 

Array in Kotlin

 

Array 생성

Array는 위에 있는 constructor를 통해서 생성할 수 있지만, 실제로는 Kotlin에서 제공하는 function들을 사용하는 것이 유용합니다.

  • arrayOf() - Array에 할당할 values를 입력하여 생성합니다.
  • arrayNulls() - Arrya size를 입력하여, 각 value가 null 인 Array를 생성합니다.
  • emptyArray() - 빈 Array를 생성합니다.
  • Array constructors - Array size와 초기화 값으로 Array를 생성합니다.

무슨 말인지 좀 어려워 보입니다. 아래 코드를 보시면 이해가 되겠지요.

//arrayOf
//1,2,3,4,5가 담긴 Array 생성
val intArray = arrayOf(1,2,3,4,5)
println(intArray.joinToString()) //joinToString()는 Array values들을 String로 반환
//출력결과: 1,2,3,4,5

//arrayOfNulls()
//size가 3이고 values가 null인 Array 생성
val nullArray: Array<Int?> = arrayOfNulls(3)
println(nullArray.joinToString())
//출력결과 null, null, null

//emptyArray
//비어있는(size 0인) Array생성
var array1 = emptyArray<String>()
var array2: Array<String> = emptyArray()

//Array constructor
//size가 5이고 초기값이 1인 Array 생성
val initArray = Array<Int>(3, {0})

 

Nested Array (중첩 배열)

Array안에 value에는 Array가 사용될 수 있습니다. 그런 경우를 Nested Array(중첩 배열)이라고 합니다.

 

// two-dimensional array
val twoDArray = Array(2) { Array<Int>(2) { 0 } }
println(twoDArray.contentDeepToString())
// [[0, 0], [0, 0]]

// three-dimensional array
val threeDArray = Array(3) { Array(3) { Array<Int>(3) { 0 } } }
println(threeDArray.contentDeepToString())
// [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]

 


Array value 접근

val oneDimArray = arrayOf(1, 2, 3) // 1차원 배열
val towDimArray = Array(2) { Array<Int>(2) { 0 } } //2차원 중첩배열

// Array value 변경
oneDimArray[0] = 10
towDimArray[0][0] = 2

println(oneDimArray[0].toString()) // 10
println(towDimArray[0][0].toString()) // 2

 

Array 비교

Array의 값들을 비교 위해서 == 혹은 !=을 사용하면 안됩니다. 두 operator는 생성된 Array(Array object(객체))가 동일한 객체를 가리키는지 여부를 확인하기때문입니다.

값을 비교하기 위해서는 Kotlin에서 제공하는 함수를 사용해야 합니다.

val array1 = arrayOf(1,2,3)
val array2 = arrayOf(1,2,3)

println(array1.contentEquals(array2))
//결과: true

array2[0] = 5
println(array1.contentEquals(array2))
//결과: false

 


Kotlin 공식문서에 따르면, 

Use arrays in Kotlin when you have specialized low-level requirements that you need to meet. For example, if you have performance requirements beyond what is needed for regular applications, or you need to build custom data structures. If you don't have these sorts of restrictions, use collections instead.

이라고 되어 있습니다.

대충 이해해보면, "특별한 성능 요구 사항이 있거나 저의하고 싶은 데이터 구조를 만들어야 하는 경우를 제외하고는 가능한 Collection을 사용하록 합니다." 정도입니다. 이유는 아래 내용으로 설명합니다.

  • Collections는 읽기 전용일 수 있으므로 더 많은 제어 기능을 제공하고 명확한 의도가 있는 강력한 코드를 작성할 수 있습니다.
  • Collections에 요소를 추가하거나 제거하는 것은 쉽습니다. 이에 비해 Array는 크기가 고정되어 있습니다. Array에서 요소를 추가하거나 제거하는 유일한 방법은 매번 새 배열을 만드는 것인데 이는 매우 비효율적입니다.
  • Collections이 구조적으로 동일한지 확인하려면 연산자(==)를 사용할 수 있습니다. 배열에는 이 연산자를 사용할 수 없습니다. 대신 배열 비교에서 자세한 내용을 읽을 수 있는 특수 함수를 사용해야 합니다.
val array1 = arrayOf(1,2,3)
val array2 = arrayOf(1,2,3)

println(array1.contentEquals(array2))
//결과: true
println(array1 == array2)
//결과: false
    
array2[0] = 5
println(array1.contentEquals(array2))
//결과: false
println(array1 == array2)
//결과: false
   
val list1 = listOf(1,2,3)
val list2 = mutableListOf(1,2,3)

println(list1 == list2)
//결과: true

list2[0] = 10
println(list1 == list2)
//결과: false

 

위 예제에서 List는 Collection의 한 구현체입니다.


Array to Collections

Collection은 interface입니다. 즉, 누군가가 상속하여 사용해야합니다. 지금 이해가 안가도 상관없습니다.

Collection에는 대표적으로 List와 Set이 있습니다. List와 Set 역시 기회가 되면 자세히 다루겠습니다.

변환은 간단합니다. Kotlin에서 toList()와 toSet() function을 제공합니다.

val simpleArray = arrayOf(1,2,3)

val simpleList:List = array.toList()

val simpleSet:Set = array.toSet()

 

Primitive-type arrays

Kotlin에서는 Boolean, Byte, Char, Double, Float, Int, Long, Short의 경우에는 primitive-type Array를 제공합니다.

혁식은 Array앞에 primitive-type을 붙이면됩니다.

BooleanArray, ByteArray, CharArray, DoubleArray, FloatArray, IntArray, LongArray, ShortArray

Array안에 Data Type이 정해진 Array로 생각하면 됩니다.

예를 들어 CharArray는 Array<Char>과 동일한 뜻으로 보면됩니다.

CharArray in Kotlin

 

위의 Array 코드와 비교해보면 다른 점은 Char로 value의 Type이 정해져 있다는 것 뿐입니다.

 

+ Recent posts