# **코틀린 컬렉션과 스트림 API vs 자바 스트림 API** 코틀린은 자바와 마찬가지로 **리스트(List), 세트(Set), 맵(Map)** 등의 컬렉션을 제공한다. 하지만 자바와는 다르게, **컬렉션을 더욱 간결하게 다룰 수 있는 함수형 API**를 기본 제공하며, 대부분의 연산을 **람다식과 메서드 체이닝**을 통해 쉽게 수행할 수 있다. 이번 글에서는 **코틀린의 컬렉션 사용법과 자바 스트림 API와의 차이점**을 비교해보겠다. --- ## **1. 코틀린 컬렉션 기본 개념** ### **1.1. 불변(Immutable) vs 가변(Mutable) 컬렉션** 코틀린의 컬렉션은 **불변형(`listOf`, `setOf`, `mapOf`)**과 **가변형(`mutableListOf`, `mutableSetOf`, `mutableMapOf`)**으로 나뉜다. 자바에서는 `Collections.unmodifiableList()` 등을 사용해야 하지만, 코틀린에서는 기본적으로 **불변 컬렉션을 사용하도록 유도**한다. #### **자바의 리스트 선언** ```java List immutableList = List.of("A", "B", "C"); // Java 9+ List 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 names = List.of("Alice", "Bob", "Charlie"); List 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 numbers = List.of(1, 2, 3, 4, 5, 6); List 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를 더 쉽게 다룰 수 있다는 점을 기억하자!**