자바에서 리스트 내의 데이터를 필터링하거나 변환하려면 for문을 돌리면서 장황한 코드를 작성하거나 Stream API를 억지로 끼워 맞춰야 했습니다.
하지만 코틀린은 표준 라이브러리(Standard Library) 자체가 어마어마한 확장 함수들의 집합소입니다. filter, map, groupBy, any 등의 함수를 파이프라인처럼 연결하면, 복잡한 데이터 조작 로직도 단 한 줄로 우아하게 끝낼 수 있습니다.
💡 핵심 비유: 데이터 가공 파이프라인
컨베이어 벨트(리스트)에 수많은 데이터가 지나갑니다. filter는 체를 받쳐 불량품을 걸러내는 거름망 역할을 하고, map은 통과한 정상품에 포장지를 씌우거나 형태를 변환하는 가공 기계 역할을 합니다. 이 기계들을 꼬리에 꼬리를 무는 체이닝 기법으로 연결할 수 있습니다.
⚙️ filter 와 map 파이프라인 시각화
📊 자주 쓰는 강력한 컬렉션 함수들
함수명
기능 요약
반환 타입
filter { }
람다 안의 조건이 참(True)인 원소들만 살려냅니다.
List
map { }
원본 데이터를 람다식의 결과 형태(예: 객체 -> 문자열)로 변환합니다.
List
groupBy { }
특정 기준(키)으로 데이터들을 묶어 카테고리화 시켜버립니다.
Map<K, List>
data class User(val name: String, val age: Int, val city: String)
fun main() {
val users = listOf(
User("Alice", 25, "Seoul"),
User("Bob", 30, "Busan"),
User("Charlie", 25, "Seoul"),
User("David", 40, "Jeju")
)
// 1. filter 와 map 체이닝 (파이프라인)
// - filter: 나이가 30 이상인 사람만 통과시킴
// - map: 통과한 사람 객체에서 '이름(name)'만 쏙 빼서 새 리스트로 만듦
val over30Names = users.filter { it.age >= 30 }.map { it.name }
println("30세 이상 이름: " + over30Names)
// 2. groupBy (SQL의 GROUP BY와 완벽히 동일)
// 도시(city) 이름을 Key로 삼아 해당하는 유저들을 그룹으로 묶은 Map을 반환합니다.
val usersByCity: Map<String, List<User>> = users.groupBy { it.city }
// 서울을 Key로 갖는 리스트의 크기(size)를 구합니다.
println("Seoul 유저 수: " + usersByCity["Seoul"]?.size + "명")
// 3. maxByOrNull, minByOrNull
// 나이(age)를 기준으로 순회를 돌며 가장 수치가 높은 유저 객체 1개를 리턴합니다.
val oldest = users.maxByOrNull { it.age }
println("가장 나이 많은 사람: " + oldest?.name)
// 4. any, all, none (Boolean 리턴 함수들)
val hasSeoul = users.any { it.city == "Seoul" } // 서울 사는 사람이 하나라도 있는가? (true)
val allAdults = users.all { it.age >= 18 } // 싹 다 18세 이상인가? (true)
println("서울 거주자 존재? " + hasSeoul)
println("모두 성인인가? " + allAdults)
}