[GDSC Ewha 5th] Android Session

[GDSC Android] Chapter 2. Functions 함수

wlalsu_u 2023. 10. 7. 15:16

2.0 Kotlin Functions 학습 목표

 

 

 

 

Kotlin은 하이브리드 언어로 

 

함수형과 객체지향을 모두 지원한다.

 

이번 챕터에서는 함수에 대해 먼저 알아보자.

 

 

 

 

1) Kotlin 프로그래밍의 기본
2) (Almost) Everything has a value
3) Kotlin의 함수
4) Compact functions
5) 람다(Lambdas) 와 high-order 함수
6) 리스트 필터(List filters)

 

 

 

 

 

모든 실습은 IntelliJ 에서 진행하였습니다.

 

 

 

 


 

 

 

 

2.1 코틀린 프로그래밍의 기본

 

 

 

 

 

먼저 프로그래밍 세팅을 위해서는 다음의 단계를 따라야 한다.

 

각 단계를 하나씩 살펴보자.

 

 

 

 

 

 

1) Kotlin 파일 생성

 

 

 

 

방법1)  IntelliJ IDE 에서 New > Kotlin File/Class 설정

 

방법2) New >  File (파일명 마지막에 코틀린 확장자(.kt) 써야함)

 

 

 

 

 

 

 

 

 

 

2) main() 함수 생성

 

 

 

 

- main 함수는 코틀린 프로그램의 진입점

 

- 실행할 함수를 main 함수 안에 써줌 (선택)

 

- 결과값(return 값) 은 무조건 있어야 함!

 

- return 값이 없는 경우는 Unit 타입 반환이 생략된 것 (아래 2.2 내용 참고)

 

 

 

 

 

fun main(){
    // 안에 아무것도 쓰지 않아도 오류 발생 X
}

 

 

 

 

 

 

3) main() 함수의 인자 전달 (선택)

 

 

 

 

- main 함수 안에 전달할 인자가 있는 경우 Array 로 받음

 

- 전달할 인자가 있는 경우 선택적으로 사용 가능하며, 주로 사용하지 않음

 

 

 

fun main(args: Array<String>){
    println("Hello World!")
}

 

 

 

 

 

 

4) main() 함수에 인자 전달하기 (선택)

 

 

 

 

IntelliJ GUI 를 이용하여 간단하게 main() 함수에 인자를 전달할 수 있다.

 

 

 

먼저 Run > Edit Configurations 에 들어가서

 

Run/Debug Configuration 창을 연다

 

 

 

인자를 넣고 싶은 파일을 지정한 후,

 

Program arguments 에 인자 값을 넣는다. 

 

 

 

 

 

 

 

 

 

 

앞서 설정한 인자는

 

args[0] 을 사용하여 main 에서 사용 가능하다.

 

 

 

 

 

 

 

 

 

 

5) 프로그램 실행

 

 

 

 

- 함수 옆에 있는 삼각형 아이콘을 클릭하여 main() 함수 실행 가능

 

 

 

 

 

 

 

 

 

 


 

 

 

 

2.2 (Almost) Everything has a value

 

 

 

 

Kotlin 에서는 거의 대부분이 식(expression) 의 형태로 표현되기 때문에,

 

결과값이 반드시 존재해야 한다.

 

 

 

 

여기서 식(expression) 의 개념을 더 잘 이해하기 위해

 

문(statement) 과 식(expression) 의 차이점을 정리해보자.

 

 

 

 

 

 

[ 💡 문(statement) 과 식(expression) 의 차이점! ]


1) 문(statement)

- A statement chanes state ( 문은 상태를 변경한다)

- 결과 값(return 값)을 갖지 않아도 됨

- 결과가 아닌 부수효과 (side effect)


2) 식 (expression)

- An expression expresses ( 식은 결과를 짜낸다 )

- 결과 값(return 값)을 반드시 가지고 있어야 함

- 결과 값을 변수에 대입하여 다른 식의 일부분으로도 사용 가능

val temperature = 20
val isHot = if (temperature > 40) true else false

 

 

 

 

 

 

 

그렇다면 여기서 '거의 대부분' 모든 것이 식으로 표현된다고 한 이유는 무엇일까?

 

 

 

 

 

Kotlin 의 거의 모든 함수는 식(expression) 으로 표현되지만,

 

일부 함수는 문(Statement) 으로만 표현된다.

 

 

 

 

 

1) 대표적인 문 (Statement)

 

 

- for 루프

 

- while 루프 / do while 루프

 

 

 

 

 

2) 대표적인 식 (Expression)

 

 

- Kotlin의 대부분의 모든 함수

 

- 다른 대부분의 언어는 문(statement) 를 기반으로 한다는 것과 차이점이 있음

 

 

 

 

 

 

 

그렇다면 여기서 한가지 의문점이 생긴다.

 

 

 

 

아래의 코드에서는 return 값이 명시되어 있지 않은데,

 

왜 에러가 발생하지 않는 것일까?

 

 

 

fun printHello() {
	println("Hello World")
}

 

 

 

 

이는 return 타입이 없는 경우

 

Kotlin.Unit 타입 ( void와 유사) 반환이 생략되어 있기 때문이다! 

 

 

 

 

 

 

Unit 타입 반환의 경우 위의 예제와 같이 생략할 수 있지만,

 

아래의 코드처럼 Unit 을 사용하여 명시적으로 표현할 수 있다.

 

 

 

 

fun printHello(): Unit {
	println("Hello World!")
}

 

 

 

 

 

 

 


 

 

 

 

2.3 Functions in Kotlin

 

 

 

 

Kotlin 에서의 함수에 대해 자세히 알아보자.

 

 

 

 

 

functions

 

 

대부분의 함수가 식(expression) 으로 표현

 

- fun 키워드 사용

 

- 코드 블록은 특정한 연산을 수행

 

- 클린 코드를 위해 재사용성이 높은 작업을 함수로 작성

 

- 함수의 task는 적당히 small 해야함

  ( ex. 양치() 함수는 적절하지만 치약짜기() 함수는 task가 너무 작음 )

 

- named 나 dafault value 인자를 받을 수 있음

 

 

 

 

 

 

 

 

 

먼저 "Hello World" 를 출력하는 printHello 함수를 만들어보자.

 

 

 

 

 

 

 

 

    fun printHello() {
        println("Hello World")
    }

    printHello()

 

 

 

 

 

 

 

 

 

 

 

함수는 기본적으로 식(expression) 이므로 결과값을 가져야 하는데,

 

위의 코드에서 return 값이 없어도 오류가 나지 않은 이유는 무엇일까?

 

 

 

 

 

 

함수가 특별한 값을 return 하지 않을 때 (= no value)

 

Unit 리턴타입이 생략되기 때문이다!

 

 

 

 

 

생략되지 않은 원래의 코드는 아래와 같다.

 

 

 

 

 

 

  fun printHello(): Unit {
       println("Hello World")
  }

  printHello()

 

 

 

 

 

 

Unit

 

 

useful한 리턴 값이 없는 경우 Unit 타입을 리턴

 

- Unit 리턴 타입 선언은 생략 가능

 

- Unit 타입은 오직 Unit 값 하나만 가짐

  (cf. Int 타입은 1, 3, 500 등 다양한 값을 가질 수 있음)

 

 

 

 

 

 

이때 Unit을 제외한 다른 타입을 리턴할 경우,

타입 추론이 불가능하므로 무조건 타입을 명시 해야함을 유의하자!

 

 

 

 

 

 

다음으로 함수에서 인자를 어떻게 사용하는지 알아보자.

 

 

파라미터의 종류에 따라 아래의 2가지 종류로 구분할 수 있다.

 

 

 

 

 

 

1) Required parameters

2) Default parameters

 

 

 

 

 

 

1) Required parameters

 

 

 

- 파라미터에 default 값이 특정되지 않은 경우

 

함수 호출 시 인자를 무조건 넣어주어야 함

 

 

 

 

 

 

 

fun tempToday(day: String, temp: Int) {
	println("Today is $day and it's $temp degrees.")
}

 

 

 

 

 

 

 

 

 

 

 

위의 코드의 경우

 

파라미터에 초기값은 작성되어 있지 않고,

 

파라미터 타입만 작성되어 있으므로,

 

아래와 같이 함수 호출 시 인자를 작성하지 않으면 오류가 발생한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2) Default parameters

 

 

 

- 파라미터 값이 전달되지 않은 경우 default 값을 사용

 

- 타입 뒤에 등호 (=) 를 사용하여 default 값 설정 

 

- 오버로드(overload) 최소화

 

 

 

 

 

 

fun drive(speed: String = "fast"){
    println("driving $speed")
}

 

 

 

 

 

 

 

 

 

 

 

여기서 가장 마지막 줄에 호출한

 

 

 

drive (speed = "turtle-like")

 

 

 

코드는 어떤 의미일까?

 

 

 

 

 

 

 

 

Named arguments

 

 

 

- 코드의 가독성을 높이기 위해 파라미터명을 앞에 작성

 

- 필수는 아니지만, 넣어야 하는 인자가 많은 경우 사용하는 것을 권장

 

 

 

 

 

 

 

 

 

[ 💡 Required parameter 와 Default parameter 비교하기 ]



하나의 함수에서 required 와 defualt 파라미터를 혼용하여 사용할 수 있다.

아래의 예시를 통해 두 파라미터를 비교해보자.


fun reformat(str: String,
	     divideByCamelHumps: Boolean,
             wordSeparator: Char,
             normalizeCase: Boolean = true){}​




str / divideByCamelHumps / wordSeparator 의 경우 디폴트 값이 없으므로 Required parameter

normalizeCase 의 경우 디폴트 값이 true 이므로 Default parameter 이다. 



따라서 reformat 이라는 함수를 아래와 같이 호출할 수 있다.


reformat("Today is a day like no other day", false, '_')



먼저 Required parameter 값은 아래와 같다.


1) str = "Today is a day like no other day"

2) divideByCamelHumps = false

3) wordSeparator = '_'



Default parameter 값은 지정해주지 않았으므로

4) normalizeCase = true (디폴트 값이므로 생략 가능)

이 된다. 


✔️여기서 Defualt 파라미터는 생략가능하므로,
     위의 예시와 같이 Required 인자를 앞에, Default 인자는 뒤에 넣는 것을 권장한다!

 

 

 

 

 

 


 

 

 

 

 

2.4 Compact functions

 

 

 

 

Kotlin 에서는 Compact funtions 이나 single-expression functions를 이용하여

 

코드를 더 명확하고 간단하게 작성할 수 있다.

 

 

 

 

Int 값을 인자로 받아 이를 2배로 반환하는 함수를 작성해보자.

 

원래는 아래와 같이 코드를 작성해야 할 것이다.

 

 

 

 

 

 

fun double(x: Int): Int {
	return x * 2
}

 

 

 

 

 

 

 

하지만 아래와 같이 중괄호를 삭제하고

 

등호(=) 를 사용하여 반환값을 작성하면,

 

훨씬 더 간단하게 함수를 작성할 수 있다!

 

 

 

 

 

 

fun double(x: Int): Int = x * 2

 

 

 

 

 

 

 


 

 

 

 

2.5 람다와 고차함수 (Lamdas and higher-order functions)

 

 

 

 

 

 

💡Kotlin functions are first-class !

 

 

 

 

 

Kotlin의 함수는 1등/1급 함수라는 것은 무슨 의미일까?

 

이는 Kotlin은 함수에 대한 어떠한 차별도 없다는 뜻이다.

 

 

 

 

즉 함수와 변수(값)를 차별하지 않는다는 뜻이다!

 

 

 

 

처음에는 이 의미가 너무 추상적으로 와닿았는데,

 

아래의 예시를 보고 의미를 이해하게 됐다!

 

 

 

 

 

Symbol " f " 만 보고 f 가 변수인지 함수인지 구분할 수 없다!

 

 

 

 

 

자바스크립트나 타입스크립트처럼

 

Kotlin은 함수형 프로그램을 제공하기 때문에

 

Kotlin에서는 함수에 대한 어떠한 차별도 없다!

 

 

 

 

 

 

 

Kotlin functions

 

 

 

- 1등 / 1급 함수로, 함수에 대한 어떠한 차별도 없음

 

- 함수를 값으로 취급

 

- 변수 / 데이터구조에 함수 할당 가능

 

- 함수가 함수의 인자(input), 결과값(output) 이 될 수 있음

 

- 함수형 프로그래밍의 특징

 

 

 

 

 

 

 

그렇다면 이 개념을 바탕으로 람다와 고차함수에 대해 알아보자.

 

 

 

 

 

 

 

1) 람다 함수 (Lambda functions)

 

 

 

- 함수의 이름이 없는 익명 함수 (= 함수 리터럴)

 

- 즉 named function 과 반대되는 개념

 

- 람다 함수의 호출은 일반적인 named function 처럼 사용

 

Function arrow ( -> ) 를 기준으로 왼쪽은 함수의 인자, 오른쪽은 함수의 본문

 

 

 

 

 

 

 

아래의 코드를 보면 함수이지만 이름을 설정하지 않은 것을 확인할 수 있다.

 

여기서 waterFilter는 함수의 이름이 아닌, 변수 이름이다!

 

(즉 함수를 변수에 할당한 것)

 

 

 

 

 

아래 함수의 인자는 level (Int 타입) 이고

 

함수의 본문은 level / 2 연산을 수행하는 것을 확인할 수 있다.

 

 

 

 

 

 

    var dirtLevel = 20
    val waterFilter = {level: Int -> level / 2}
    println(waterFilter(dirtLevel))

 

 

 

 

 

 

 

 

 

 

다음으로 kotlin 에서 함수타입에 대해 알아보자.

 

 

 

 

 

앞서 배운 Int타입, String타입, Double 타입처럼

 

코틀린의 함수는 변수와 함수의 타입을 구분하지 않는 1등 함수이므로,

 

람다와 매우 유사한 함수타입을 갖고 있다.

 

 

 

 

 

 

 

Kotlin의 함수 타입 문법

 

 

 

- Koltin에서는 변수와 함수타입을 구분하지 않음

 

- Function arrow ( -> ) 를 기준으로 왼쪽은 함수의 input타입, 오른쪽은 함수의 return타입을 지정

 

- 해당 타입 조건을 만족하하는 함술면 어떠한 함수이든 사용 가능

 

- 등호(=) 뒤에 타입 조건을 만족하는 람다 함수를 작성

 

 

 

 

 

 

 

val waterFilter: (Int) -> Int = {level -> level / 2}

 

 

 

 

 

 

1) waterFilter : 변수 이름

 

2) (Int) -> Int : int 형을 인자로 받고 int 형을 리턴하는 함수 타입

 

3) {level -> level/ 2} : 람다 함수

 

 

 

 

 

 

 

 

앞서 Kotlin의 경우 함수의 인자와 리턴값도 함수로 설정할 수 있음을 배웠다.

 

인자와 리턴값이 함수인 경우에 대해 자세하게 알아보자.

 

 

 

 

 

 

 

2) 고차 함수 (Higher-order functions)

 

 

 

- 파라미터(input) 또는 리턴값(output) 으로 함수를 사용

 

 

 

 

 

 

아래의 코드를 한번 살펴보자.

 

 

 

fun encodeMsg(msg: String, encode: (String) -> (String): String
{
	return encode(msg)
}

 

 

 

 

 

msg는 단순히 String 타입의 인자를 받는 파라미터이다.

 

 

하지만 encode는 String타입의 인자를 받아 String타입을 리턴하는 함수임을 알 수 있다.

 

따라서 encodeMsg는 함수를 인자로 받는 "고차함수" 이다.

 

 

 

 

 

이때 return 값인 encode(msg)는 encode 함수의 결과(String타입)를 반환하므로

 

함수가 아닌 변수 값임을 유의하자!

 

(즉 msg라는 String을 encode 함수에 넣었을 때 반환되는 String 값)

 

 

 

 

 

 

 

 

 

다음으로 함수에 대한 정보를 전달하기 위해

 

함수를 변수에 저장하는 경우와

 

함수를 다른 함수로 전달하는 경우를 알아보자.

 

 

 

 

 

 

 

 

1) 함수를 변수에 저장할 때 (람다함수)

 

 

 

 

val enc1: (String) -> (String) = { input -> input.toUpperCase() }
println(encodeMsg("abc", enc1))

 

 

 

 

앞서 encodeMsg는 String 타입과 (String->String) 함수를 인자로 받는 함수였다.

 

 

 

따라서 위의 코드에서 String 타입으로는 "abc"

 

함수타입으로는 enc1 변수를 인자로 넣은 것을 확인할 수 있다.

 

 

 

이는 작성한 함수가 람다함수이므로.

 

이를 enc1 이라는 변수에 저장한 후

 

이를 다시 함수타입 자리에 넣는 방법이다.

 

 

 

 

 

💡 이때 Kotlin의 함수타입은 역할과 구현으로 분리되는 것을 확인할 수 있다.


1) 역할 : 함수타입

ec) (String) -> (String) : String을 input으로 하고 String을 output으로 하는 모든 함수

2) 구현 : 함수 본문

ex) {input -> input.toUpperCase() } : String을 input, String을 output으로 하는 구체적인 실제 함수

 

 

 

 

 

 

 

 

2) 함수를 다른 함수로 전달할 때 (고차함수)

 

 

 

 

- named function을 다른 함수의 인자로 보내기 위함

 

- 더블 콜론 ( : : )을 사용하여 작성

 

 

 

fun enc1(input: String): String = input.reversed()
encodeMessage("abc", ::enc)

 

 

 

 

앞서 람다함수를 사용한 경우와 다르게

 

위의 코드는 enc1 이라는 이름을 가진 named 함수이다.

 

 

 

encodeMessage의 두번째 인자는 함수타입이므로

 

enc1 함수를 인자로 전달하기 위해 ::enc를 작성하였다.

 

 

 

앞서 람다 함수를 변수에 넣은 후 전달할 때에는 단순히 변수 이름을 썼지만

 

named 함수를 전달하는경우 콜론 2개 ( : : )를 사용해야 항을 유의하자!

 

 

 

 

 

💡 콜론 2개 ( : : )를 붙여야 하는 이유


위의 예시에서 콜론을 붙이지 않고 enc2("abc") 와 같이 작성하는 경우

이는 enc2 함수에 abc라는 String을 넣어 반환되는 cba 라는 String을 의미한다.


따라서 함수 자체를 넣는것이 아닌, enc2 함수의 리턴 값인 String 변수를 넣는 것이 된다.

✔️ 함수 참조(함수 자체) 를 보내야 하는 경우는 더블 콜론을 사용하자!

 

 

 

[ 참고 ] 함수가 가장 마지막 파라미터인 경우


Kotlin에서는 가독성을 높이기 위해 

함수가 가장 마지막 파라미터인 경우, 해당 파라미터를 괄호 밖에 사용할 수 있다!


encodeMessage("actonym", {input -> input.toUpperCase() })​



위의 코드의 경우 람다함수가 가장 마지막 파라미터로 사용되므로

아래와 같이 코드를 수정해 가독성을 높일 수 있다.


encodeMessage("acronym") {input -> input.toUpperCase()}

 

 

 

[ 참고 ] Kotlin 빌트인 함수에서의 고차함수


많은 Kotlin의 built-in 함수는

마지막 파라미터가 함수인 고차함수를 사용한다.


앞서 배운 repeat 함수 역시 함수를 인자로 받는 고차함수임을 알 수 있다.


inline fun repeat(times: Int, action: (Int) -> Unit)



repeat 함수를 사용하는 경우

time 파라미터에는 Int 타입 정수를 넣고

action 파라미터에는 아래와 같이 람다함수를 사용하는데,

함수가 가장 마지막 파라미터이므로 괄호 밖에 작성한 것을 확인할 수 있다.



repeat(2) {
	print("Hello")
}

 

 

 

 

 

 

 

 


 

 

 

 

 

2.6 리스트 필터 (List filters)

 

 

 

 

 

 

리스트에서 특정 조건을 만족하는 리스트만 사용하려면 어떻게 해야할까?

 

 

 

C와 같은 일반적인 언어에서 if 문을 사용하여 처리할 수 있을 것이다.

 

하지만 Kotlin에서는 리스트 필터를 사용하여 더욱 단순하게 구현할 수 있다.

 

 

 

 

 

 

 

 

리스트 필터 (List filters)

 

 

 

- 리스트에 filter() 함수를 사용하여 원하는 조건의 리스트만 추출

 

- filter { 식 } 의 식에 대해 true를 반환하는 값만 포함

 

파라미터가 오직 하나일 때 it 키워드 사용 가능 

 

 

 

 

 

 

 

아래의 예시를 통해 리스트 필터를 이해해보자.

 

 

 

 

 

 

1,2,3 을 포함하고 있는 ints 리스트에서

 

0 이상의 값만 추출하여 리스트를 만들기 위해서는

 

아래와 같이 코드를 작성할 수 있다.

 

 

 

 

val ints = listOf(1,2,3)
ints.filter { n: Int -> n > 0 }

 

 

 

 

 

이때 ints 리스트는 Int 타입의 값만 저장할 수 있다는 것이 명시적으로 드러나므로

 

n은 생략하여 아래와 같이 작성할 수 있다.

 

 

 

 

 

ints.filter { n -> n > 0 }

 

 

 

 

 

 

이때 리스트 필터의 파라미터가 오직 한개 이므로

 

변수 n 을 it 으로 대체할 수 있고, 화살표 역시 생략이 가능하다.

 

 

 

 

it 은 ints 리스트의 값을 자동으로 하나씩 돌아준(iterate) 다.

 

( it을 사용하면 인자의 이름을 일일이 지어주는 수고를 덜 수 있다..😀)

 

 

 

 

 

 

 

따라서 최종적으로 아래의 코드로 간단하게 리스트 필터를 구현할 수 있다. 

 

 

 

 

 

 

ints.filter { it > 0 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

리스트 필터는 처리방법에 따라

 

필터링 작업을 즉시 처리하는(Eager) 방식과 지연처리(Lazy) 방식으로 구분된다.

 

 

이에 대해 하나씩 자세히 알아보자.

 

 

 

 

 

 

 

 

1) Eager filter (즉시 처리, 즉시 반환)

 

 

 

필터링 작업을 즉시처리하는 방식으로 가장 일반적으로 사용

 

 

 

 

 

 

 

 

리스트 필터링은 별다른 설정을 하지 않은 경우

 

기본적으로 Eager filter 방식으로 처리한다.

 

 

 

아래의 실습을 확인해보면 filter 조건에 해당하는 리스트가

 

곧바로 출력되는 것을 확인할 수 있다.

 

 

 

 

 

 

 

val instruments = listOf("viola", "cello", "violin")
val eager = instruments.filter { it [0] == 'v' }
println("eager: " + eager)

 

 

 

 

 

 

 

 

 

 

 

2) Lazy filter (지연 처리, 필요한 경우 반환)

 

 

 

- 필터링 작업을 지연처리하는 방식으로 특수한 경우 따로 설정

 

- lazy evaluation 을 위해서는 시퀀스 자료구조로 변환 필요

 

- 엄청난 사이즈의 데이터(고사양 작업) 처리나 실제로 사용하는 데이터가 몇개 되지 않는 경우 유용

 

-필요할 때에만 메모리에 할당하므로 메모리 용량이 넉넉하지 않은 경우 유용

 

- 하지만 필터링 처리 하나 하나의 cost 가 큼  

 

 

 

 

 

 

 

 

 

Lazy 필터링으로 처리하고 싶은 경우

 

아래와 같이 리스트를 시퀀스를 먼저 만들어주고 필터를 거는 것을 확인할 수 있다.

 

 

 

 

 

 

val instruments = listOf("viola", "cello", "violin")
// 시퀀스로 먼저 만들어 준 후 필터링
val filtered = instruments.asSequence().filter { it[0] == 'v' }
println("filtered: " + filtered)

 

 

 

 

 

 

실제 결과값을 출력해보면 

 

리스트가 생성되어 반환된 것이 아니라,

 

리스트에 대한 정보만 출력된 것을 확인할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[ 추가 ] Sequence 에서 List로 변환


위의 예시에서 Lazy filtering 을 사용하기 위해 리스트를 시퀀스로 변환하였다.

그러다면 Lazy를 Eager로 다시 변환하기 위해 시퀀스를 리스트로 어떻게 변활할 수 있을까?


toList() 함수를 이용하여 Sequence 를 List로 변환할 수 있다!



아래의 코드를 확인해보면 리스트로 변환 시

리스트 필터링이 즉시 처리되는 것을 확인할 수 있다.


// 즉시 -> 지연 처리
val filtered = instruments.asSequence().filter { it[0] == 'v' }
// 지연 -> 즉시 처리
val newList = filtered.toList()
println("new list: " + newList)​

 

 

 

[ 참고 ] 다른 리스트 변환 함수


1) map()

- 리스트의 값을 하나씩 매핑시킴

- { 키, 값 } 을 갖는 자료구조의 Map과 다른 개념







2) flatten() 

- 중첩되어 있는 collection 모든 요소를 하나의 single list로 반환







💡map() 과 flatten() 이 동시에 처리되는 경우가 많으므로, flatMap() 함수를 사용할 수 있다.


 

 

 

 

 

 

 

 

 

 

 

 

'GDSC Android 교육 세션 자료 및 강의 내용' 과 'Codelab 2강 : Functions' 내용을 기반으로 작성하였습니다.