Kotlin에서 컬렉션 사용

1. 소개

대부분의 앱에서는 연락처, 설정, 검색 결과 등의 데이터를 목록으로 표시합니다.

46df844b170f4272.png

그러나 지금까지 작성한 코드에서는 화면에 표시되는 숫자나 텍스트 등 단일 값으로 구성된 데이터로 대부분 작업했습니다. 임의적인 양의 데이터가 포함된 앱을 빌드하려면 컬렉션을 사용하는 방법을 알아야 합니다.

컬렉션 유형(데이터 구조라고도 함)을 사용하면 일반적으로 동일한 데이터 유형인 여러 값을 체계적인 방식으로 저장할 수 있습니다. 컬렉션은 순서가 지정된 목록이거나 고유한 값을 그룹화한 것, 또는 한 가지 데이터 유형의 값을 다른 데이터 유형의 값에 매핑한 것일 수 있습니다. 컬렉션을 효과적으로 사용하는 기능을 통해 목록 스크롤과 같은 Android 앱의 일반적인 기능을 구현할 수 있을 뿐 아니라 임의의 양의 데이터가 관련된 다양한 실제 프로그래밍 문제를 해결할 수 있습니다.

이 Codelab에서는 코드에서 여러 값을 사용하는 방법을 설명하고 배열, 목록, 세트, 맵을 비롯한 다양한 데이터 구조를 소개합니다.

기본 요건

  • 클래스, 인터페이스, 제네릭 등 Kotlin의 객체 지향 프로그래밍에 관한 기본 지식

학습할 내용

  • 배열을 만들고 수정하는 방법
  • ListMutableList를 사용하는 방법
  • SetMutableSet를 사용하는 방법
  • MapMutableMap을 사용하는 방법

필요한 항목

  • Kotlin 플레이그라운드에 액세스할 수 있는 웹브라우저

2. Kotlin의 배열

배열이란 무엇인가요?

배열은 프로그램에서 임의의 수의 값을 그룹화하는 가장 간단한 방법입니다.

태양 전지판 그룹화를 태양 전지 배열이라고 하거나 Kotlin 학습으로 프로그래밍 경력의 여러 배열의 가능성이 열리는 것처럼 Array값이 두 개 이상인 것을 나타냅니다. 특히 배열은 모두 동일한 데이터 유형을 보유한 값의 시퀀스입니다.

33986e4256650b8b.png

  • 배열에는 요소 또는 때로는 항목이라고 하는 값이 여러 개 포함되어 있습니다.
  • 배열의 요소는 순서가 지정되고 색인으로 액세스됩니다.

색인이란 무엇일까요? 색인은 배열의 요소에 상응하는 정수입니다. 색인은 배열의 시작 요소로부터 항목까지의 거리를 알려줍니다. 이를 0 기반 색인이라고 합니다. 배열의 첫 번째 요소는 색인 0에 있고 두 번째 요소는 색인 1에 있습니다. 첫 번째 요소에서 한 위치 떨어져 있기 때문입니다.

bb77ec7506ac1a26.png

기기 메모리에서는 배열의 요소가 서로 나란히 저장됩니다. 기본적인 세부정보는 이 Codelab에서 다루지 않지만 두 가지 중요한 의미가 있습니다.

  • 색인을 통해 배열 요소에 빠르게 액세스할 수 있습니다. 색인을 통해 배열의 임의 요소에 액세스할 수 있으며 다른 임의의 요소에 액세스하는 데도 거의 같은 시간이 걸릴 것으로 예상할 수 있습니다. 이것이 배열에 임의의 액세스가 있다고 하는 이유입니다.
  • 배열의 크기는 고정되어 있습니다. 즉, 이 크기를 초과하여 배열에 요소를 추가할 수는 없습니다. 100 요소 배열에서 색인 100에 있는 요소에 액세스하려고 하면 예외가 발생합니다. 가장 높은 색인이 99이기 때문입니다(첫 번째 색인은 1이 아니라 0임). 그러나 배열의 색인에서 값은 수정할 수 있습니다.

코드에서 배열을 선언하려면 arrayOf() 함수를 사용하세요.

69e283b32d35f799.png

arrayOf() 함수는 배열 요소를 매개변수로 사용하고 전달된 매개변수와 일치하는 유형의 배열을 반환합니다. 지금까지 본 다른 함수와 약간 다를 수도 있습니다. arrayOf()의 매개변수가 다양하기 때문입니다. 인수 두 개를 arrayOf()에 전달하면 결과 배열에는 0과 1로 색인이 생성된 두 요소가 포함됩니다. 인수 세 개를 전달하면 결과 배열에는 요소 3개가 포함되며 0~2로 색인이 생성됩니다.

태양계를 간단히 탐사하여 실제 배열을 살펴보겠습니다.

  1. Kotlin 플레이그라운드로 이동합니다.
  2. main()에서 rockPlanets 변수를 만듭니다. arrayOf()를 호출하여 네 가지 문자열과 함께(태양계의 각 행성에 하나씩) String 유형을 전달합니다.
val rockPlanets = arrayOf<String>("Mercury", "Venus", "Earth", "Mars")
  1. Kotlin은 유형 추론을 사용하므로 arrayOf()를 호출할 때 유형 이름을 생략해도 됩니다. rockPlanets 변수 아래에 꺾쇠괄호로 유형을 전달하지 않고 다른 변수 gasPlanets를 추가합니다.
val gasPlanets = arrayOf("Jupiter", "Saturn", "Uranus", "Neptune")
  1. 배열을 사용하면 멋진 작업을 할 수 있습니다. 예를 들어 숫자 유형 Int 또는 Double과 마찬가지로 두 배열을 함께 추가할 수 있습니다. solarSystem이라는 새 변수를 만들고 더하기(+) 연산자를 사용하여 rockPlanetsgasPlanets의 결과와 같게 설정합니다. 결과적으로 rockPlanets 배열의 요소와 gasPlanets 배열의 요소가 모두 포함된 새 배열이 생성됩니다.
val solarSystem = rockPlanets + gasPlanets
  1. 프로그램을 실행하여 이렇게 작동하는지 확인합니다. 아직 출력은 표시되지 않습니다.

배열 요소에 액세스

색인으로 배열 요소에 액세스할 수 있습니다.

1f8398eaee30c7b0.png

이를 아래 첨자 문법이라고 하며 다음 세 부분으로 구성됩니다.

  • 배열 이름
  • 여는 대괄호([) 및 닫는 대괄호(])
  • 대괄호 안에 있는 배열 요소의 색인

색인으로 solarSystem 배열의 요소에 액세스해 보겠습니다.

  1. main()에서 solarSystem 배열의 각 요소에 액세스하여 출력합니다. 첫 번째 색인은 0이고 마지막 색인은 7인 점에 유의하세요.
println(solarSystem[0])
println(solarSystem[1])
println(solarSystem[2])
println(solarSystem[3])
println(solarSystem[4])
println(solarSystem[5])
println(solarSystem[6])
println(solarSystem[7])
  1. 프로그램을 실행합니다. 요소의 순서는 arrayOf()를 호출할 때 나열한 순서와 같습니다.
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune

배열 요소의 값을 색인으로 설정할 수도 있습니다.

9469e321ed79c074.png

색인에 액세스하는 것은 이전과 같습니다. 즉, 배열 이름 뒤에 색인이 포함된 여는 대괄호와 닫는 대괄호가 있습니다. 여기서 그 뒤에 할당 연산자(=)와 새 값이 나옵니다.

solarSystem 배열의 값을 수정하는 방법을 연습해 보겠습니다.

  1. 미래의 인간 정착자를 위해 화성에 새 이름을 부여해 보겠습니다. 색인 3의 요소에 액세스하여 "Little Earth"와 같게 설정합니다.
solarSystem[3] = "Little Earth"
  1. 색인 3의 요소를 출력합니다.
println(solarSystem[3])
  1. 프로그램을 실행합니다. 배열의 네 번째 요소(색인 3에 있음)가 업데이트됩니다.
...
Little Earth
  1. 이제 과학자들이 해왕성 너머에서 명왕성이라는 9번째 행성을 발견했다고 가정해 보겠습니다. 앞서 배열의 크기는 조절할 수 없다고 언급했습니다. 크기를 조절하려고 하면 어떻게 될까요? Pluto를 solarSystem 배열에 추가해 보겠습니다. 색인 8에 Pluto를 추가합니다. 이 색인이 배열의 9번째 요소이기 때문입니다.
solarSystem[8] = "Pluto"
  1. 코드를 실행합니다. ArrayIndexOutOfBounds 예외가 발생합니다. 배열에 이미 요소 8개가 있으므로 당연히 9번째 요소는 추가할 수 없습니다.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 8 out of bounds for length 8
  1. 배열에 추가한 Pluto를 삭제합니다.

삭제 코드

solarSystem[8] = "Pluto"
  1. 배열을 지금보다 크게 만들려면 새 배열을 만들어야 합니다. 다음과 같이 newSolarSystem이라는 새 변수를 정의합니다. 이 배열은 요소를 8개가 아닌 9개 저장할 수 있습니다.
val newSolarSystem = arrayOf("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto")
  1. 이제 색인 8에 있는 요소를 출력해 봅니다.
println(newSolarSystem[8])
  1. 코드를 실행하고 예외 없이 실행되는지 살펴봅니다.
...
Pluto

아주 좋습니다. 배열을 알아봤으므로 컬렉션을 사용하여 거의 모든 작업을 할 수 있습니다.

단, 주의할 점이 있습니다. 배열은 프로그래밍의 기본적인 관점 중 하나이지만 요소를 추가 및 삭제해야 하거나 컬렉션의 고유성이 필요하거나 객체를 다른 객체에 매핑해야 하는 작업에 배열을 사용하는 것은 그렇게 간단하지 않으며 앱의 코드가 금방 복잡해질 것입니다.

따라서 Kotlin을 비롯한 대부분의 프로그래밍 언어에서는 실제 앱에서 흔히 발생하는 상황을 처리하기 위해 특수 컬렉션 유형을 구현합니다. 다음 섹션에서는 세 가지 일반적인 컬렉션인 List, Set, Map을 알아봅니다. 일반적인 속성과 메서드를 알아보고 이러한 컬렉션 유형을 사용하는 상황도 알아봅니다.

3. 목록

목록은 순서가 지정되고 크기 조절이 가능한 컬렉션으로, 일반적으로 크기 조절 가능한 배열로 구현됩니다. 배열이 용량까지 채워졌는데 새 요소를 삽입하려고 하면 배열이 더 큰 새 배열에 복사됩니다.

a4970d42cd1d2b66.png

목록을 사용하면 특정 색인의 다른 요소 사이에 새 요소를 삽입할 수도 있습니다.

a678d6a41e6afd46.png

목록은 이런 방식을 통해 요소를 추가하고 삭제할 수 있습니다. 대부분의 경우 목록에 있는 요소 수와 관계없이 어떤 요소든 목록에 추가하는 데는 동일한 시간이 소요됩니다. 가끔씩 새 요소의 추가로 인해 배열이 정의된 크기를 초과하게 되는 경우 새 요소를 위한 공간을 확보하기 위해 배열 요소가 이동해야 할 수 있습니다. 목록이 이 모든 작업을 실행하지만 내부적으로는 필요할 때 새 배열로 교체되는 배열일 뿐입니다.

ListMutableList

Kotlin에서 볼 수 있는 컬렉션 유형은 인터페이스를 하나 이상 구현합니다. 이 단원 앞부분의 제네릭, 객체, 확장 프로그램 Codelab에서 알아봤듯이 인터페이스는 클래스에서 구현할 속성 및 메서드의 표준 세트를 제공합니다. List 인터페이스를 구현하는 클래스는 List 인터페이스의 모든 속성과 메서드의 구현을 제공합니다. 이는 MutableList의 경우에도 마찬가지입니다.

그렇다면 ListMutableList의 기능은 무엇일까요?

  • List는 순서가 지정된 읽기 전용 항목 컬렉션과 관련된 속성과 메서드를 정의하는 인터페이스입니다.
  • MutableList는 요소 추가 및 삭제와 같이 목록을 수정하는 메서드를 정의하여 List 인터페이스를 확장합니다.

이러한 인터페이스는 List 또는 MutableList의 속성과 메서드만 지정합니다. 각 속성과 메서드의 구현 방법을 결정하는 것은 이를 확장하는 클래스입니다. 위에서 설명한 배열 기반 구현을 대부분(항상은 아니라도) 사용하겠지만 Kotlin을 사용하면 다른 클래스에서 ListMutableList를 확장할 수 있습니다.

listOf() 함수

arrayOf()와 마찬가지로 listOf() 함수는 항목을 매개변수로 사용하지만 배열이 아닌 List를 반환합니다.

  1. main()에서 기존 코드를 삭제합니다.
  2. main()에서 listOf()를 호출하여 solarSystem이라는 행성 List를 만듭니다.
fun main() {
    val solarSystem = listOf("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune")
}
  1. List에는 목록에 있는 요소의 수를 가져오는 size 속성이 있습니다. solarSystem 목록의 size를 출력합니다.
println(solarSystem.size) 
  1. 코드를 실행합니다. 목록의 크기는 8이어야 합니다.
8

목록의 요소에 액세스

배열과 마찬가지로 아래 첨자 문법을 사용하여 List에서 특정 색인의 요소에 액세스할 수 있습니다. get() 메서드를 사용하여 동일한 작업을 할 수 있습니다. 아래 첨자 문법 및 get() 메서드는 Int를 매개변수로 사용하고 이 색인에 있는 요소를 반환합니다. Array와 마찬가지로 ArrayList도 0 기반 색인이므로 예를 들어 네 번째 요소는 색인 3에 있습니다.

  1. 아래 첨자 문법을 사용하여 색인 2의 행성을 출력합니다.
println(solarSystem[2])
  1. solarSystem 목록에서 get()을 호출하여 색인 3의 요소를 출력합니다.
println(solarSystem.get(3))
  1. 코드를 실행합니다. 색인 2의 요소는 "Earth"이고 색인 3의 요소는 "Mars"입니다.
...
Earth
Mars

색인으로 요소를 가져오는 것 외에도 indexOf() 메서드를 사용하여 특정 요소의 색인을 검색할 수도 있습니다. indexOf() 메서드는 지정된 요소(인수로 전달됨)를 목록에서 검색하여 처음으로 일치하는 요소의 색인을 반환합니다. 목록에 요소가 없으면 -1이 반환됩니다.

  1. solarSystem 목록에서 indexOf()를 호출하여 "Earth"를 전달하는 결과를 출력합니다.
println(solarSystem.indexOf("Earth"))
  1. indexOf()를 호출하여 "Pluto"를 전달하고 그 결과를 출력합니다.
println(solarSystem.indexOf("Pluto"))
  1. 코드를 실행합니다. 요소가 "Earth"와 일치하므로 색인 2가 출력됩니다. "Pluto"와 일치하는 요소가 없으므로 -1이 출력됩니다.
...
2
-1

for 루프를 사용하여 목록 요소 반복

함수 유형과 람다 표현식에 관해 알아볼 때 repeat() 함수를 사용하여 코드를 여러 번 실행하는 방법을 확인했습니다.

프로그래밍에서 일반적인 작업은 목록의 각 요소에 한 번씩 작업을 실행하는 것입니다. Kotlin에는 간결하고 읽기 쉬운 문법으로 이를 처리하는 for 루프라는 기능이 포함되어 있습니다. 흔히 목록을 순환하거나 목록을 반복하는 것을 지칭합니다.

f11277e6af4459bb.png

목록을 순환하려면 for 키워드 뒤에 여는 괄호와 닫는 괄호 순으로 사용합니다. 괄호 안에는 변수 이름, in 키워드, 컬렉션 이름을 차례로 포함합니다. 닫는 괄호 뒤에는 여는 중괄호와 닫는 중괄호가 있습니다. 여기에는 컬렉션의 각 요소에 실행할 코드를 포함합니다. 이를 루프의 본문이라고 합니다. 이 코드가 실행될 때마다 이를 반복이라고 합니다.

in 키워드 앞에 있는 변수는 val 또는 var로 선언되지 않으며 get-only로 간주됩니다. 원하는 이름을 지정할 수 있습니다. 목록에 복수형 이름(예: planets)이 부여되면 변수 이름은 일반적으로 단수형(예: planet)으로 지정됩니다. 변수 이름을 item 또는 element로 지정하는 것도 일반적입니다.

이는 컬렉션의 현재 요소(첫 번째 반복의 경우 색인 0의 요소, 두 번째 반복의 경우 색인 1의 요소 등)에 상응하는 임시 변수로 사용되며 중괄호 내에서 액세스할 수 있습니다.

이를 실제로 확인해 보려면 for 루프를 사용하여 각 행성 이름을 별도의 줄에 출력합니다.

  1. main()에서 가장 최근 println() 호출 아래에 for 루프를 추가합니다. 괄호 안에서 변수의 이름을 planet으로 지정하고 solarSystem 목록을 순환합니다.
for (planet in solarSystem) {
}
  1. 중괄호 안에서 println()을 사용하여 planet 값을 출력합니다.
for (planet in solarSystem) {
    println(planet)
}
  1. 코드를 실행합니다. 루프 본문 내의 코드는 컬렉션의 각 항목에 실행됩니다.
...
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune

목록에 요소 추가

컬렉션의 요소를 추가, 삭제, 업데이트하는 기능은 MutableList 인터페이스를 구현하는 클래스에서만 사용할 수 있습니다. 새로 발견된 행성을 추적하고 있다면 목록에 자주 요소를 추가할 수 있는 이 기능이 있는 것이 좋습니다. 요소를 추가하거나 삭제하려는 목록을 만들 때 listOf() 대신 mutableListOf() 함수를 구체적으로 호출해야 합니다.

add() 함수에는 두 가지 버전이 있습니다.

  • 첫 번째 add() 함수는 목록에 있는 요소 유형의 단일 매개변수를 보유하고 이를 목록 끝에 추가합니다.
  • 다른 버전의 add()에는 매개변수가 두 개 있습니다. 첫 번째 매개변수는 새 요소를 삽입해야 하는 색인에 해당합니다. 두 번째 매개변수는 목록에 추가되는 요소입니다.

예를 보면서 살펴보겠습니다.

  1. listOf() 대신 mutableListOf()를 호출하도록 solarSystem의 초기화를 변경합니다. 이제 MutableList에 정의된 메서드를 호출할 수 있습니다.
val solarSystem = mutableListOf("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune")
  1. 명왕성을 행성으로 분류할 수도 있습니다. solarSystem에서 add() 메서드를 호출하여 "Pluto"를 단일 인수로 전달합니다.
solarSystem.add("Pluto")
  1. 일부 과학자들은 지구와 충돌하여 달을 형성하기 전에 테이아라는 행성이 존재했다고 설명합니다. "Earth""Mars" 사이의 색인 3"Theia"를 삽입합니다.
solarSystem.add(3, "Theia")

특정 색인의 요소 업데이트

아래 첨자 문법을 사용하여 기존 요소를 업데이트할 수 있습니다.

  1. 색인 3의 값을 "Future Moon"으로 업데이트합니다.
solarSystem[3] = "Future Moon"
  1. 아래 첨자 문법을 사용하여 색인 39의 값을 출력합니다.
println(solarSystem[3])
println(solarSystem[9])
  1. 코드를 실행하여 출력을 확인합니다.
Future Moon
Pluto

목록에서 요소 삭제

요소는 remove() 또는 removeAt() 메서드를 사용하여 삭제됩니다. remove() 메서드에 요소를 전달하거나 removeAt()을 사용하여 색인으로 요소를 삭제할 수 있습니다.

요소를 삭제하는 두 가지 메서드를 모두 실제로 살펴보겠습니다.

  1. solarSystem에서 removeAt()을 호출하여 색인에 9를 전달합니다. 이렇게 하면 목록에서 "Pluto"가 삭제됩니다.
solarSystem.removeAt(9)
  1. solarSystem에서 remove()를 호출하여 "Future Moon"을 삭제할 요소로 전달합니다. 그러면 목록이 검색되고 일치하는 요소가 발견되면 삭제됩니다.
solarSystem.remove("Future Moon")
  1. List는 요소가 목록에 있는 경우 Boolean을 반환하는 contains() 메서드를 제공합니다. "Pluto"에 관해 contains()를 호출한 결과를 출력합니다.
println(solarSystem.contains("Pluto"))
  1. 좀 더 간결한 문법은 in 연산자를 사용하는 것입니다. 요소, in 연산자, 컬렉션을 사용하여 요소가 목록에 있는지 확인할 수 있습니다. in 연산자를 사용하여 solarSystem"Future Moon"이 포함되어 있는지 확인합니다.
println("Future Moon" in solarSystem)
  1. 코드를 실행합니다. 두 문 모두 false를 출력해야 합니다.
...
false
false

4. 세트

세트는 특정 순서가 없고 중복 값을 허용하지 않는 컬렉션입니다.

9de9d777e6b1d265.png

이와 같은 컬렉션이 가능한 이유는 무엇일까요? 비결은 해시 코드입니다. 해시 코드는 Kotlin 클래스의 hashCode() 메서드에서 생성된 Int입니다. Kotlin 객체의 반고유 식별자로 생각할 수 있습니다. 객체를 약간만 변경해도(예: String에 문자 하나를 추가) 해시 값은 크게 달라집니다. 두 객체가 동일한 해시 코드를 가질 수 있지만(해시 충돌이라고 함) hashCode() 함수를 사용하면 다른 두 값이 대부분 각각 고유한 해시 코드를 가지는 일정 수준의 고유성이 보장됩니다.

84842b78e78f2f58.png

세트에는 중요한 두 가지 속성이 있습니다.

  1. 세트에서 특정 요소를 검색하는 것은 목록과 비교할 때 특히 큰 컬렉션의 경우 빠릅니다. ListindexOf()는 일치 항목이 발견될 때까지 각 요소를 처음부터 확인해야 하지만 첫 번째 요소인지 십만 번째 요소인지 관계없이 요소가 세트에 있는지 확인하는 데는 평균적으로 동일한 시간이 걸립니다.
  2. 세트는 같은 양의 데이터에 목록보다 더 많은 메모리를 사용하는 경향이 있습니다. 세트의 데이터보다 더 많은 배열 색인이 필요한 경우가 많기 때문입니다.

세트의 장점은 고유성을 보장한다는 것입니다. 새로 발견한 행성을 추적하는 프로그램을 작성했다면 세트는 행성이 이미 발견되었는지 확인하는 간단한 방법을 제공합니다. 데이터 양이 많으면 요소가 목록에 있는지 확인하는 것보다(모든 요소를 반복해야 함) 이 방법이 더 좋은 경우가 많습니다.

ListMutableList와 마찬가지로 SetMutableSet가 모두 있습니다. MutableSetSet를 구현하므로 MutableSet를 구현하는 모든 클래스에서 둘 다 구현해야 합니다.

691f995fde47f1ff.png

Kotlin에서 MutableSet 사용

이 예에서는 MutableSet를 사용하여 요소를 추가하고 삭제하는 방법을 보여줍니다.

  1. main()에서 기존 코드를 삭제합니다.
  2. mutableSetOf()를 사용하여 solarSystem이라는 행성 Set를 만듭니다. 그러면 기본 구현이 LinkedHashSet()MutableSet가 반환됩니다.
val solarSystem = mutableSetOf("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune")
  1. size 속성을 사용하여 세트의 크기를 출력합니다.
println(solarSystem.size)
  1. MutableList와 마찬가지로 MutableSet에는 add() 메서드가 있습니다. add() 메서드를 사용하여 solarSystem 세트에 "Pluto"를 추가합니다. 추가되는 요소에 관한 단일 매개변수만 사용됩니다. 세트의 요소의 순서가 꼭 지정되는 것은 아니므로 색인이 없습니다.
solarSystem.add("Pluto")
  1. 요소를 추가한 후 세트의 size를 출력합니다.
println(solarSystem.size)
  1. contains() 함수는 단일 매개변수를 사용하고 지정된 요소가 세트에 포함되어 있는지 확인합니다. 포함되어 있으면 true를 반환합니다. 포함되어 있지 않으면 false를 반환합니다. contains()를 호출하여 "Pluto"solarSystem에 있는지 확인합니다.
println(solarSystem.contains("Pluto"))
  1. 코드를 실행합니다. 크기가 증가하여 이제 contains()true를 반환합니다.
8
9
true
  1. 앞에서 언급한 것처럼 세트에는 중복 값이 포함될 수 없습니다. "Pluto"를 다시 추가해 보세요.
solarSystem.add("Pluto")
  1. 세트의 크기를 다시 출력합니다.
println(solarSystem.size)
  1. 코드를 다시 실행합니다. "Pluto"는 이미 세트에 있으므로 추가되지 않습니다. 이번에는 크기가 증가하지 않습니다.
...
9

remove() 함수는 단일 매개변수를 사용하고 지정된 요소를 세트에서 삭제합니다.

  1. remove() 함수를 사용하여 "Pluto"를 삭제합니다.
solarSystem.remove("Pluto")
  1. 컬렉션 크기를 출력하고 contains()를 다시 호출하여 "Pluto"가 여전히 세트에 있는지 확인합니다.
println(solarSystem.size)
println(solarSystem.contains("Pluto"))
  1. 코드를 실행합니다. "Pluto"가 더 이상 세트에 없고 크기는 이제 8입니다.
...
8
false

5. 맵 컬렉션

Map은 키와 값으로 구성된 컬렉션입니다. 고유 키가 다른 값에 매핑되므로 맵이라고 합니다. 키와 그에 수반되는 값을 key-value pair라고도 합니다.

8571494fb4a106b6.png

맵의 키는 고유합니다. 하지만 맵의 값은 그렇지 않습니다. 다른 두 키가 동일한 값에 매핑될 수 있습니다. 예를 들어 "Mercury"에는 위성이 0개 있고 "Venus"에도 위성이 0개 있습니다.

맵에서 키로 값에 액세스하는 것이 일반적으로 indexOf()를 사용하는 등 큰 목록을 검색하는 것보다 더 빠릅니다.

맵은 mapOf() 또는 mutableMapOf() 함수를 사용하여 선언할 수 있습니다. 맵에는 쉼표로 구분된 두 가지 일반 유형(키에 하나, 값에 하나)이 필요합니다.

affc23a0e1f2b223.png

맵은 초깃값이 있으면 유형 추론을 사용할 수도 있습니다. 맵을 초깃값으로 채우기 위해 각 키-값 쌍은 키, to 연산자, 값 순으로 구성됩니다. 각 쌍은 쉼표로 구분됩니다.

2ed99c3391c74ec4.png

맵을 사용하는 방법과 몇 가지 유용한 속성 및 메서드를 자세히 살펴보겠습니다.

  1. main()에서 기존 코드를 삭제합니다.
  2. 다음과 같은 초깃값이 포함된 mutableMapOf()를 사용하여 solarSystem이라는 맵을 만듭니다.
val solarSystem = mutableMapOf(
    "Mercury" to 0,
    "Venus" to 0,
    "Earth" to 1,
    "Mars" to 2,
    "Jupiter" to 79,
    "Saturn" to 82,
    "Uranus" to 27,
    "Neptune" to 14
)
  1. 목록 및 세트와 마찬가지로 Map은 키-값 쌍의 수를 포함하는 size 속성을 제공합니다. solarSystem 맵의 크기를 출력합니다.
println(solarSystem.size)
  1. 아래 첨자 문법을 사용하여 추가 키-값 쌍을 설정할 수 있습니다. "Pluto" 키를 5 값으로 설정합니다.
solarSystem["Pluto"] = 5
  1. 요소를 삽입한 후 크기를 다시 출력합니다.
println(solarSystem.size)
  1. 아래 첨자 문법을 사용하여 값을 가져올 수 있습니다. "Pluto" 키의 위성 수를 출력합니다.
println(solarSystem["Pluto"])
  1. get() 메서드를 사용하여 값에 액세스할 수도 있습니다. 아래 첨자 문법을 사용하든 get()을 호출하든 전달하는 키가 맵에 없을 수 있습니다. 키-값 쌍이 없으면 null이 반환됩니다. "Theia"의 위성 수를 출력합니다.
println(solarSystem.get("Theia"))
  1. 코드를 실행합니다. 명왕성의 위성 수가 출력됩니다. 그러나 테이아는 맵에 없으므로 get()을 호출하면 null이 반환됩니다.
8
9
5
null

remove() 메서드는 지정된 키가 있는 키-값 쌍을 삭제합니다. 지정된 키가 맵에 없는 경우 삭제된 값 또는 null도 반환합니다.

  1. remove()를 호출하고 "Pluto"를 전달한 결과를 출력합니다.
solarSystem.remove("Pluto")
  1. 항목이 삭제되었는지 확인하려면 크기를 다시 출력합니다.
println(solarSystem.size)
  1. 코드를 실행합니다. 맵의 크기는 항목 삭제 후 8입니다.
...
8
  1. 아래 첨자 문법이나 put() 메서드는 이미 존재하는 키의 값을 수정할 수도 있습니다. 아래 첨자 문법을 사용하여 목성의 위성을 78로 업데이트하고 새로운 값을 출력하세요.
solarSystem["Jupiter"] = 78
println(solarSystem["Jupiter"])
  1. 코드를 실행합니다. 기존 키("Jupiter")의 값이 업데이트됩니다.
...
78

6. 결론

축하합니다. 프로그래밍에서 가장 기본적인 데이터 유형 중 하나인 배열과 List, Set, Map 등 배열에 기반하여 빌드된 편리한 여러 컬렉션 유형을 알아봤습니다. 이러한 컬렉션 유형을 사용하면 코드에서 값을 그룹화하고 정리할 수 있습니다. 배열과 목록을 사용하면 색인으로 요소에 빠르게 액세스할 수 있는 반면 세트와 맵은 해시 코드를 사용하여 컬렉션의 요소를 더 쉽게 찾을 수 있도록 합니다. 향후 앱에서 이러한 컬렉션 유형이 자주 사용되는 것을 확인할 수 있으며 사용 방법을 알면 향후 프로그래밍 경력에 도움이 될 것입니다.

요약

  • 배열은 동일한 유형의 순서가 지정된 데이터를 저장하고 크기가 고정되어 있습니다.
  • 배열은 다른 여러 컬렉션 유형을 구현하는 데 사용됩니다.
  • 목록은 크기 조절이 가능하고 순서가 지정된 컬렉션입니다.
  • 세트는 순서가 지정되지 않은 컬렉션이며 중복 값을 포함할 수 없습니다.
  • 맵은 세트와 유사하게 작동하고 지정된 유형의 키와 값 쌍을 저장합니다.

7. 자세히 알아보기