인덱스로 요소 가져오기
val numbers = listOf(1, 2, 3, 4)
println(numbers.get(0)) // 1
println(numbers[0]) // 1
//numbers.get(5) // 예외 발생!
println(numbers.getOrNull(5)) // null
println(numbers.getOrElse(5) { it }) // 5
Kotlin
복사
•
List는 인덱스 접근을 지원하는 가장 기본적인 컬렉션이다.
•
elementAt(), first(), last() 와 같은 여러 함수를 사용하여 요소를 가져올 수 있다.
•
가장 간단한 방법은 인덱스를 사용하여 요소를 가져오는 것이다.
•
get() 함수나 [] 구문을 사용할 수 있다.
•
만약 List 크기가 지정한 인덱스보다 작으면 예외가 발생하고 이를 방지하기 위해 두 가지 함수가 제공된다.
◦
getOrElse()
▪
존재하지 않는 인덱스일 때 기본값을 계산하여 반환한다.
◦
getOrNull()
▪
인덱스가 존재하지 않으면 null을 반환한다.
리스트의 부분 가져오기
val numbers = (0..13).toList()
println(numbers.subList(3, 6)) // [3, 4, 5]
Kotlin
복사
•
List의 특정 범위를 가져오기 위해 subList() 함수를 사용할 수 있다.
•
이 함수는 지정한 범위의 요소를 포함하는 List를 반환한다.
•
원본 List의 요소가 변경되면 서브 List의 요소도 변경된다.
요소 위치 찾기
선형 탐색
val numbers = listOf(1, 2, 3, 4, 2, 5)
println(numbers.indexOf(2)) // 1
println(numbers.lastIndexOf(2)) // 4
Kotlin
복사
•
List에서 특정 요소의 위치를 찾기 위해 indexOf() 와 lastIndexOf() 함수를 사용할 수 있다.
•
이 함수들은 해당 요소의 첫 번째와 마지막 위치를 반환하며 요소가 없으면 -1 을 반환한다.
조건에 맞는 요소의 위치 찾기
val numbers = mutableListOf(1, 2, 3, 4)
println(numbers.indexOfFirst { it > 2 }) // 2
println(numbers.indexOfLast { it % 2 == 1 }) // 2
Kotlin
복사
•
indexOfFirst()
◦
조건을 만족하는 첫 번째 요소의 인덱스를 반환하며 없으면 -1을 반환한다.
•
indexOfLast()
◦
조건을 만족하는 마지막 요소의 인덱스를 반환한다.
정렬된 리스트에서 이진 탐색
val numbers = mutableListOf("one", "two", "three", "four")
numbers.sort()
println(numbers)
println(numbers.binarySearch("two")) // 3
println(numbers.binarySearch("z")) // -5
println(numbers.binarySearch("two", 0, 2)) // -3
Kotlin
복사
•
List가 오름차순으로 정렬된 경우 이진 탐색(binarySearch())을 사용하면 더 빠르게 요소를 찾을 수 있다.
•
요소가 존재하면 인덱스를 반환하고 존재하지 않으면 (-삽입 지점 - 1) 을 반환한다.
•
삽입 지점은 정렬된 List에서 해당 요소가 있어야 할 인덱스를 말한다.
•
동일한 값의 요소가 여러 개 있을 경우 검색 결과는 그 중 아무 인덱스나 반환될 수 있다.
•
인덱스의 범위를 지정하여 검색하면 함수는 두 개의 인덱스 사이에서만 검색한다.
Comparator를 이용한 이진 탐색
val productList = listOf(
Product("WebStorm", 49.0),
Product("AppCode", 99.0),
Product("DotTrace", 129.0),
Product("ReSharper", 149.0)
)
println(productList.binarySearch(Product("AppCode", 99.0), compareBy<Product> { it.price }.thenBy { it.name }))
Kotlin
복사
•
List의 요소가 Comparable이 아닐 경우 Comparator를 제공하여 이진 탐색을 수행할 수 있다.
비교 함수를 사용한 이진 탐색
data class Product(val name: String, val price: Double)
fun priceComparison(product: Product, price: Double) = sign(product.price - price).toInt()
fun main() {
val productList = listOf(
Product("WebStorm", 49.0),
Product("AppCode", 99.0),
Product("DotTrace", 129.0),
Product("ReSharper", 149.0)
)
println(productList.binarySearch { priceComparison(it, 99.0) })
}
Kotlin
복사
•
비교 함수로 이진 탐색을 수행하면 명시적인 값을 제공하지 않고도 요소를 찾을 수 있다.
•
List는 비교 함수의 반환 값에 따라 오름차순으로 정렬되어 있어야 한다.
리스트 쓰기 작업
•
컬렉션 수정 작업 외에도 변경 가능한 List는 특정한 쓰기 작업을 지원한다.
•
이러한 작업들은 인덱스를 사용하여 요소에 접근하며 List 수정 기능을 확장한다.
추가
val numbers = mutableListOf("one", "five", "six")
numbers.add(1, "two")
numbers.addAll(2, listOf("three", "four"))
println(numbers) // [one, two, three, four, five, six]
Kotlin
복사
•
List의 특정 위치에 요소를 추가하려면 add() 와 addAll() 을 사용하여 삽입할 위치를 추가 인수로 제공한다.
•
지정된 위치 이후의 모든 요소는 오른쪽으로 이동한다.
업데이트
val numbers = mutableListOf("one", "five", "three")
numbers[1] = "two"
println(numbers) // [one, two, three]
Kotlin
복사
•
List는 주어진 위치의 요소를 대체하는 set() 함수와 그 연산자 형태인 []도 제공한다.
•
set() 은 다른 요소들의 인덱스를 변경하지 않는다.
val numbers = mutableListOf(1, 2, 3, 4)
numbers.fill(3)
println(numbers) // [3, 3, 3, 3]
Kotlin
복사
•
fill() 은 컬렉션의 모든 요소를 지정된 값으로 단순히 대체한다.
제거
val numbers = mutableListOf(1, 2, 3, 4, 3)
numbers.removeAt(1)
println(numbers) // [1, 3, 4, 3]
Kotlin
복사
•
List에서 특정 위치의 요소를 제거하려면 removeAt() 함수를 사용하여 인덱스를 인수로 제공한다.
•
제거된 요소 이후의 모든 요소들의 인덱스가 하나씩 감소한다.
정렬
val numbers = mutableListOf("one", "two", "three", "four")
numbers.sort()
println("오름차순 정렬: $numbers") // [four, one, three, two]
numbers.sortDescending()
println("내림차순 정렬: $numbers") // [two, three, one, four]
numbers.sortBy { it.length }
println("길이 기준 오름차순 정렬: $numbers") // [one, two, four, three]
numbers.sortByDescending { it.last() }
println("마지막 글자 기준 내림차순 정렬: $numbers") // [three, one, four, two]
numbers.sortWith(compareBy<String> { it.length }.thenBy { it })
println("Comparator로 정렬: $numbers") // [one, two, four, three]
numbers.shuffle()
println("셔플: $numbers")
numbers.reverse()
println("역순: $numbers")
Kotlin
복사
•
변경 가능한 List의 경우 표준 라이브러리는 이러한 정렬 작업을 그대로 수행하는 확장 함수들을 제공한다.
•
이러한 작업을 List 인스턴스에 적용하면 해당 인스턴스의 요소 순서가 변경된다.
•
in-place 정렬 함수의 이름은 읽기 전용 List에 적용되는 함수의 이름과 유사하지만 ed/d 접미사가 없다.
◦
sort* 는 모든 정렬 함수에서 sorted* 대신 사용된다. (sort(), sortDescending(), sortBy())
◦
shuffle() 은 shuffled() 대신 사용된다.
◦
reverse() 는 reversed() 대신 사용된다.
•
asReversed() 는 변경 가능한 List에 호출되면 원래 List의 역순 뷰인 또 다른 변경 가능한 List를 반환한다.
•
이 뷰에서 변경한 내용은 원래 List에 반영된다.