컬렉션 타입과 람다
집합 연산 함수
forEach( ), forEachIndexed( )
forEach( ) : 단순히 컬렉션 타입의 데이터 개수만큼 특정 구문을 반복 실행할 때 유용합니다.
val list = listOf(1, 11, 5)
list.filter { it > 10 }
.forEach { println(it) }
[실행 결과]
11
forEachIndexed( ) : forEach( ) 함수와 동일하며 단지 람다 함수에 인덱스값까지 전달해 줍니다.
val list = listOf(1, 11, 5)
list.forEachIndexed { index, value ->
println("index : $index, value : $value")
}
[실행 결과]
index : 0, value : 1
index : 1, value : 11
index : 2, value : 5
all( ), any( )
all( ) : 함수는 컬렉션 타입의 데이터가 특정 조건에 모두 만족하는지 판단
any( ) : 함수는 특정 조건에 만족하는 데이터가 있는지 판단
class User(val name: String, val age: Int)
val list = listOf(User("kotlin", 33), User("java", 28))
println("all test : ${list.all { it.age > 30 }}")
println("any test : ${list.any { it.age > 30 }}")
[실행 결과]
all test : false
any test : true
count( ), find( )
count( ) : 람다식으로 대입한 조건에 만족하는 데이터 개수를 반환
find( ) : 조건에 만족하는 가장 첫 번째 데이터를 반환
class User(val name: String, val age: Int)
val list = listOf(User("kotlin", 33), User("java", 28))
println("count test : ${list.count { it.age > 25 }}")
val user = list.find { it.age > 25 }
println("find test : ${user?.name} ${user?.age}")
[실행 결과]
count test : 2
find test : kotlin 33
reduce( ), reduceRight( ), fold( ), foldRight( )
reduce( ), fold( ) : 람다 함수를 대입하면 컬렉션 타입의 데이터를 람다 함수에 차례로 전달하며 람다 함수의 결괏값을 반환
reduce( )와 fold( )의 차이점은 fold( ) 함수는 초기값을 지정할 수 있지만, reduce( ) 함수는 초기값을 지정할 수 없습니다.
그래서 만약 호출하는 컬렉션 타입이 비어 있으면 reduce( ) 함수를 사용할 경우 UnsupportedOperationException이 발생하게 됩니다.
val result = listOf(1, 2).fold(10) { total, next ->
println("$total ... $next")
total + next
}
println("fold test : $result")
[실행 결과]
10 ... 1
11 ... 2
fold test : 13
val result = listOf(1, 2, 3).reduce { total, next -> total + next }
println("reduce test : $result")
[실행 결과]
reduce test : 6
foldRight( ) : fold( ) 함수와 같은데 차이점은 전달되는 데이터가 마지막부터 거꾸로 전달되며 람다 함수의 매개변수도 첫 번째가 전달되는 데이터, 두 번째가 이전 결괏값입니다.
val result = listOf(1, 2, 3).foldRight(4) { next, total ->
println("$total ... $next")
total + next
}
println("foldRight test : $result")
[실행 결과]
4 ... 3
7 ... 2
9 ... 1
foldRight test : 10
reduceRight( ) : reduce( ) 함수와 같으며 단지 데이터를 마지막부터 전달한다는 차이가 있습니다.
max( ), maxBy( ), min( ), minBy( )
max( ) : 컬렉션 타입의 데이터 중 가장 큰 값을 반환
maxBy( ) : max( ) 함수와 목적은 같지만 maxBy( ) 함수에는 람다 함수를 매개변수로 지정하여 로직에 의한 계산 결과 중 가장 큰 값을 반환
val result = listOf(1, 11, 5).maxBy { it % 10 }
println("max test : $result")
[실행 결과]
max test : 5
min( ) : 컬렉션 타입의 데이터 중 가장 작은 값을 반환
minBy( ) : min( ) 함수와 목전은 같지만 minBy( ) 함수에는 람다 함수를 매개변수로 지정하여 로직에 의한 계산 결과 중 가장 작은 값을 반환
none( ), sumBy( )
none( ) : 람다 함수에서 지정한 조건에 맞는 데이터가 없으면 true, 있으면 false를 반환
val list = listOf(1, 11, 5).none { it % 10 == 0 }
println("none test : $list")
[실행 결과]
none test : true
sumBy( ) : 람다 함수를 거쳐 반환한 모든 값을 더하는 함수
필터링 함수
filter( ) : 컬렉션 타입의 데이터 중 특정 조건에 맞는 데이터만 추출
val list = listOf(12, 8, 9, 20)
val resultList = list.filter { it > 10 }
for (i in resultList) {
println(i)
}
[실행 결과]
12
20
filterNot( ), filterNotNull( )
filterNot( ) : filter( ) 함수와 반대 -> 조건에 맞지 않는 데이터만 추출
filterNotNull( ) : null이 아닌 데이터만 추출
drop( ), dropwhile( ), dropLastWhile( )
drop( ) : 매개변수로 숫자를 대입하면 앞부분부터 대입한 숫자 개수만큼을 제외하고 나머지를 추출
val list = listOf(1, 2, 3, 4).drop(2)
.forEach { println(it) }
[실행 결과]
3
4
dropWhile( ) : 매개변수로 람다 함수를 지정하며 앞부분부터 조건에 만족하지 않는 데이터가 나올 때 데이터를 제외, 조건에 만족하지 않는 데이터가 나오는 순간 그 데이터부터 나머지를 추출합니다.
val list = listOf(2, 1, 12, 5, 23).dropWhile { it < 10 }
.forEach { println(it) }
[실행 결과]
12
5
23
dropLastWhile( ) : dropWhile( ) 함수와 순서가 반대, 마지막부터 거꾸로 조건을 판단하고 조건에 맞지 않는 데이터가 나오는 순간 그 나머지를 추출합니다.
slice( ), take( ), takeLast( ), takeWhile( )
slice( ) : 범위나 숫자 값을 여러 개 대입하고 그 위치에 있는 데이터만 추출
take( ) : 숫자 값을 매개변수로 전달하면 앞에서부터 숫자에 해당하는 개수의 데이터를 추출
takeLast( ) : take( )와 반대이며, 마지막 데이터부터 매개변수로 전달받은 개수만큼 추출
takeWhile( ) : 람다 함수로 조건을 명시하고 앞에서부터 차례로 데이터가 조건에 맞는지를 판단, 조건에 맞지 않는 데이터가 나오기 전까지의 데이터를 추출합니다.
매핑 함수
map( ), mapIndexed( )
map( ) : forEach( ) 함수와 데이터 개수만큼 반복 실행하는 것은 동일하나 차이점은 반환값이 있다는 점입니다.
val list = listOf(12, 8, 9, 20)
list.filter { it > 10 }
.map { it * 10 }
.forEach { println(it) }
[실행 결과]
120
200
mapIndexed( ) : map( ) 함수와 동일한데 람다 함수에 인덱스까지 전달해 줍니다.
groupBy( ) : 컬렉션 타입의 데이터를 특정 데이터로 묶을 때 사용합니다.
val list = listOf<User>(User("kim", 33), User("lee", 28), User("park", 28))
list.groupBy { it.age }
.forEach {
println("key : ${it.key} ... count : ${it.value.count()}")
it.value.forEach { println("${it.name} .. ${it.age}") }
}
[실행 결과]
key : 33 ... count : 1
kim .. 33
key : 28 ... count : 2
lee .. 28
park .. 28
요소 함수
contains( ) : 컬렉션 타입의 데이터 중 특정 데이터가 있는지를 판단, 데이터가 있으면 true를 없으면 false를 반환합니다.
elementAt( ) : 특정 위치에 데이터를 추출합니다.
만약 데이터 범위를 벗어난 인덱스값을 전달하면 IndexOutOfBoundsException이 발생합니다.
elementAtOrElse( ) : elementAt( ) 함수처럼 특정 인덱스의 데이터를 추출합니다.
만약 인덱스값이 데이터 범위를 벗어나면 지정된 람다 함수가 실행되고 그 람다 함수에서 반환한 값을 반환합니다.
elementAtOrNull( ) : elementAt( ) 함수처럼 특정 인덱스의 데이터를 추출하는데, 만약 인덱스값이 데이터 범위를 벗어나면 null을 반환합니다.
first( ) : 람다 함수로 조건을 주고 그 조건에 맞는 가장 첫 번째 데이터를 추출합니다.
만약 조건에 맞는 데이터가 하나도 없으면 NoSuchElementException이 발생합니다.
firstOrNull( ) : first( ) 함수와 동일한데 조건에 맞는 데이터가 없으면 null을 반환합니다.
last( ) : 람다 함수로 조건을 주고 그 조건에 만족하는 가장 마지막 데이터를 추출합니다.
만약 조건에 맞는 데이터가 하나도 없으면 NoSuchElementException이 발생합니다.
lastOrNull( ) : last( ) 함수와 동일한데 조건에 맞는 데이터가 없으면 null을 반환합니다.
indexOf( ) : 매개변수로 받은 데이터가 위치하는 첫 번째 인덱스값을 반환합니다.
만약 데이터가 없으면 -1을 반환합니다.
indexOfFirst( ) : indexOf( ) 함수와 동일한데 차이점은 indexOf( ) 함수는 매개변수로 데이터를 전달받지만 indexOfFirst( ) 함수는 람다 함수를 전달받습니다. 람다 함수를 실행하여 그 결괏값에 해당하는 인덱스를 반환합니다.
indexOfLast( ) : indexOfFirst( ) 함수와 동일한데 indexOfLast( ) 함수는 마지막 인덱스를 반환합니다.
정렬 함수
reversed( ) : 데이터의 순서를 거꾸로 바꿀 때 사용합니다.
sorted( ) : 정렬을 목적으로 사용합니다.
sortedBy( ) : 람다 함수를 대입할 수 있고 람다 함수의 결괏값을 대상으로 정렬합니다.
val list = listOf(11, 13, 12).sortedBy { it % 3 }
.forEach { println(it) }
[실행 결과]
12
13
11
sortedDescending( ), sortedDescendingBy( ) 함수는 sorted( ) , sortedBy( ) 함수와 동일한데, 정렬이 역순입니다.
숫자 값을 정렬하면 큰 수에서 작은 수로 정렬되고 문자열은 z에서 a 순서로 정렬됩니다.