- 필터와 맵
- 다양한 컬렉션 처리 기능
- List를 Map으로
- 중첩된 컬렉션 처리
1 . 필터와 맵
| 1. filter 2. filterIndexed 3. map 4. mapIndexed 5. mapNotNull |
package fp
import java.security.Principal
fun main() {
val fruits = listOf (
Fruit(1, "apple", 500, 1_000),
Fruit(2, "banana", 800, 1_500),
Fruit(3, "apple", 800, 1_500)
)
val apples = fruits.filter {f -> f.name == "apple"}
// 필터에서 인덱스가 필요한 경우
val apple2 = fruits.filterIndexed { idx, fruit ->
println(idx) // 0, 1, 2
fruit.name == "apple"
}
// 필터된 대상의 다른 프라퍼티 값 가져오기
val apple3 = fruits.filter { f -> f.name == "apple"}
.map { fruit -> fruit.currentPrice }
println(apple3) // [1000, 1500]
// 맵 결과 중 특정 인덱스와 같이 가져오기
val apple4 = fruits.filter { f -> f.name == "apple"}.mapIndexed {
idx, f ->
println("idx = $idx") // idx = 0, 1
f.currentPrice
}
println(apple4) // [1000, 1500]
// 맵 결과 null이 아닌것만 들고오기
val apple5 = fruits.filter { fruit -> fruit.name == "ddd" }
.mapNotNull(Fruit::currentPrice)
println("null 이면? $apple5") // null 이면? []
}
data class Fruit (
val id: Long,
val name: String,
val factoryPrice: Long,
val currentPrice: Long,
) {
}
※ 람다 이용
fun main() {
val fruits = listOf (
Fruit(1, "apple", 500, 1_000),
Fruit(2, "banana", 800, 1_500),
Fruit(3, "apple", 800, 1_500)
)
filterFruits(fruits) {fruit -> fruit.name == "apple"}
}
fun filterFruits(
fruit: List<Fruit>,
filter: (Fruit) -> Boolean
) : List<Fruit> {
return fruit.filter(filter)
}
2 .다양한 컬렉션 처리 기능
fun main() {
val fruits = listOf (
Fruit(1, "apple", 500, 1_000),
Fruit(2, "banana", 800, 1_500),
Fruit(3, "apple", 800, 1_700)
)
fruits.all {f -> f.name == "apple"} // false (모두 만족 true)
fruits.none {f -> f.name == "melon"} // true (모두 불충족 true)
fruits.any {f -> f.name == "banana"} // true (하나라도 만족하면 true)
fruits.count() // 3 list의 size()와 같음
fruits.sortedBy {f -> f.currentPrice} // 오름차순 정렬
fruits.sortedByDescending {f -> f.currentPrice} // 내림차순 정렬
fruits.distinctBy { f -> f.name}.map {f -> f.currentPrice} // 특정 컬럼 기준 중복 제거
fruits.first {f -> f.name == "banana"} // Fruit(id=2, name=banana, ...) - null허용 안함
fruits.firstOrNull() {f -> f.name == "melon"} // null (null 허용함)
fruits.last {f -> f.name == "apple"} // Fruit(id=3, name=apple, ...) - null허용 안함
fruits.lastOrNull() {f -> f.name == "melon"} // null (null 허용)
}
3 . List를 Map으로
- groupBy : List의 element를 Key로 이용하고 싶은 Map을 만들고 싶을 때
fun main() {
val fruits = listOf (
Fruit(1, "apple", 500, 1_000),
Fruit(2, "banana", 800, 1_500),
Fruit(3, "apple", 800, 1_700)
)
val map: Map<String, List<Fruit>> = fruits.groupBy { fruit -> fruit.name }
print(map)
}
[출력결과]
{apple=[Fruit(id=1, name=apple, factoryPrice=500, currentPrice=1000), Fruit(id=3, name=apple, factoryPrice=800, currentPrice=1700)]
, banana=[Fruit(id=2, .......]}
▶ mysql의 GroupBy와 결과가 유사하다.
- associateBy : 그룹핑 안하고 List의 특정 컬럼을 Key로 만들어 Map으로 변경할 때 (매개값에 단일 객체가 들어감)
val map: Map<Long, Fruit> = fruits.associateBy { fruit -> fruit.id }
print(map)
[출력결과]
{1=Fruit(id=1, name=apple, factoryPrice=500, currentPrice=1000),
2=Fruit(id=2, name=banana, factoryPrice=800, currentPrice=1500),
3=Fruit(id=3, name=apple, factoryPrice=800, currentPrice=1700)}
| ※ 함수형 파라미터를 2개 이상 받는 경우에는 소괄호 () 안에 중괄호 {}를 넣어줘야된다 |
- groupBy를 하되 그룹핑한 값(Key) 중 특정 컬럼 값만 value로 뽑아내고 싶을 때
val map: Map<String, List<Long>> = fruits.groupBy (
{fruit -> fruit.name}, // Key
{fruit -> fruit.factoryPrice} // Value
)
print(map) // {apple=[500, 800], banana=[800]}
- 위 코드를 중복 제거하고 싶으면 associateBy 이용
val map: Map<String, Long> = fruits.associateBy (
{fruit -> fruit.name},
{fruit -> fruit.factoryPrice}
)
print(map) // {apple=800, banana=800}
- Map또한 filter, any, none 같은 거 모두 사용 할 수 있다.
print(map.filter { (key, value) -> key == "apple"}) // {apple= 800}
4 . 중첩된 컬렉션 처리
- flatMap : List<List>가 단일 List 로 바뀐다.
fun main() {
val fruits = listOf(listOf (
Fruit(1L, "apple", 1_000, 1_000),
Fruit(2L, "apple", 800, 1_500),
Fruit(3L, "apple", 800, 1_700)
), listOf (
Fruit(1L, "banana", 1_000, 1_000),
Fruit(2L, "banana", 800, 1_500),
Fruit(3L, "banana", 800, 1_700)
), listOf (
Fruit(1L, "watermelon", 10_000, 10_000),
Fruit(2L, "watermelon", 8_000, 10_500),
Fruit(3L, "watermelon", 8_000, 10_700)
)
)
val samePrice= fruits.flatMap {
list -> list.filter { fruit -> fruit.factoryPrice == fruit.currentPrice}
}
println(samePrice)
}
[출력결과]
[Fruit(id=1, name=apple, factoryPrice=1000, currentPrice=1000),
Fruit(id=1, name=banana, factoryPrice=1000, currentPrice=1000),
Fruit(id=1, name=watermelon, factoryPrice=10000, currentPrice=10000)]
{list -> list.filter { f -> f. ...}} 과 같이 람다가 중첩되어 있기 때문에 아래와 같이 리팩토링도 가능하다.
data class Fruit (
val id: Long,
val name: String,
val factoryPrice: Long,
val currentPrice: Long,
) {
val isSame: Boolean
get() = currentPrice == factoryPrice
}
val List<Fruit>.samePrice: List<Fruit>
get() = this.filter(Fruit::isSame)
fun main() {
val fruits = listOf(listOf (
.....
)
)
val isSamePrice = fruits.flatMap { list -> list.samePrice }
print(isSamePrice)
}
[출력결과]
[Fruit(id=1, name=apple, factoryPrice=1000, currentPrice=1000),
Fruit(id=1, name=banana, factoryPrice=1000, currentPrice=1000),
Fruit(id=1, name=watermelon, factoryPrice=10000, currentPrice=10000)]
□ List<List> → Map<key, value> : .flatMap()
□ List<List> → List<List> : flatten()
※ (intellij) 코틀린 코드 자바로 변환
tool > Kotlin > Show Kotlin Bytecode
자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide)| 최태현 - 인프런 강의
현재 평점 5.0점 수강생 3,556명인 강의를 만나보세요. 이 강의를 통해 Kotlin 언어의 특성과 배경, 문법과 동작 원리, 사용 용례, Java와 Kotlin을 함께 사용할 때에 주의할 점 등을 배울 수 있습니다. Ko
www.inflearn.com
'Kotlin > Java to Kotlin Guide' 카테고리의 다른 글
| scope function (0) | 2025.10.10 |
|---|---|
| Type Alias·as import / 구조분해·componentN / Jump·Label / Takeif · TakeUnless (0) | 2025.10.09 |
| FP - 람다 (0) | 2025.10.09 |
| FP - 다양한 함수 (0) | 2025.10.09 |
| FP - 배열과 컬렉션 (0) | 2025.10.08 |