Kotlin

컬렉션 타입과 람다

jay20033 2024. 1. 18. 17:31

집합 연산 함수

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 순서로 정렬됩니다.