-
7-1 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입(2)Study(종료)/Kotlin 22.09.13 ~ 12.18 2022. 10. 29. 22:26
7장
7-1. 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입 (1) (7-1.1~ 7-1.4)7-1. 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입 (2) ( 7-1.5~ 7-1.7 )
7-1. 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입 (3) ( 7-1.8~ 7-1.11 )
7-2. 컬렉션과 I/O 자세히 알아보기 : 파일과 I/O 스트림
7-1. 컬렉션
5) 컬렉션 원소에 접근하기
기본 컬렉션 연산 외에 개별 컬렉션 원소에 대한 접근을 편하게 해주는 함수들을 살펴보자.
- first() / last() : 주어진 컬렉션의 첫 번째 / 마지막 원소 반환, 해당 컬렉션이 비어있을 경우 Exception 발생
- firstOrNull() / LastOrNull() : 해당 컬렉션이 비어있을 경우 Exception을 발생시키지 않고 Null 반환
- single() : 싱글턴 컬렉션의 원소 반환, 비어있거나 원소가 두 개 이상이면 Exception 발생
- singleOrNull() : 비어있거나 원소가 두 개 이상일 때 Exception을 발생시키지 않고 Null 반환
- elementAt() : 인덱스를 사용해 컬렉션 원소를 가져옴. 인덱스가 잘못된 경우 Exception 발생
- elementOrNull() : 인덱스가 잘못된 경우 Null 반환
- elementAtOrElse() : 인덱스가 잘못된 경우 지정된 람다가 반환하는 원소를 돌려줌
println(listOf(1).single()) // 1 // println(listOf(1, 2, 3).single()) // Exception println(listOf(1, 2, 3).elementAtOrNull(3)) // null println(listOf(1, 2, 3).elementAtOrElse(20){"no element"}) // no element
6) 컬렉션에 대한 조건 검사
어떤 컬렉션이 주어진 조건을 만족하는지 검사하고 싶을 때 코틀린 라이브러리는 다양한 방법의 검사 함수를 제공한다.
- all() : 컬렉션의 모든 원소가 조건을 만족할 경우 true 반환
- none() : 컬렉션의 모든 원소가 조건을 만족하지 않을 경우 true 반환
- any() : 컬렉션의 원소중 하나라도 조건을 만족할 경우 true 반환
val list = listOf(1, 2, 3, 4) println(list.all { it < 10 }) // true println(list.all { it % 2 == 0 }) // false println(list.any { it % 2 == 0 }) // true println(list.none { it % 5 == 0 }) // true
7) 집계(aggreation)
컬렉션 원소의 합계를 계산하거나 최댓값을 찾는 등 컬렉션 내용으로부터 한 값을 계산해 내는 경우를 집계(aggreation)이라고 부른다.
집계 함수는 세 가지 기본 그룹으로 나눌 수 있다.
1) 합계 최솟값 최댓값 등 자주 쓰이는 집계값을 계산
- count()
- 컬렉션의 원소 수를 반환
- 배열, 이터러블, 시퀸스, 맵을 포함하는 모든 컬렉션 객체에 적용 가능(size 프로퍼티를 일반화한 함수)
- 원소 개수가 Int.MAX_VALUE보다 클 경우 Exception throw. (무한 시퀸스에 대해 count() 적용 시 발생)
- 조건을 추가해 주어진 조건을 만족하는 원소의 수를 반환하는 함수로도 사용 가능
- sum()
- 배열, 이터러블, 시퀸스의 산술 합계를 계산
- 반환 타입은 계산한 컬렉션의 원소 타입에 따라 달라짐
- average()
- 배열, 이터러블, 시퀸스의 산술 평균을 계산
- 반환 타입은 항상 Double
- 컬렉션이 비버있을 경우 Double.NaN 반환
- 비어있지 않은 컬렉션 c에 대해 c.average() = c.sum().toDouble() /c.count()
- 원소 개수가 Int.MAX_VALUE보다 클 경우 Exception throw.
- minOrNull() / maxOrNull()
- 비교 가능한 타입의 값이 들어있는 배열, 이터러블, 시퀸스의 최소/최대값 계산
2) 컬렉션 원소를 문자열로 엮음
- joinToString()
- 그대로 사용할 경우 아무 인자도 받지 않음
- 디폴트로 각 원소를 toString() 메서드를 이용해 문자열로 변환한 뒤 구분 문자열로 콤마와 공백(", ") 사용
println(listOf(1, 2, 3, 4).joinToString()) // 1, 2, 3, 4
-
- 커스텀 변환 함수를 이용해 변환 가능
- separator : 인접 두 원소 사이에 들어갈 구분 문자열 설정(디폴트 : ", ")
- prefix / postfix : 결과 문자열의 맨 앞(prefix) / 맨 뒤(postfix)에 들어갈 문자열(디폴트 : 빈 문자열 " ")
- limit : 최대로 보여줄 수 있는 원소의 개수(디폴트 : -1, 개수 제한 x)
- truncated : limit가 양수인 경우 컬렉션의 원소를 모두 표현하지 못할 때 이 파라미터를 뒤에 추가(디폴트 : "...")
- 커스텀 변환 함수를 이용해 변환 가능
val list = listOf(1, 2, 3, 4) println(list.joinToString(prefix = "[", postfix = "]")) // [1, 2, 3, 4] println(list.joinToString(separator = "!")) // 1!2!3!4 println(list.joinToString(limit = 1)) // 1, ... println(list.joinToString(limit = 1, separator = "&", truncated = "!!!")) // 1&!!!
- joinTo()
- 문자열을 새로 생성하는 대신 파라미터로 받은 Appendable 객체 뒤에 덧붙여줌.
- StringBuilder가 Appendable 객체에 속함
val list = listOf(1, 2, 3, 4) val builder = StringBuilder("test: ") println(list.joinTo(builder, separator = "--")) // test: 1--2--3--4
3) 두 값을 조합하는 함수를 이용해 원하는 임의의 집계 방식을 구현하게 해주는 함수
- reduce() / reduceIndexed()
- 파라미터가 두 개인 함수를 받는다. 첫 번째 인자는 누적된 값이고, 두 번째 인자는 컬렉션의 현재 값이다.
- 컬렉션이 비여있을 경우 초기화가 불가능하므로 Exception throw
- 집계 과정
- 1) 누적값을 최초 컬렉션의 첫 번째 원소로 초기화
- 2) 컬렉션의 매 원소(두 번째 원소부터)에 대해 현재 누적값과 현재 원소를
- 파라미터로 받은 함수에 적용하고 이 적용의 결과를 누적값에 대입
- 3) 누적의 결과 반환
val list1 = listOf(1, 2, 3, 4) println(list1.reduce { acc, i -> acc * i}) // 24 val list2 = listOf("a", "b", "c", "d") println(list2.reduce { acc, s -> acc + s}) // a b c d
-
- 집계 규칙이 원소의 인덱스에 따라 달라진다면 reduceIndexed() 사용
val list1 = listOf(1, 2, 3, 4) println(list1.reduceIndexed { index, acc, i -> if(index % 2 == 0) acc * i else acc + i }) // 13 // (1 + 2) * 3 + 4 = 13
- fold() / foldIndexed()
- 누적값의 초깃값을 원하는 대로 지정하고 싶은 경우 사용
- 컬렉션이 비어있어도 초기값을 지정해주므로 Exception throw X
val list1 = listOf(1, 2, 3, 4) println(list1.fold("initial value ") { acc, i -> acc + i}) // initial value 1234
8) 걸러내기(filter)
조건을 만족하지 못하는 원소를 제외한 원하는 원소만 남기는 여러 함수가 있다.
이 걸러내기 연산은 원본 컬렉션을 변경하지 않는다.
- filter()
- 이 함수에 전달되는 조건은 현재 원소를 인자로 받아
- 원소를 컬렉션에 유지해야 하는 경우 true, 버려야 하는 경우 false 반환
- 배열, 이터러블, 맵, 시퀸스에 적용 가능
- 각각의 반환타입
- Array<T>, Iterable<T> 를 filter 할 경우 List<T> 반환
- Map<K, V>을 filter 할 경우 Map<K, V> 반환
- Sequence<T>를 filter 할 경우 Sequence<T> 반환
- Map의 경우 조건 파라미터가 Map.Entry 타입을 인자로 받는다.
- Key나 Value만 filter 하고 싶은 경우 filterKeys()나 filterValues() 함수를 사용
- filterKeys()나 filterValues() 함수는 filterNot 같은 부정 변형이 존재하지 않음
- filterNot()
- 조건을 부정해 filter, 조건이 false를 반환할 때만 원소를 남김
- filterIndexed()
- filter 조건이 인덱스와 관련이 있을 경우 인덱스 값을 추가로 받는 함수인 filterIndexed() 사용
- filterNotNull()
- 널인 원소를 filter해주므로 결과값으로 not-null 타입의 컬렉션을 반환
- filterIsInstance()
- 특정 타입만 남기고 싶은 경우 사용
- 함수의 인자로 타입(Int, String, ...)을 넘겨 인자로 넘어온 타입과 동일한 타입의 원자로 구성된 컬렉션을 반환
- filterTo() / filterNotTo() / filterIndexedTo() / ...
- 위 모든 filter() 관련 함수들은 불변 타입(val)의 컬렉션을 생성해냄
- 이를 가변 타입(var) 컬렉션에 넣고 싶은 경우 뒤에 To를 붙이면 가변 타입의 컬렉션을 반환
다음글
반응형'Study(종료) > Kotlin 22.09.13 ~ 12.18' 카테고리의 다른 글
7-2 컬렉션과 I/O 자세히 알아보기 : 파일과 I/O 스트림 (0) 2022.10.30 7-1 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입(3) (0) 2022.10.30 7-1 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입(1) (0) 2022.10.28 6-3. 특별한 클래스 사용하기 : 인라인 클래스(값 클래스) (0) 2022.10.23 6-2. 특별한 클래스 사용하기 : 데이터 클래스(data class) (0) 2022.10.22 - first() / last() : 주어진 컬렉션의 첫 번째 / 마지막 원소 반환, 해당 컬렉션이 비어있을 경우 Exception 발생