반응형
이 포스팅에서 작성하는 내용은 자바 개발자를 위한 코틀린 입문 에서 발췌하였습니다.
https://inf.run/BpYf
1. Lambda Expression
- 코틀린에서는 기본적으로 함수가 그 자체로 값이 될 수 있다.
즉, 변수에 할당할 수 있고, 파라미터로 넘길 수 있다. (자바에서의 함수 : 2급 시민, 코틀린에서의 함수 : 1급 시민) - 마지막 파라미터가 함수일 때, 소괄호 밖에 중괄호로 사용 가능하다.
- 람다로 작성 시, 파라미터가 한 개라면 it 키워드로 직접 참조가 가능하다.
- 람다로 여러 줄을 작성가능하며, 이 때 마지막 줄의 결과가 리턴의 반환 값이다. (return 키워드가 없더라도 알아서 반환)
- Closure : 코틀린은 람다를 실행할 때, 람다 안에서 사용되는 변수들의 모든 값을 알고 있는다.
class Game(
val name: String,
val price: Int
)
fun main() {
val gameShop =
listOf(
Game("lol", 1_000),
Game("lol", 1_000),
Game("lol", 2_000),
Game("lol", 3_000),
Game("maple", 1_000),
Game("maple", 3_000),
Game("diablo", 10_000)
)
// 익명함수를 사용한 방법
// 함수의 파라미터 및 리턴타입 설정은 생략 가능하다. (Game) -> Boolean
var isLol: (Game) -> Boolean = fun(game: Game): Boolean {
return game.name == "lol"
}
// 람다 표현식을 이용한 방법
// 함수의 파라미터 및 리턴타입 설정은 생략 가능하다. (Game) -> Boolean
var isLol2: (Game) -> Boolean = { game -> game.name == "lol" }
// 호출방법 1
isLol(gameShop[0])
// 호출방법 2
isLol.invoke(gameShop[0])
// Filter를 이용한 방법 1
filterGames(gameShop, isLol)
// Filter를 이용한 방법 2
filterGames(gameShop) {game: Game -> game.name == "lol"}
// Filter를 이용한 방법 3
// 람다로 작성 시, 파라미터가 한 개라면 it 키워드로 직접 참조가 가능하다.
filterGames(gameShop) {it.name == "lol"}
}
private fun filterGames(
gameShop: List<Game>,
filter: (Game) -> Boolean // 함수의 파라미터 및 리턴타입 설정
): List<Game> {
val games = mutableListOf<Game>() // 가변 리스트 정의
for(game in games){
if(filter(game)){
games.add(game)
}
}
return games
}
// filter 를 이용
private fun filterGames2(
gameShop: List<Game>,
filter: (Game) -> Boolean // 함수의 파라미터 및 리턴타입 설정
): List<Game> {
return gameShop.filter(filter).toList()
}
2. 그 외의 함수형 프로그래밍(Java의 stream())
data class User(
val id: Long,
val name: String,
val age: Long,
val money: Long
) {
fun nullOrValue() {
this == null
}
}
fun main() {
val users =
listOf(
User(1,"홍길동", 4, 1_000, ),
User(2,"홍길동", 6, 2_000, ),
User(3,"홍길동", 5, 3_000, ),
User(4,"홍길동", 7, 4_000, ),
User(5,"강백호", 10, 5_000, ),
User(6,"강백호", 11, 10_000, ),
User(7,"강호동", 22, 50_000, )
)
// java stream 처럼 filter 를 이용해서 원하는 필터를 걸 수 있음
val gildongs = users.filter {it.name == "홍길동"}
println(gildongs)
// 필터 내의 로직에서 index 를 확인할 때 아래와 같이 사용 가능하다.
val gildongsWithIdx = users.filterIndexed { idx, user ->
println(idx)
user.name == "홍길동"
}
println(gildongsWithIdx)
// .map을 이용해서 특정한 형태로 추출할 수 있다. (여기서도 마찬가지로 index 가 필요하다면, mapIndexed를 사용하면 된다.)
var gildongsMoney = users.filter {it.name == "홍길동"}.map{user -> user.money}
println(gildongsMoney)
// map의 결과가 null이 아닌 것을 조회
var gildongsMoneyNotNull = users.filter {it.name == "홍길동"}.mapNotNull{user -> user.nullOrValue()}
// all : 람다의 결과가 모두 참이라면 true 반환, 하나라도 거짓이라면 false 반환
var allLambda = users.all{it.name == "홍길동"}
println("allLambda : $allLambda")
// none : 람다의 결과가 모두 거짓이라면 true 반환, 하나라도 참이라면 false 반환
var noneLambda = users.none{it.name == "김멍목"}
println("noneLambda : $noneLambda")
// any : 람다의 결과가 하나라도 참이라면 true 반환, 모두 거짓이라면 false 반환
var anyLambda = users.any{it.name == "홍길동"}
println("anyLambda : $anyLambda")
// count : 말그대로 갯수를 세는 기능
var gildongsCount = users.count{it.name == "홍길동"}
println("gildongsCount : $gildongsCount")
// sortedBy : 오름차순 정렬, sortedByDescending : 내림차순 정렬
var moneySort = users.sortedBy { it.money }
println(moneySort)
var moneySortReverse = users.sortedByDescending { it.money }
println(moneySortReverse)
// distinctBy : 람다의 결과를 기준으로 중복 제거
var userNames = users.distinctBy {user -> user.name}.map { user -> user.name }
println("userNames : $userNames")
// first : 첫번 째 값을 조회 (null 이면 NPE), firstOrNull : 첫번 째 값 조회(null 가능)
// last : 마자막 값을 조회 (null 이면 NPE), lastOrNull : 마지막 값 조회(null 가능)
var userFirst = users.first{user -> user.name == "강백호"}
println("userFirst : $userFirst")
// groupBy : 사람 이름을 Key로 하는 Map을 반환(value : List<User>)
val nameMapList: Map<String, List<User>> = users.groupBy { it.name }
println(nameMapList)
val customMapList: Map<String, List<Long>> = users.groupBy({user->user.name}, {user->user.money})
println(customMapList)
// associateBy : 사람 id을 Key로 하는 Map을 반환.(value : User. 단일 객체로 반환)
val nameMap: Map<Long, User> = users.associateBy { user -> user.id }
println(nameMap)
val customMap: Map<Long, Long> = users.associateBy({ user -> user.id}, { user -> user.money })
println(customMap)
val map: Map<String, List<User>> = users.groupBy { user->user.name }
.filter{(K,V) -> K == "홍길동"}
println(map)
// flatMap : java와 기능 동일, flatten : 중첩 클래스 해제
}
반응형
'BE > Kotlin' 카테고리의 다른 글
[Kotlin] Collection, 확장/중위함수 (0) | 2023.03.08 |
---|---|
[Kotlin] object 키워드, 클래스 관련 (0) | 2023.03.07 |
[Kotlin] 클래스, 상속, 접근제어자 (0) | 2023.03.04 |
[Kotlin] 조건문, 반복분, 예외처리 (0) | 2023.02.24 |
[Kotlin] 변수, 타입 사용 방법 (0) | 2023.02.22 |