ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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를 붙이면 가변 타입의 컬렉션을 반환

    다음글

    7-1. 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입 (3) ( 7-1.8~ 7-1.11 )

    반응형

    댓글

Designed by Tistory.