๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์ž๋ฐ”

Lambdas and Stream

by moon101 2023. 1. 19.

Streams API

๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ํฌํ•จํ•˜๋Š” ์ปฌ๋ ‰์…˜์ด๋ผ๋„ ์šฐ๋ฆฌ๊ฐ€ ์–ป๊ณ ์ž ํ•˜๋Š” ์ •๋ณด๋Š” ๋น„์Šทํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, '์ด๋Ÿฌํ•œ ์กฐ๊ฑด์— ๋งž๋Š” ์•„์ดํ…œ์„ ์ค˜', '์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์„ ํ™œ์šฉํ•ด์„œ ๋ชจ๋“  ์•„์ดํ…œ์„ ๋ฐ”๊ฟ”์ค˜, ' '์ค‘๋ณต๋œ ๋ฐ์ดํ„ฐ๋Š” ์ง€์›Œ์ค˜', ๋˜๋Š” '์ด๋Ÿฐ ๋ฐฉ๋ฒ•์œผ๋กœ ์š”์†Œ๋“ค์„ ์ •๋ ฌํ•ด ์ค˜' ๋“ฑ์„ ์ปฌ๋ ‰์…˜์— ์š”์ฒญํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ณด์ž. ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด for๋ฌธ๊ณผ Iterator๋ฅผ ์ด์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜ ๊ฐ ์ปฌ๋ ‰์…˜ ํด๋ž˜์Šค์— ๋งž๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์™”๋‹ค. List๋ฅผ ์ •๋ ฌํ•  ๋•Œ๋Š” Collections.sort()๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐฐ์—ด์„ ์ •๋ ฌํ•  ๋•Œ๋Š” Arrays.sort()๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. 

 

Streams API๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์ถ”์ƒํ™” ํ•ด์„œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๊ฐ€ ๋ฌด์—‡์ด๋“  ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•ด ์ค€๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” '์–ด๋–ป๊ฒŒ' ๋ณด๋‹ค๋Š” '๋ฌด์—‡์„'์— ์ดˆ์ ์„ ๋งž์ถฐ ์ปฌ๋ ‰์…˜์— Streams API๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์—ฐ์‚ฐ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

Stream ๋ฉ”์†Œ๋“œ์—๋Š” ์ค‘๊ฐ„ ์—ฐ์‚ฐ(intermediate operations)ํ•˜๊ณ  ์ตœ์ข… ์—ฐ์‚ฐ(terminal operations)์ด ์žˆ๋Š”๋ฐ ์ตœ์ข…์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•ด์•ผ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ(output)๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ์ค‘๊ฐ„ ์—ฐ์‚ฐ์€ ์ง€์—ฐ๋œ ์—ฐ์‚ฐ์œผ๋กœ ์ตœ์ข…์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. 

  • ์ค‘๊ฐ„ ์—ฐ์‚ฐ(lazy) : ์ŠคํŠธ๋ฆผ ๋ฉ”์†Œ๋“œ๋กœ ๋‹ค๋ฅธ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ตœ์ข… ์—ฐ์‚ฐ์„ ํ˜ธ์ถœํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ ์ „๊นŒ์ง€ ์Šคํƒ์ฒ˜๋Ÿผ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์„ ๊ณ„์† ์–น์–ด์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ค‘๊ฐ„ ์—ฐ์‚ฐ์€ stateless ํ•˜๊ณ  stateful๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋Š”๋ฐ ๋งŒ์•ฝ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ์—ฐ์‚ฐ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ ์†Œ์Šค์˜ ์ •๋ณด๋ฅผ ๋ชจ๋‘ ์•Œ์•„์•ผ ํ•œ๋‹ค๋ฉด ๊ทธ ์—ฐ์‚ฐ์€ stateful ํ•˜๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, filter()๋Š” stateless ํ•˜๊ณ , sorted()๋Š” stateful ํ•˜๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์˜ˆ) Stream<T> limit (long maxSize) : ์ŠคํŠธ๋ฆผ์˜ ์ผ๋ถ€๋ฅผ ์ž˜๋ผ๋‚ผ ๋•Œ ์‚ฌ์šฉ. maxSize๋งŒํผ ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์ œํ•œํ•œ๋‹ค. 
  • ์ตœ์ข… ์—ฐ์‚ฐ(eager) : ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์†Œ๋ชจํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด ๋‚ธ๋‹ค. ์ตœ์ข… ์—ฐ์‚ฐ ํ›„์—์„œ๋Š” ์ŠคํŠธ๋ฆผ์ด ๋‹ซํžˆ๊ณ  ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. 
    • ์˜ˆ) boolean anyMatch(Predicate<? super T> predicate) : returns true if any element matches the provided predicate

 

์ŠคํŠธ๋ฆผ ์˜คํผ๋ ˆ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•(stream pipeline)์€ 3๋‹จ๊ณ„๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๊ณ , ์ด ์ค‘ 1๋ฒˆ์งธ์™€ 3๋ฒˆ์งธ๋Š” ๊ผญ ํ•„์š”ํ•˜๋‹ค. 

  1. ์ปฌ๋ ‰์…˜์„ ์ŠคํŠธ๋ฆผํ™”ํ•˜๊ธฐ 
  2. ๋งŒ๋“ค์–ด์ค€ ์ŠคํŠธ๋ฆผ์— ์ค‘๊ฐ„ ์—ฐ์‚ฐ ์‚ฌ์šฉ 
  3. ๊ฒฐ๊ณผ๋ฌผ์„ ์ตœ์ข…์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•ด์„œ ๊ฐ€์ ธ์˜ค๊ธฐ

 

์ŠคํŠธ๋ฆผ์˜ ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. 

  • ์žฌ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ๋งŒ์•ฝ ์ŠคํŠธ๋ฆผ์„ ๋ณ€์ˆ˜์— ์ €์žฅํ•ด ๋†“๊ณ  ์žฌ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด exception์ด ๋ฐœ์ƒํ•œ๋‹ค. 
  • ์ŠคํŠธ๋ฆผ์ด ๋™์ž‘ํ•˜๋Š” ๋™์•ˆ์—๋Š” ์ปฌ๋ ‰์…˜์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.
  • ์ŠคํŠธ๋ฆผ ์—ฐ์‚ฐ์€ ์›๋ณธ ์ปฌ๋ ‰์…˜์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค. 

 

์˜ค๋ธŒ์ ํŠธ 5์žฅํ•˜๊ณ  12์žฅ์— ์ŠคํŠธ๋ฆผ์ด ๋‚˜์™€์„œ TODO๋กœ ์ ์–ด๋†“๊ณ  ๋„˜์–ด๊ฐ”๋˜ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์™”๋‹ค. 

  • 5์žฅ ์ฝ”๋“œ

๋žŒ๋‹ค์‹์€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋žŒ๋‹ค์‹์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

  • 12์žฅ ์ฝ”๋“œ

mapToInt()์™€ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์„œ๋“œ๋กœ๋Š” Integer์˜ parseInt()๋‚˜ valueOf()๊ฐ€ ์žˆ๋‹ค.
Collections.unmodifiableList()

 

 

Lambda

๋žŒ๋‹ค์‹์„ ์ž˜ ์ดํ•ดํ•˜๋ฉด Stream API๋ฅผ ๋” ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋žŒ๋‹ค์‹์€ ๊ฐ์ฒด์ด๊ณ , single abstract method์„ ํ˜ธ์ถœํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค. ๋žŒ๋‹ค์‹์€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค(functional interface)๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๊ณ  ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์—๋Š” ์˜ค์ง ํ•˜๋‚˜์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋งŒ ์ •์˜๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. (static ๋ฉ”์„œ๋“œ์™€ default ๋ฉ”์„œ๋“œ์˜ ๊ฐœ์ˆ˜๋Š” ์ƒ๊ด€์—†์Œ) ์ต๋ช… ๋‚ด๋ถ€ ํด๋ž˜์Šค์™€ ๋น„์Šทํ•จ. 

 

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

  • BinaryOperator<T> : method apply T ํƒ€์ž…์˜ ์ธ์ž 2๊ฐœ๋ฅผ ๋ฐ›์•„์„œ T ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•จ 
  • Consumer<T> : method accept  T ํƒ€์ž…์˜ ์ธ์ž๋ฅผ ๋ฐ›๊ณ , ๋ฐ˜ํ™˜๊ฐ’์€ ์—†์Œ
  • Function<T, R> : method apply T ํƒ€์ž…์˜ ์ธ์ž๋ฅผ ๋ฐ›์•„์„œ R ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•จ
  • Predicate<T> : method test T ํƒ€์ž…์˜ ์ธ์ž๋ฅผ ๋ฐ›์•„์„œ boolean์„ ๋ฐ˜ํ™˜ํ•จ
  • Supplier<T> : method get ์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ , T ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•จ. ์ŠคํŠธ๋ฆผ์—์„œ ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•  ์ปฌ๋ ‰์…˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์ฃผ๋กœ ์‚ฌ์šฉ๋จ
  • UnaryOperator<T> : method get ์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ , T ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•จ
Stream<T> filter(Predicate<? super T>predicate)
	Returns a stream of the elements that match the given predicate.
    
<T> : the Type of the object in the stream
<R> : the type of the Result of the method

 

์—ฌ๊ธฐ์„œ <? super T>๋Š” ์™€์ผ๋“œ ์นด๋“œ์ธ๋ฐ ์—ฌ๊ธฐ์„œ์˜ T๋Š” lower bound์ด๊ณ ,

<? extends T>์—์„œ์˜ T๋Š” upper bound์ด๋‹ค. 

์˜ˆ๋ฅผ ๋“ค๋ฉด, List<? super Integer>์ด๋ฉด List<Integer>, List<Number>, ๊ทธ๋ฆฌ๊ณ  List<Object>๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. 

 

 

๋žŒ๋‹ค์‹์„ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋ฉ”์„œ๋“œ ์ฐธ์กฐ (method reference)๊ฐ€ ์žˆ๋Š”๋ฐ,

ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๋งŒ ํ˜ธ์ถœํ•˜๋Š” ๋žŒ๋‹ค์‹์€ 'ํด๋ž˜์Šค ์ด๋ฆ„::๋ฉ”์„œ๋“œ์ด๋ฆ„' ๋˜๋Š” '์ฐธ์กฐ๋ณ€์ˆ˜::๋ฉ”์„œ๋“œ์ด๋ฆ„'์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. 

 

๋ฉ”์„œ๋“œ ์ฐธ์กฐ์—๋Š” 4๊ฐ€์ง€ ํƒ€์ž…์ด ์žˆ๋‹ค. 

  • instance method => String::toUpperCase String ํด๋ž˜์Šค์˜ toUpperCase ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
String::toUpperCase String ํด๋ž˜์Šค์˜ toUpperCase ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
์•„๋ž˜ ๋‘ ๊ฐœ์˜ ๋žŒ๋‹ค์‹์„ ๋ฉ”์„œ๋“œ ์ฐธ์กฐ๋กœ ๋ฐ”๊พผ ๊ฒƒ.
(String s) -> {return s.toUpperCase();}
s -> s.toUpperCase()
  • instance method of specific object => System.out::println
  • static method => Math::sqrt
  • constructor => TreeMap::new ๊ธฐ๋ณธ ์ƒ์„ฑ์ž(์ธ์ž๊ฐ€ ์—†๋Š”)๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ

 

 

์ž๋ฐ” 8์—์„œ ๋žŒ๋‹ค์™€ ์ŠคํŠธ๋ฆผ์ด ์ถ”๊ฐ€๋˜๋ฉด์„œ functional programming์ด ๊ฐ€๋Šฅํ•ด์กŒ๊ณ , 

๋ณ€์ˆ˜๋“ค์ด immutable ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Ÿฐํƒ€์ž„์‹œ์— ๋ฐ์ดํ„ฐ์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ํ™•๋ฅ ์ด ์ค„์–ด๋“ค์–ด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์ข€ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

 

 

// TODO

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ๋ถ€๋ถ„์€ ์•„์ง ๊ณต๋ถ€ํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ, ๋‚˜์ค‘์— ์™œ ์ด๋ ‡๊ฒŒ ๋˜๋Š”์ง€ ์ฐพ์•„๋ด์•ผ๊ฒ ๋‹ค. 

 

 

 

 

 

์ฐธ๊ณ ์ž๋ฃŒ

ํ—ค๋“œํผ์ŠคํŠธ ์ž๋ฐ” ch.12

์ž๋ฐ”์˜ ์ •์„ ch.14

์Šคํ”„๋ง ์ž…๋ฌธ์„ ์œ„ํ•œ ์ž๋ฐ” ๊ฐ์ฒด ์ง€ํ–ฅ์˜ ์›๋ฆฌ์™€ ์ดํ•ด ๋ถ€๋ก B.

https://learning.oreilly.com/videos/java-8-fundamentals/9780133489354/9780133489354-JFUN_lesson17_02/

https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html

https://docs.oracle.com/javase/tutorial/extra/generics/morefun.html

https://stackoverflow.com/questions/2827585/what-is-super-t-syntax

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

๋Œ“๊ธ€