2025-02-22T01:33:42

This commit is contained in:
2025-02-22 01:33:42 +09:00
parent b5f6bbb1e0
commit ee63c56f2b
9 changed files with 1451 additions and 0 deletions

183
docs/05_컬렉션.md Normal file
View File

@@ -0,0 +1,183 @@
# **코틀린 컬렉션과 스트림 API vs 자바 스트림 API**
코틀린은 자바와 마찬가지로 **리스트(List), 세트(Set), 맵(Map)** 등의 컬렉션을 제공한다. 하지만 자바와는 다르게, **컬렉션을 더욱 간결하게 다룰 수 있는 함수형 API**를 기본 제공하며, 대부분의 연산을 **람다식과 메서드 체이닝**을 통해 쉽게 수행할 수 있다.
이번 글에서는 **코틀린의 컬렉션 사용법과 자바 스트림 API와의 차이점**을 비교해보겠다.
---
## **1. 코틀린 컬렉션 기본 개념**
### **1.1. 불변(Immutable) vs 가변(Mutable) 컬렉션**
코틀린의 컬렉션은 **불변형(`listOf`, `setOf`, `mapOf`)**과 **가변형(`mutableListOf`, `mutableSetOf`, `mutableMapOf`)**으로 나뉜다.
자바에서는 `Collections.unmodifiableList()` 등을 사용해야 하지만, 코틀린에서는 기본적으로 **불변 컬렉션을 사용하도록 유도**한다.
#### **자바의 리스트 선언**
```java
List<String> immutableList = List.of("A", "B", "C"); // Java 9+
List<String> mutableList = new ArrayList<>();
mutableList.add("A");
mutableList.add("B");
```
#### **코틀린의 리스트 선언**
```kotlin
val immutableList = listOf("A", "B", "C") // 불변 리스트
val mutableList = mutableListOf("A", "B") // 가변 리스트
mutableList.add("C")
```
> **차이점 요약:**
> - **자바**: `List.of()`(불변) vs `ArrayList<>()`(가변)
> - **코틀린**: `listOf()`(불변) vs `mutableListOf()`(가변)
---
## **2. 코틀린 컬렉션 사용 예제**
### **2.1. 리스트(List)**
```kotlin
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers[0]) // 1
println(numbers.size) // 5
```
가변 리스트:
```kotlin
val mutableNumbers = mutableListOf(1, 2, 3)
mutableNumbers.add(4)
println(mutableNumbers) // [1, 2, 3, 4]
```
---
### **2.2. 집합(Set)**
```kotlin
val names = setOf("Alice", "Bob", "Charlie")
println(names.contains("Alice")) // true
```
가변 집합:
```kotlin
val mutableNames = mutableSetOf("Alice", "Bob")
mutableNames.add("Charlie")
```
---
### **2.3. 맵(Map)**
```kotlin
val userMap = mapOf("Alice" to 25, "Bob" to 30)
println(userMap["Alice"]) // 25
```
가변 맵:
```kotlin
val mutableUserMap = mutableMapOf("Alice" to 25)
mutableUserMap["Bob"] = 30
```
---
## **3. 코틀린의 스트림 API vs 자바의 스트림 API**
자바에서는 컬렉션을 처리할 때 **스트림 API(`Stream`)**를 사용해야 하지만,
코틀린은 **컬렉션 자체가 스트림 API처럼 동작**한다.
### **3.1. 자바 스트림 예제**
```java
List<String> names = List.of("Alice", "Bob", "Charlie");
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith("A"))
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(filteredNames); // [ALICE]
```
> **자바의 특징:**
> - `.stream()`을 호출해야 함
> - `.collect(Collectors.toList())`를 사용해야 리스트 반환
---
### **3.2. 코틀린 컬렉션 API 예제**
```kotlin
val names = listOf("Alice", "Bob", "Charlie")
val filteredNames = names
.filter { it.startsWith("A") }
.map { it.uppercase() }
println(filteredNames) // [ALICE]
```
> **코틀린의 특징:**
> - `stream()` 없이 컬렉션 자체에서 메서드 체이닝 가능
> - `collect()` 없이 리스트 반환
---
### **3.3. 숫자 리스트 필터링 & 변환**
#### **자바 (Stream API 사용)**
```java
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
List<Integer> evenSquares = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println(evenSquares); // [4, 16, 36]
```
#### **코틀린 (컬렉션 API 사용)**
```kotlin
val numbers = listOf(1, 2, 3, 4, 5, 6)
val evenSquares = numbers
.filter { it % 2 == 0 }
.map { it * it }
println(evenSquares) // [4, 16, 36]
```
> **차이점 요약:**
> - **자바**: `.stream()` 호출 → `filter()`, `map()` → `.collect(Collectors.toList())` 필요
> - **코틀린**: 바로 `filter()`, `map()` 사용 가능
---
## **4. 추가적인 컬렉션 함수들**
### **4.1. `forEach`**
```kotlin
val numbers = listOf(1, 2, 3)
numbers.forEach { println(it) }
```
### **4.2. `groupBy`**
```kotlin
val words = listOf("apple", "banana", "avocado", "blueberry")
val grouped = words.groupBy { it.first() }
println(grouped)
// {a=[apple, avocado], b=[banana, blueberry]}
```
### **4.3. `associateBy` (키 매핑)**
```kotlin
data class Person(val name: String, val age: Int)
val people = listOf(Person("Alice", 25), Person("Bob", 30))
val personMap = people.associateBy { it.name }
println(personMap["Alice"]) // Person(name=Alice, age=25)
```
---
## **5. 정리: 코틀린 vs 자바 스트림 API 차이점**
| 기능 | 자바 (Stream API) | 코틀린 (컬렉션 API) |
|------|----------------|----------------|
| 스트림 사용 | `.stream()` 필요 | 컬렉션 자체에서 사용 가능 |
| 리스트 반환 | `.collect(Collectors.toList())` 필요 | 자동 반환 |
| `filter()` 사용 | `filter(n -> 조건)` | `filter { it 조건 }` |
| `map()` 사용 | `map(n -> 변환)` | `map { it 변환 }` |
| 그룹핑 | `.collect(Collectors.groupingBy())` | `groupBy { it 기준 }` |
| 가변 리스트 | `new ArrayList<>()` | `mutableListOf()` |
코틀린은 **컬렉션을 더욱 직관적이고 간결하게 다룰 수 있도록 설계**되었다.
자바에서 스트림 API를 써야 하는 많은 경우를 **코틀린에서는 기본 컬렉션 함수만으로 해결**할 수 있다.
> **코틀린으로 스트림 API를 더 쉽게 다룰 수 있다는 점을 기억하자!**