관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] 코틀린 스트림 함수 정리 본문

안드로이드/코틀린 & 아키텍처 & Recent

[안드로이드] 코틀린 스트림 함수 정리

막무가내막내 2019. 11. 20. 00:48
728x90

[2021-04-13 업데이트]

 

출처 : 커니의 코틀린

=> 책 추천합니다 !

 

커니의 코틀린책을 보며 공부하는 중이다.

스트림 함수를 공부한걸 간략하게 정리하면서 공부할 수 있는 포스팅을 가질려고합니다. 그리고 필요한 함수를 원할 때 찾을수 있게 기록합니다.

 

<예시 데이터 cities>

//데이터
val cities = listOf("Seoul", "Tokyo", "Mountain View")

[변환]

map() => 컬렉션 내 인자를 다른 값 혹은 타입으로 변환할 때 사용합니다.

//데이터
val cities = listOf("Seoul", "Tokyo", "Mountain View")
cities.map{ city -> city.length }
		.forEach{ println("length=$it")}
        
cities.map{ city -> city.toUpperCase() }
		.forEach { println(it) }  //참고로 it대신 city라고 하면 컴파일 에러가 발생한다.

>>output

SEOUL

TOKYO

MOUNTAIN VIEW

length=5

length=5

length=13

 

 

+) mapNotNull()은 컬렉션 내 각 인자를 변환함과 동시에, 반환한 결과가 널 값인 경우 이를 무시합니다.

 


[그룹핑]

groupBy() => 컬렉션 내 인자들을 지정한 기준에 따라 분류하며, 각 인자들의 리스트를 포함하는 맵 형태로 결과를 반환합니다.

//데이터
val cities = listOf("Seoul", "Tokyo", "Mountain View")
cities.groupBy{ city -> if (city.length <= 5 ) "A" else "B" }
		.forEach{ key, cities -> println("key = $key , cities = $cities") }

도시이름의 길이가 5 이하면 A 그룹에 아니라면 B 그룹에 대입한다.


 

 

[필터]

filter() => 컬렉션 내 인자들 중 주어진 조건과 일치하는 인자만 걸러주는 역할을 합니다.

map은 값들을 변환시켜주는 거고 filter는 조건에 부합하지 않는 값들을 걸러준다는 차이점을 꼭 기억합시다.

//데이터
val cities = listOf("Seoul", "Tokyo", "Mountain View")
cities.filter { city -> city.length <= 5 }
		forEach{ println(it) }

 도시 이름의 길이가 5 이하인 항목만 통과됩니다.

 

 


 

 

<예시 데이터2  cities>

 

 

val cities = listOf("Seoul", "Tokyo", "Mountain View", "NYC", "Singapore" )

 

 

 

[테이크]

take() => 컬렉 션 내 인자들 중 앞에서 take() 함수의 인자로 받은 개수만큼만을 인자로 갖는 리스트를 반환합니다.

takeLast() => take() 에서 역순으로 반환한다고 보면 됩니다.

takeWhile() => 첫 번쨰 인자부터 시작하여 주어진 조건을 만족하는 인자까지를 포함하는 리스트를 반환합니다.

taskLastWhile() => taskWhile()의 역순반환입니다.

val cities = listOf("Seoul", "Tokyo", "Mountain View", "NYC", "Singapore" )
//output : Seoul
cities.take(1)
	.forEach { println(it) }
    

//output : NYC 
//         Singapore
cities.takeLast(2)
	.forEach { println(it) }
    
    
//output : Seoul
           Tokyo
cities.takeWhile { city -> city.length <= 5 }
 
//NYC
//Singapore
cities.takeLastWhile { city -> city.length <= 13 }

 

 


[드롭]

drop() => take() 함수의 반대 역할을 합니다. 조건을 만족하는 항목을 컬렉션에서 제외한 결과를 반환합니다.

주의해야할 점은 drop(1) 을 했을때 두번째 인덱스가 drop 된다는 점이다. 

그밖에,,..

dropLast()

dropWhile()

dropLastWhile()

val cities = listOf("Seoul", "Tokyo", "Mountain View", "NYC", "Singapore" )
cities.drop(1)
	.forEach { println(it) }

//Tokyo
//Mountain View
//NYC
//Singapore

 

 


[퍼스트, 라스트]

first() => 컬렉션 내 첫번째 인자를 반환합니다. 특정 조건을 걸어서 그 조건에 만족하는 첫번째 인자를 반환하게도 할 수 있습니다.

 

last() => first()와 반대로 가장  마지막 인자를 반환합니다.

 

firstOfNull(), lastOfNull() => 조건을 만족하는 값이 없으면 예외발생 대신 null을 반환하게합니다.

val cities = listOf("Seoul", "Tokyo", "Mountain View", "NYC", "Singapore" )

 

 

//첫번째 인자반환 Seoul
println(cities.first())

//문자열 길이가 5를 초과하는 첫번째 인자를 반환
println(cities.first { city -> city.length > 5 } )


//문자열 길이가 5를 초과하는 첫번째 인자를 반환 없을 경우 예외를 발생 시켜 NO가 출력
try {
	println(cities.first { city -> city.length > 5 } )
}catch ( e : NoSuchElementException) {
	println("NO")
}

 

 

 


 

[중복제거]

distinct() => 컬렉션 내에 포함된 항목 중 중복된 항목을 걸러낸 결과를 반환합니다. ( 항목의 중복 여부는 equals()로 판단되며 distinctBy() 함수를 사용하면 비교에 사용할 키 값을 직접 설정 가능합니다.

val cities = listOf("Seoul", "Tokyo", "Mountain View", "Seoul", "Tokyo" )
//중복된 항목을 제거합니다. ( 즉 두개 이상이 있어도 한번만 출력됩니다. )
cities.distinct()
 	.forEach { println(it) } 
 
 //중복된 항목을 도시이름의 길이로 판단합니다.
 cities.distinctBy{city -> city.length}
 	.forEach { println(it) }

처음거는

Seoul

Tokyo

Mountain View 가 출력됩니다.

두번째거는 

Mountain View 만 출력됩니다.

 

 


 

 

[조합 및 집계]

 

[조합]

zip() => 두 컬렉션 내의 자료들을 조합하여 새로운 자료를 만들 때 사용합니다. 두 컬렉션의 자료 개수가 달라도 사용할 수 있고 적은 쪽을 따라갑니다.

val names = listOf("MINSU", "YOUNGME", "BAEKGU", "SOYOUNG")
var ages = listOf(10, 20, 30)

//Pair형태로 자료를 조합
names.zip(ages)
	.forEach{ pairs -> println("${pairs.first}:${pairs.second}") }

//출력 (적은 쪽을 따라가므로 SOYOUNG은 제외된다)
MINSU:10
YOUNGME:20
BAEKGU:30


//조합할 자료의 타입을 조합함수를 통해 지정하면 해당 형태로 바꿔준다.
names.zip(ages)
	.forEach{ name , age -> "$name ($age)"}
    
//출력
MINSU (10)
YOUNGME (20)
BAEKGU (30)
    

 

 

[조합]

jsonToString() => 컬렉션 내 자료를 무낮열 형태로 변환함과 동시에, 이를 조합하여 하나의 문자열로 생성합니다.

jsonToString(sperator ="|") => 이렇게 구분자를 줄 수 도 있습니다.

val cities = listOf("Seoul", "Tokyo", "Mountain View", "NYC", "Singapore" )
print(cities.jsonToString())

print(cities.jsonToString(sperator ="|"))

첫번째 출력 Seoul, Tokyo, Mountain View, NYC, Singapore

두번째 출력  Seoul|Tokyo|Mountain View|NYC|Singapore

 

 

[집계]

count() => 컬렉션 내 포함된 자료의 개수를 반환합니다. 조건을 줄 수 도 있습니다.

 

val cities = listOf("Seoul", "Tokyo", "Mountain View", "NYC", "Singapore" )
//5
cities.count()

//3
cities.count { city -> city.length <= 5 }

 

이 밖에 

p112(커니의코틀린)

reduce()  => joinToString()의 조상격이라 볼 수 있으며 컬렉션 내 첫 번째 자료부터 조합을 시작하고, reduceRight() 함수는 동일한 작업을 컬렉션 내 마지막 자료부터 시작합니다.

fold() => reduce() 함수와 거의 동일한 역할을 하나 초깃값을 지정가능합니다.

 

 


 

[기타]

[자료존재 여부 있는지]

any() => 컬렉션 내 단 하나의 자료라도 존재하면 true를 그렇지 않으면 false를 반환. 조건식을 줄 수 도 있습니다.

val cities = listOf("Seoul", "Tokyo", "Mountain View", "NYC", "Singapore" )
//cities에 자료가 존재하는지 확인  => true
println(cities.any())


// 문자열 길이가 5 이하인 자료가 있는 지 확인  => true 
print(cities.any { city -> city.length <= 5 } )

 

[자료존재 여부 없는지]

none() => any()함수와 반대 작업을 수행, 컬렉션이 비어있는지 여부를 반환합니다.

//false  cities는 비어있지 않기때문
println(cities.none())

//true  빈 문자열을 가진 자료가 없습니다.
println(cities.none { city -> city.isEmpty() } )

 

 

[최댓값]

max() => 숫자 타입의 자료를 갖는 컬렉션 내에서 최댓값을 찾아 반환합니다.

 

[최솟값]

min() => 숫자 타입의 자료를 갖는 컬렉션 내에서 최솟값을 찾아 반환합니다.

 

val nums = listOf(4, 2, 5, 3, 2, 0, 8)

//최댓값 반환 8
println(nums.max())


//최솟값 반환 0
println(nums.min())

 

 

 


[P.S]

스트림함수를 실행했다고 해당 리스트의 값은 바뀌지않는다.

val cities = listOf("Seoul", "Tokyo", "Mountain View", "EXAMPLE")
cities.filter { city -> city.length <= 5 }
		.forEach{ println(it) }

 

예를들어 위와 같이 필터를 하고 cities를 출력해도 cities는 원래의 값 그대로 4개의 값을 갖는다.

만약 필터링된 리스트를 갖고 싶다면은 다음과 같이 하면된다.

 

 

val cities = listOf("Seoul", "Tokyo", "Mountain View", "EXAMPLE")
    val cities2 = cities.filter { city -> city.length <= 5 }
    println("RESLT => " + cities2.toString())

결과는 다음과 같다.

RESULT => [Seoul, Tokyo]

 

 

 

 

댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!!

 

 

 

 

 

728x90
Comments