Kotlin (2) 콜렉션, 열거형, 분기
저번 시간에는 함수, 변수, 클래스 정의에 대하여 공부하였었다.
오늘은 그 함수와 변수를 더 다양하게 정의하는 방법이나, 목록으로 정의된 변수에 대해 일괄 처리하는 방법에 대해 공부하겠다.
이후에 나오는 코드들은 Kotlin Playground에서 직접 입력하고, 실행하며 학습하면 도움이 된다!
바로 본론으로 넘어가겠다.
Kotlin
☝ Collection
Collection은 우리가 알던 배열과 비슷한 종류의 것들을 모두 총칭하는 단어이다.
Collection의 정의는 “목록형 데이터를 처리하는 자료구조“를 뜻한다.
Kotlin에서는 Collection을 여러가지 방법으로 선언할 수 있다.
기본적으로 List, Set, Map의 세 가지가 있으며, 더욱 세세한 분류로 나눌 수도 있다.
모든 배열은 읽기/쓰기가 가능한 가변형mutable type과, 읽기/쓰기가 불가능한 불변형immutable type로 분류가 가능하다.
각각을 간단히 알아보고, 하위 주제에서 예시를 통해 다루겠다.
- List
- 순서가 중요한 가변 크기의 배열을 의미한다.
listOf()
로 선언 시 불변형mutableListOf()
형으로 선언하여 가변형으로 선언 가능.
- 순서가 중요한 가변 크기의 배열을 의미한다.
- Set
- 순서가 없고, 중복을 허용하지 않음.
setOf()
로 선언 시 불변형mutableSetOf()
형으로 선언하여 가변형으로 선언 가능.
- 순서가 없고, 중복을 허용하지 않음.
- Map
- 데이터를 key-value 쌍 형식으로 저장한다.
- key는 항상 유일함.
mapOf()
로 선언 시 불변형mutableMapOf()
형으로 선언하여 가변형으로 선언 가능.
정도가 될 것이다.
1.1 List
List의 가장 큰 특징은, 순서가 존재한다는 것이다.
Kotlin
fun main() {
val weekDays = listOf("Sun","Mon","Tue","Wed","Thu","Fri","Sat")
print(weekDays)
}
Result
[Sun, Mon, Tue, Wed, Thu, Fri, Sat]
이런 형식으로 불변형 List를 선언할 수 있다.
이런 식으로 List를 선언하면, weekDays
의 변수형은 List<String>
이 된다.
List는 순서가 존재하기 때문에, index를 이용해 값을 호출할 수 있다.
다른 언어들과 비슷하게 첫 번째 원소의 index는 0부터 시작한다.
Kotlin
fun main() {
val weekDays: List<String> = listOf("Sun","Mon","Tue","Wed","Thu","Fri","Sat")
print(weekDays[0]+", "+weekDays[5])
}
Result
Sun, Fri
불변형이 아닌, 가변형 List를 만들고 싶다면, listOf
대신에 mutableListOf
를 사용하면 된다.
이 때의 변수형 역시 List<String>
이 아닌, MutableList<String>
가 된다.
Kotlin
fun main() {
var weekDays: MutableList<String> = mutableListOf("Sun", "Mon", "Tue", "Wed", "Thu")
weekDays.add("Fri")
weekDays.add("Sat")
weekDays.add("Foo")
println(weekDays)
weekDays.remove("Foo")
println(weekDays)
}
Result
[Sun, Mon, Tue, Wed, Thu, Fri, Sat, Foo]
[Sun, Mon, Tue, Wed, Thu, Fri, Sat]
mutableList의 경우는, add와 remove를 통해 List에 item을 추가하거나, 제거할 수 있다.
만약 remove를 index를 이용해서 하고싶다면, weekDays.remove(item)
가 아닌 weekDays.removeAt(index)
를 사용하면 된다.
1.2 Set
Set의 가장 큰 특징은, 순서가 존재하지 않는다는 것이다.
순서가 존재하지 않는다는 뜻은, 아래 예제를 통해 알아보자.
Kotlin
fun mix(cl1: String, cl2: String) = if (setOf(cl1, cl2) == setOf("espresso","water")) "americano" else "wtf"
fun main() {
println("espresso + water = "+mix("espresso","water"))
println("water + espresso = "+mix("water","espresso"))
print("water + milk \t = "+mix("water","milk"))
}
Result
espresso + water = americano
water + espresso = americano
water + milk = wtf
위처럼, 물+에스프레소던, 에스프레소+물이던 잘 만들어지는 아메리카노 같은 경우에 set이 자주 사용된다. 물에 우유를 섞은 것은 별로 먹고싶지 않다;;
List와 마찬가지로, 빈 set을 가변형으로 선언하고 set에 add하는 식으로 사용할 수 있다.
Kotlin
fun main() {
var someSet = setOf('1','2')
print(someSet[0])
}
Result
ERROR : No get method providing array access
하지만, set은 순서를 가지지 않는 collection이므로, someSet[0]
같은 index를 활용한 접근은 불가능하다.
Kotlin
fun main() {
var someSet = mutableSetOf('1','2','3')
someSet.add('1')
print(someSet)
}
Result
[1, 2, 3]
또한 set은 중복되는 아이템을 가질 수 없으므로, 중복되는 원소를 input하면 원래 있던 아이템 위에 씌워진다고 생각하면 된다.
1.3 Map
map의 가장 큰 특징은 key-value 쌍으로 이루어진 데이터라는 점이다.
Kotlin
fun main() {
var myCafe = mapOf(1 to "espresso", 10 to "water", 100 to "milk", 11 to "americano", 101 to "cafe latte", 110 to "wtf")
print(myCafe)
print(myCafe[1])
}
Result
{1=espresso, 10=water, 100=milk, 11=americano, 101=cafelatte, 110=wtf}
espresso
위와 같은 형식으로, "espresso"
라는 값에 1
이라는 키를 할당하는 형식으로 구성된다.
map의 index로 key를 입력하면, key에 해당하는 value가 return된다.
Kotlin
fun main() {
var myCafe = mapOf(1 to "espresso", 1 to "water")
print(myCafe)
}
Result
{1=water}
키는 반드시 유일한 값이어야 한다. 만약 동일한 키에 대한 값을 2번 할당하면, 더 나중에 할당된 값이 키에 할당된다.
Kotlin
var myCafe = mapOf(1 to "espresso", 10 to "water",
100 to "milk", 11 to "americano",
101 to "cafe latte", 110 to "wtf")
fun mix(key1: Int, key2: Int) {
println("${myCafe[key1]} + ${myCafe[key2]} = ${myCafe[key1+key2]}")
}
fun main() {
mix(1, 10)
mix(100, 1)
mix(100, 10)
}
Result
espresso + water = americano
milk + espresso = cafe latte
milk + water = wtf
위 코드는 2가지 재료의 키를 입력하면, 재료를 섞어 완성품을 만드는 코드다.
이런식으로, 키 값끼리는 서로 더해서 다른 키 값을 구할 수도 있다.
🤞 열거형Enum과 분기When
2.1 if문
if문을 사용하면 조건에 따라 원하는 값을 쉽게 받아낼 수 있다.
Kotlin에서 if문은 expression값을 반환하는 형태이기 때문에, 타 언어보다 조금 더 간결하게 사용할 수 있다.
Kotlin
fun main() {
val weekdays = listOf("Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday", "Friday", "Saturday")
var answer = mutableListOf<String>()
weekdays.map{
var item = if (it == "Sunday" || it == "Saturday") "weekend" else "weekday"
answer.add(item)
}
for (i in weekdays.indices) {
println("${weekdays[i]} is ${answer[i]}")
}
}
Result
Sunday is weekend
Monday is weekday
Tuesday is weekday
Wednesday is weekday
Thursday is weekday
Friday is weekday
Saturday is weekend
위 코드에서 가장 중요한 부분은 아래와 같다.
var item = if (it == "Sunday" || it == "Saturday") "weekend" else "weekday"
answer.add(item)
if문이 it
map을 수행하는 weekdays의 각 원소에 따라서 weekend
, weekday
를 return하는 expression이기 때문에, item
이라는 변수에 직접 할당할 수 있다.
이는 다른 언어보다 굉장히 직관적이고 간단한 형태로, Kotlin의 강점중 하나다.
2.2 열거형Enum
enum은 간단히 말해 데이터 보따리같은 느낌이다.
예시를 보며 어떤 느낌인지 이해해보자.
Kotlin
enum class WeekDays(val cnt: Int) {
Sunday(0), Monday(1), Tuesday(2), Wednesday(3),
Thursday(4), Friday(5), Saturday(6); // enum 마지막은 ; 필수
fun isWeek() = if (cnt == 0 || cnt == 6) "Weekend" else "Week"
}
fun main() {
println(WeekDays.Monday.isWeek())
print(WeekDays.Saturday.isWeek())
}
Result
Week
Weekend
Weekdays
라는 보따리 안에, 일~토요일 까지의 데이터를 넣어주었다.
각 데이터는 0~6까지 멤버 변수를 가지고, 멤버 변수가 0이나 6이면 주말을 의미하도록 isWeek()
함수를 정의하였다.
열거형의 데이터에 .
을 통해 isWeek()
함수를 사용하면 주말인지 평일인지 알 수 있는 식으로 작동한다.
2.3 분기When
When
은 if문이 많이 필요한 상황에 사용되며, 다른 언어의 switch
와 같은 역할을 한다.
입력되는 값들을 미리 분류하고, 해당 분류에 따른 값을 return한다.
When구문을 이용하면 enum에서 설명한 isWeek()
를 다른 방법으로도 표현할 수 있다.
예시로 확인해보자.
Kotlin
fun isWeekend(week: String) =
when (week) {
"Sunday", "Saturday" -> "Weekend"
"Friday" -> "Fire Friday"
else -> "Weekdays"
}
fun main() {
println(isWeekend("Sunday"))
println(isWeekend("Friday"))
print(isWeekend("Tuesday"))
}
Result
Weekend
Fire Friday
Weekdays
이 경우는 if문이 적어서 비효율적으로 보일 수 있지만, if문이 복잡해지거나 길어질수록 when문이 진가를 발휘한다.
when은 확장성도 뛰어나고, 예외 처리도 가능하다는 장점이 있다.
2.4 When의 인자로 Enum 사용
언급했던 Enum 역시 When의 인자로 사용 가능하다.
앞의 두 예제를 묶어서 이해해보자.
Kotlin
enum class WeekDays(val cnt: Int) {
Sunday(0), Monday(1), Tuesday(2), Wednesday(3),
Thursday(4), Friday(5), Saturday(6);
}
fun isWeekend(week: WeekDays) =
when (week) {
WeekDays.Sunday, WeekDays.Saturday -> "Weekend"
WeekDays.Friday -> "Fire Friday"
else -> "Weekdays"
}
fun main() {
println(isWeekend(WeekDays.Sunday))
println(isWeekend(WeekDays.Friday))
print(isWeekend(WeekDays.Tuesday))
}
Result
Weekend
Fire Friday
Weekdays
When의 인자로 Enum을 받는 것도 가능하다.
🍀 마치며
기본적으로 존재하는 자료구조에 대해서는 대충 다뤘고, 대간단히 반복문에 대해서도 짚어보았다.
다음 시간에는 코틀린에서 사용되는 반복문에 대하여 다루어보려고 한다.
오늘 배운 내용과, 그 정도만 알고있어도 사실 프로그래머스나 백준같은 적당한 난이도의 알고리즘 문제를 작성하는데는 문제가 없는 수준이라고 생각한다.
참고한 블로그 : https://tourspace.tistory.com/64
댓글남기기