컬렉션 연산 개요

컬렉션 연산 개요 (Collection operations overview)

코틀린 표준 라이브러리는 컬렉션에 연산을 수행하는 다양한 함수를 제공해요. 여기에는 요소를 얻거나 추가하는 것 같은 단순한 연산부터 검색, 정렬, 필터링, 변환 등을 포함한 더 복잡한 연산까지 여러 가지가 있습니다.

출처: Kotlin 공식 문서 — Collection operations overview

본문

확장 함수와 멤버 함수

컬렉션 연산은 표준 라이브러리에서 두 가지 방식으로 선언됩니다. 컬렉션 인터페이스의 멤버 함수확장 함수가 그것이에요.

멤버 함수는 컬렉션 타입에 필수적인 연산을 정의합니다. 예를 들어 Collection은 비어 있는지 확인하는 isEmpty()를 담고 있고, List는 요소에 인덱스로 접근하는 get()을 담고 있죠.

컬렉션 인터페이스의 나만의 구현을 만들 때는 그 멤버 함수를 구현해야 해요. 새 구현을 더 쉽게 만들려면 표준 라이브러리의 컬렉션 인터페이스 뼈대 구현을 사용하세요. AbstractCollection, AbstractList, AbstractSet, AbstractMap과 이들의 변경 가능한 대응형이 있습니다.

다른 컬렉션 연산은 확장 함수로 선언됩니다. 필터링, 변환, 정렬 등 컬렉션 처리 함수들이 여기에 해당해요.

공통 연산 (Common operations)

공통 연산은 읽기 전용 컬렉션과 변경 가능한 컬렉션 모두에서 사용할 수 있습니다. 공통 연산은 다음 그룹으로 나뉘어요.

이 페이지들에서 설명하는 연산은 원본 컬렉션에 영향을 주지 않고 결과를 반환합니다. 예를 들어 필터링 연산은 필터링 조건(predicate)과 일치하는 모든 요소를 담은 새 컬렉션을 만들어 내죠. 이런 연산의 결과는 변수에 저장하거나, 다른 함수에 전달하는 식으로 사용해야 합니다.

fun main() {
//sampleStart
    val numbers = listOf("one", "two", "three", "four")  
    numbers.filter { it.length > 3 }  // nothing happens with `numbers`, result is lost
    println("numbers are still $numbers")
    val longerThan3 = numbers.filter { it.length > 3 } // result is stored in `longerThan3`
    println("numbers longer than 3 chars are $longerThan3")
//sampleEnd
}

특정 컬렉션 연산에는 대상(destination) 객체를 지정하는 옵션이 있어요. 대상은 함수가 새 객체로 결과를 반환하는 대신 결과 항목을 덧붙이는 변경 가능한 컬렉션입니다. 대상으로 연산을 수행하기 위한 별도의 함수들이 있는데, 이름에 To 접미사가 붙어 있어요. 예를 들어 filter() 대신 filterTo(), associate() 대신 associateTo()를 쓰죠. 이 함수들은 대상 컬렉션을 추가 매개변수로 받습니다.

fun main() {
//sampleStart
    val numbers = listOf("one", "two", "three", "four")
    val filterResults = mutableListOf<String>()  //destination object
    numbers.filterTo(filterResults) { it.length > 3 }
    numbers.filterIndexedTo(filterResults) { index, _ -> index == 0 }
    println(filterResults) // contains results of both operations
//sampleEnd
}

편의를 위해 이 함수들은 대상 컬렉션을 다시 반환하므로, 함수 호출의 해당 인자 자리에 바로 생성할 수 있어요.

fun main() {
    val numbers = listOf("one", "two", "three", "four")
//sampleStart
    // filter numbers right into a new hash set, 
    // thus eliminating duplicates in the result
    val result = numbers.mapTo(HashSet()) { it.length }
    println("distinct item lengths are $result")
//sampleEnd
}

대상이 있는 함수는 필터링, 연결(association), 그룹화, 펼치기(flattening) 등 여러 연산에서 사용할 수 있어요. 대상 연산의 전체 목록은 Kotlin collections reference를 참고하세요.

쓰기 연산 (Write operations)

변경 가능한 컬렉션에는 컬렉션 상태를 바꾸는 쓰기 연산도 있어요. 이런 연산에는 요소 추가, 제거, 업데이트가 포함됩니다. 쓰기 연산은 Write operationsList-specific operations의 해당 섹션, Map specific operations에 나와 있습니다.

특정 연산에는 같은 동작을 수행하는 함수 쌍이 있어요. 하나는 제자리에서 적용하고, 다른 하나는 결과를 별도 컬렉션으로 반환하는 식이죠. 예를 들어 sort()는 변경 가능한 컬렉션을 제자리에서 정렬해서 상태가 바뀌고, sorted()는 같은 요소를 정렬된 순서로 담은 새 컬렉션을 만듭니다.

fun main() {
//sampleStart
    val numbers = mutableListOf("one", "two", "three", "four")
    val sortedNumbers = numbers.sorted()
    println(numbers == sortedNumbers)  // false
    numbers.sort()
    println(numbers == sortedNumbers)  // true
//sampleEnd
}

더 알아보기 (Learn more)