Lambda & Stream

Java ๋žŒ๋‹ค ํ‘œํ˜„์‹๊ณผ Stream API

JAVA 8 ์—์„œ ๋žŒ๋‹ค ํ‘œํ˜„์‹(Lambda Expression) ๊ณผ ์ŠคํŠธ๋ฆผ API(Stream API) ๊ฐ€ ๋„์ž…๋˜๋ฉด์„œ, ์ž๋ฐ” ์–ธ์–ด๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„์„ ๋ถ€๋ถ„์ ์œผ๋กœ ๋ฐ›์•„๋“ค์ด๊ณ  ๋ณด๋‹ค ์„ ์–ธ์ ์ธ ์ฝ”๋“œ ์ž‘์„ฑ์„ ์ง€์›ํ•˜๊ฒŒ ๋˜์—ˆ์Œ. ์ด๋กœ์จ ๊ฐœ๋ฐœ์ž๋Š” ๋ฐ˜๋ณต๋ฌธ์ด๋‚˜ ์ต๋ช… ํด๋ž˜์Šค์— ์˜์กดํ•˜๋˜ ๋ฐฉ์‹์„ ๋ฒ—์–ด๋‚˜, ์ฝ”๋“œ์˜ ๊ฐ„๊ฒฐ์„ฑ ๊ณผ ๊ฐ€๋…์„ฑ ์„ ๋†’์ด๊ณ  ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ™œ์šฉ ๋“ฑ์˜ ํšจ์œจ์„ฑ ๋„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Œ. ์•„๋ž˜์—์„œ๋Š” ๋žŒ๋‹ค ํ‘œํ˜„์‹๊ณผ ์ŠคํŠธ๋ฆผ API ์˜ ๊ฐ๊ฐ์˜ ๊ฐœ๋… ์ •์˜, ๋„์ž… ๋ฐฐ๊ฒฝ, ๋ฌธ๋ฒ•, ์žฅ๋‹จ์ , ํ™œ์šฉ ์‚ฌ๋ก€๋ฅผ ์„ค๋ช…ํ• ๊ฑฐ์ž„.

Lambda Expression

์ •์˜์™€ ๋„์ž… ๋ฐฐ๊ฒฝ

๋žŒ๋‹ค ํ‘œํ˜„์‹ ์€ ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜)๋ฅผ ํ•˜๋‚˜์˜ ์‹(expression) ์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ๋ฌธ๋ฒ•์œผ๋กœ, ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋‹จ์ผ ๋ฉ”์„œ๋“œ ์ธํ„ฐํŽ˜์ด์Šค (Functional Interface) ์˜ ์ต๋ช… ๊ตฌํ˜„์ฒด์™€ ๋™๋“ฑํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•จ. ๋‹ค์‹œ ๋งํ•ด, ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ๋™์ž‘ ์ž์ฒด๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด ์ฒ˜๋Ÿผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์–ด์„œ, ๋ฉ”์„œ๋“œ์˜ ์ธ์ˆ˜๋กœ ํ•จ์ˆ˜ํ˜• ๋™์ž‘์„ ์ง์ ‘ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ด์ง. Java 8 ์ด์ „์—๋Š” ์ด๋Ÿฌํ•œ ๋™์ž‘ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ต๋ช… ํด๋ž˜์Šค(์ต๋ช… ๋‚ด๋ถ€ ํด๋ž˜์Šค)๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์ฝ”๋“œ๊ฐ€ ์žฅํ™ฉํ•ด์ง€๊ณ  ๋ถˆํŽธํ•˜๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Œ. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋‚˜ ์ปฌ๋ ‰์…˜ ์ •๋ ฌ์„ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ์ž‘์—…์ด๋ผ๋„ ActionListener ๋‚˜ Comparator ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ต๋ช… ํด๋ž˜์Šค ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ์Œ. ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ์ด๋Ÿฌํ•œ ๋ถˆํŽธํ•จ์„ ํ•ด์†Œํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ–ˆ์œผ๋ฉฐ, ์ž๋ฐ”๋„ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์žฅ์ ์„ ํก์ˆ˜ํ•˜์—ฌ ๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™”(behavior parameterization) ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Œ. ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ณ€ํ™”ํ•˜๋Š” ์š”๊ตฌ์‚ฌํ•ญ์— ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•˜๊ณ , ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ ์ค‘๋ณต๊ณผ ๋ณต์žก์„ฑ์„ ์ค„์ด๋Š” ๋ฐ ํฌ๊ฒŒ ๊ธฐ์—ฌํ•˜์˜€์Œ.

๋ฌธ๋ฒ•๊ณผ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

Java ์—์„œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค (์ถ”์ƒ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•˜๋‚˜๋งŒ ์„ ์–ธ๋œ ์ธํ„ฐํŽ˜์ด์Šค) ์˜ ๊ตฌํ˜„์„ ์‰ฝ๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ์‹์œผ๋กœ ์‚ฌ์šฉ๋จ. ๊ธฐ๋ณธ ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Œ.

(๋งค๊ฐœ๋ณ€์ˆ˜ ๋ชฉ๋ก) -> { ํ•จ์ˆ˜ ๋ณธ๋ฌธ }
  • ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ชฉ๋ก : ํ•จ์ˆ˜์— ์ „๋‹ฌ๋  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋‚˜์—ดํ•จ. ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•˜๋‚˜์ด๋ฉด ๊ด„ํ˜ธ () ๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Œ.

  • -> : ๋žŒ๋‹ค ํ™”์‚ดํ‘œ ์—ฐ์‚ฐ์ž๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜ ๋ณธ๋ฌธ์„ ๊ตฌ๋ถ„ํ•จ.

  • ํ•จ์ˆ˜ ๋ณธ๋ฌธ : ์ฃผ์–ด์ง„ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•ด ์ˆ˜ํ–‰ํ•  ๋กœ์ง์„ ์ •์˜ํ•จ. ํ•œ ์ค„๋กœ ํ‘œํ˜„๋˜๋Š” ๊ฒฝ์šฐ ์ค‘๊ด„ํ˜ธ {} ๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ๊ฐ’์ด ๋žŒ๋‹ค์˜ ๋ฐ˜ํ™˜๊ฐ’์ด ๋จ. ์—ฌ๋Ÿฌ ์ค„๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฒฝ์šฐ {} ๋ธ”๋ก ๋‚ด์— ์ž‘์„ฑํ•˜๊ณ  return ๋ฌธ์„ ์‚ฌ์šฉํ•จ.

๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ํƒ€๊ฒŸ ํƒ€์ž… ๋ฌธ๋งฅ, ์ฆ‰ ๋ณ€์ˆ˜ ์„ ์–ธ์ด๋‚˜ ๋ฉ”์„œ๋“œ ์ธ์ˆ˜ ๋“ฑ์˜ ์œ„์น˜์—์„œ ํ•ด๋‹น ๋žŒ๋‹ค์™€ ํ˜ธํ™˜๋˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ํƒ€์ž…์„ ํ†ตํ•ด ์‚ฌ์šฉ๋จ. ์˜ˆ๋ฅผ ๋“ค์–ด Runnable ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ธ์ˆ˜๊ฐ€ ์—†๊ณ  ๋ฐ˜ํ™˜๊ฐ’์ด ์—†๋Š” run() ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๋Š”๋ฐ, ์ด๋ฅผ ๋žŒ๋‹ค๋กœ ํ‘œํ˜„ํ•˜๋ฉด () -> {...} ํ˜•ํƒœ๊ฐ€ ๋จ. ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ ์˜ˆ๋ฅผ ํ†ตํ•ด ๋น„๊ตํ•ด๋ณด๋ฉด:

// Java 8 ์ด์ „ : ์ต๋ช… ํด๋ž˜์Šค๋กœ ์“ฐ๋ ˆ๋“œ ์‹คํ–‰
Thread th1 = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello, World!");
    }
});
th1.start();


// Java 8 ์ดํ›„ : ๋žŒ๋‹ค ํ‘œํ˜„์‹์œผ๋กœ ์“ฐ๋ ˆ๋“œ ์‹คํ–‰
Thread th2 = new Thread(() -> System.out.println("Hello, World!"));
th2.start();

์œ„ ์ฝ”๋“œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ต๋ช… ํด๋ž˜์Šค ๊ตฌํ˜„์— ๋น„ํ•ด ๊ตฌ๋ฌธ์ด ํ›จ์”ฌ ๊ฐ„๊ฒฐ ํ•ด์ง. ์ด ์™ธ์—๋„ ๋žŒ๋‹ค๋Š” Comparator ์™€ ๊ฐ™์ด ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๋งŒ ๊ฐ€์ง„ ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์— ๋„๋ฆฌ ์‚ฌ์šฉ๋จ. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฆฌ์ŠคํŠธ ์ •๋ ฌ์„ ์œ„ํ•œ ๋น„๊ต์ž๋ฅผ ๋žŒ๋‹ค๋กœ ์‰ฝ๊ฒŒ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Œ.

List<String> fruits = Arrays.asList("banana", "apple", "cherry");

// ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•œ ์ •๋ ฌ: ๋ฌธ์ž์—ด ๊ธธ์ด๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ
fruits.sort((a,b) -> a.length() - b.length());
System.out.println(fruits); // result : [apple, banana, cherry]

์œ„์˜ sort ํ˜ธ์ถœ์—์„œ ๋žŒ๋‹ค (a,b) -> a.length() - b.length() ๋Š” Comparator<String> ์˜ compare(String o1, String o2) ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์„ ํ‘œํ˜„ํ•œ ๊ฒƒ์ž„. ์ด์ฒ˜๋Ÿผ ๋žŒ๋‹ค ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด, ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ต๋ช… ํด๋ž˜์Šค ์„ ์–ธ์„ ์ง์ ‘ ํ•˜์ง€ ์•Š๊ณ ๋„ ํ•„์š”ํ•œ ๋™์ž‘์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Œ. ๋˜ํ•œ ใ„น๋งˆ๋‹ค ๋‚ด๋ถ€์—์„œ๋Š” ์™ธ๋ถ€ ์ง€์—ญ๋ณ€์ˆ˜ ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ ํ•ด๋‹น ๋ณ€์ˆ˜๋Š” ์ž๋™์œผ๋กœ effectively final(์‚ฌ์‹ค์ƒ ์ƒ์ˆ˜) ๋กœ ์ทจ๊ธ‰๋˜์–ด ๋žŒ๋‹ค์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ํ™œ์šฉ๋จ.

์žฅ์ 

  • ์ฝ”๋“œ ๊ฐ„๊ฒฐ์„ฑ ํ–ฅ์ƒ : ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํ›จ์”ฌ ์งง๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉฐ, ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ(boilerplate) ์ฝ”๋“œ๋ฅผ ์ค„์—ฌ์คŒ. ์ต๋ช… ํด๋ž˜์Šค ์‚ฌ์šฉ ๋Œ€๋น„ ์ž‘์„ฑํ•ด์•ผ ํ•  ์ฝ”๋“œ๋Ÿ‰์ด ํฌ๊ฒŒ ๊ฐ์†Œํ•˜์—ฌ ๊ฐ€๋…์„ฑ์ด ๋†’์•„์ง.

  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ง€์› : ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋ฉ”์„œ๋“œ์˜ ์ธ์ž๋กœ ๋™์ž‘์„ ๋„˜๊ธฐ๊ฑฐ๋‚˜ ์ปฌ๋ ‰์…˜์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์„ ์ „๋žต์ฒ˜๋Ÿผ ๋ฐ”๊ฟ” ๋ผ์šฐ๋Š” ๋“ฑ ๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™” ๊ฐ€ ์‰ฌ์›Œ์ง.

  • ํ‘œํ˜„๋ ฅ ์ฆ๊ฐ€ : ๋žŒ๋‹ค์™€ ํ•จ๊ป˜ ๋„์ž…๋œ ์ŠคํŠธ๋ฆผ API ์™€ ๊ฒฐํ•ฉํ•˜์—ฌ, ๋ณต์žกํ•œ ์—ฐ์‚ฐ์„ ์„ ์–ธ์ ์ด๊ณ  ์ง๊ด€์ ์ธ ๋ฐฉ์‹ ์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Œ. ๋ฌด์—‡์„ ํ• ์ง€์— ์ง‘์ค‘ํ•œ ์ฝ”๋“œ ์ž‘์„ฑ์ด ๊ฐ€๋Šฅํ•ด์ง€๊ณ , loop ๋‚˜ ์กฐ๊ฑด๋ฌธ ๋“ฑ์˜ ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ์€ ์ˆจ๊ฒจ์ง.

  • ๋ฉฑ๋“ฑ์„ฑ ๋ฐ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™œ์šฉ : ๋žŒ๋‹ค๋กœ ์ „๋‹ฌ๋˜๋Š” ํ•จ์ˆ˜๋Š” ๋ถ€์ž‘์šฉ์ด ์—†๋„๋ก ์ž‘์„ฑ๋˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋˜๋Š”๋ฐ, ์ด๋Ÿฐ ํŠน์„ฑ ๋•๋ถ„์— ์ŠคํŠธ๋ฆผ์—์„œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๋ฅผ ํ•  ๋•Œ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Œ. ๋˜ํ•œ ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ ๋“ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ ๊ด€๋ฆฌ ์ฝ”๋“œ ์—†์ด๋„ ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง.

  • ํ‘œ์ค€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ํ™œ์šฉ : ์ž๋ฐ” 8 ์—์„œ๋Š” java.util.function ํŒจํ‚ค์ง€์— ๋‹ค์–‘ํ•œ ์šฉ๋„์˜ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค(Consumer, Function, Predicate ๋“ฑ) ๊ฐ€ ์ œ๊ณต๋˜์–ด ์žˆ์–ด, ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•œ ํ‘œ์ค€ํ™”๋œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ. ์ด๋Š” API ์„ค๊ผ ๋ฐ ์‚ฌ์šฉ ์ธก๋ฉด์—์„œ ์ผ๊ด€์„ฑ์„ ๋ถ€์—ฌํ•จ.

๋‹จ์ 

  • ์ดˆ๊ธฐ ๊ฐ€๋…์„ฑ ์ €ํ•˜ : ๋žŒ๋‹ค ๋ฌธ๋ฒ•์ด ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ์˜คํžˆ๋ ค ์ฝ”๋“œ์˜ ์˜๋ฏธ๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Œ. ์ต๋ช… ํด๋ž˜์Šค์— ๋น„ํ•ด ์ฝ”๋“œ์˜ ๋ช…์‹œ์„ฑ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค ๋Š” ์ง€์ ๋„ ์žˆ์œผ๋ฉฐ, ์–ด๋А ์ธํ„ฐํŽ˜์ด์Šค์˜ ์–ด๋–ค ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ธ์ง€ ๋ฐ”๋กœ ์•Œ๊ธฐ ์–ด๋ ค์›Œ ์ฒ˜์Œ์—” ํ˜ผ๋ž€์„ ์ค„ ์ˆ˜ ์žˆ์Œ.

  • ๋””๋ฒ„๊น… ์–ด๋ ค์›€ : ๋žŒ๋‹ค ํ‘œํ˜„์‹ ์ž์ฒด์—๋Š” ์ด๋ฆ„์ด ์—†๊ณ  ์ต๋ช… ํ•จ์ˆ˜ ํ˜•ํƒœ๋กœ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋””๋ฒ„๊ฑฐ๋กœ ์ถ”์ ํ•  ๋•Œ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๊ฐ€ ์ง๊ด€์ ์ด์ง€ ์•Š์„ ์ˆ˜ ์žˆ๊ณ , ๋žŒ๋‹ค ๋‚ด๋ถ€์—์„œ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์–ด๋А ์ง€์ ์ธ์ง€ ํŒŒ์•…์ด ๋‹ค์†Œ ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ์Œ. ๋˜ํ•œ ๋žŒ๋‹ค ๋‚ด ์ฝ”๋“œ๋Š” ํ•˜๋‚˜์˜ ํด๋กœ์ €(Closure) ๋กœ ์ทจ๊ธ‰๋˜๋ฏ€๋กœ, ์ค‘๊ฐ„์— ๋ณ€์ˆ˜ ๊ฐ’์„ ์ฐ์–ด๋ณด๊ฑฐ๋‚˜ ํ•˜๊ธฐ๊ฐ€ ์ „ํ†ต์ ์ธ ๋ฃจํ”„์— ๋น„ํ•ด ๋ฒˆ๊ฑฐ๋กœ์›€.

  • ์ œํ•œ ์‚ฌํ•ญ : ๋žŒ๋‹ค๋Š” ์˜ค์ง ํ•˜๋‚˜์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋งŒ์„ ๊ฐ€์ง„ ์ธํ„ฐํŽ˜์ด์Šค ์— ๋Œ€ํ•ด์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ (@FunctionalInterface ), ๊ธฐ์กด์˜ ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง„ ํƒ€์ž…์„ ๋žŒ๋‹ค๋กœ ์ง์ ‘ ๊ตฌํ˜„ํ•  ์ˆ˜๋Š” ์—†์Œ. ๋˜ํ•œ ๋žŒ๋‹ค ๋ณธ๋ฌธ์—์„œ checked ์˜ˆ์™ธ ๋ฅผ ๋˜์ง€๋ ค๋ฉด ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค์— ๊ทธ ์˜ˆ์™ธ๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ์–ด์•ผ ํ•˜๋Š” ๋“ฑ์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ œํ•œ์ด ์žˆ์Œ.

  • ์™ธ๋ถ€ ์ƒํƒœ ๋ณ€๊ฒฝ์˜ ์ œํ•œ : ๋žŒ๋‹ค ๋‚ด๋ถ€์—์„œ๋Š” ์™ธ๋ถ€ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Œ. (ํ•ด๋‹น ๋ณ€์ˆ˜๋Š” effectively final ์ด์–ด์•ผ ํ•จ.) ๋”ฐ๋ผ์„œ ๋žŒ๋‹ค์‹ ๋‚ด๋ถ€์—์„œ ์™ธ๋ถ€ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋กœ์ง์€ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ œํ•œ๋˜๋ฉฐ, ์ด๋Ÿฌํ•œ ์„ค๊ณ„๋Š” ๋ถ€์ž‘์šฉ์„ ๋ฐฉ์ง€ํ•˜์ง€๋งŒ ๋•Œ๋กœ๋Š” ๋ถˆํŽธํ•จ์œผ๋กœ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์Œ.(AtomicInteger ๋‚˜ ๋ฐฐ์—ด ๋“ฑ์œผ๋กœ ์šฐํšŒ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๊ถŒ์žฅ๋˜์ง€๋Š” ์•Š์Œ.)

  • ์„ฑ๋Šฅ ๋ฐ ์ปดํŒŒ์ผ ์˜ค๋ฒ„ํ—ค๋“œ : ๋žŒ๋‹ค ์ž์ฒด๋Š” ์ž๋ฐ” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ invokedynamic ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ์ˆจ๊ฒจ์ง„ ํด๋ž˜์Šค ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์—ฌ ์ฒ˜๋ฆฌํ•จ. ์ผ๋ฐ˜์ ์œผ๋กœ ์ด๋กœ ์ธํ•œ ์‹คํ–‰ ์„ฑ๋Šฅ ๋ถ€ํ•˜๊ฐ€ ํฌ์ง€ ์•Š์ง€๋งŒ, ์ž๋ฐ” 8 ์ดˆ๊ธฐ์—๋Š” ๋žŒ๋‹ค ์‚ฌ์šฉ ์‹œ ์ฒซ ํ˜ธ์ถœ์— ์•ฝ๊ฐ„์˜ ์ง€์—ฐ์ด ์žˆ๋‹ค๋Š” ๋ณด๊ณ ๋„ ์žˆ์—ˆ์Œ. ํ•˜์ง€๋งŒ JIT ์ตœ์ ํ™”๋กœ ๋Œ€๋ถ€๋ถ„ ์ƒ์‡„๋˜๋ฉฐ, ๋žŒ๋‹ค ํ‘œํ˜„์‹ ๊ทธ ์ž์ฒด๋กœ ํฐ ์„ฑ๋Šฅ์ƒ์˜ ๋‹จ์ ์€ ์—†์Œ ( ์ฃผ๋กœ ์ŠคํŠธ๋ฆผ ์‚ฌ์šฉ ์‹œ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ด์Šˆ)

Stream API

Stream ์€ ์ž๋ฐ” 8 ์—์„œ ์ปฌ๋ ‰์…˜ ๋“ฑ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋„์ž…๋œ ํ•จ์ˆ˜ํ˜• API ์ž„. ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ ์–ธํ˜•(declarative) ๋ฐฉ์‹์œผ๋กœ ์ปฌ๋ ‰์…˜์˜ ์š”์†Œ๋“ค์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋„ ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹์„ ํ†ตํ•ด ํŒŒ์ดํ”„๋ผ์ธ ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ. ์ŠคํŠธ๋ฆผ์€ ํ•œ๋งˆ๋””๋กœ ๋ฐ์ดํ„ฐ ์š”์†Œ๋“ค์˜ ์—ฐ์†์ ์ธ ํ๋ฆ„ ์œผ๋กœ์„œ, ์ด์— ๋Œ€ํ•ด ์ผ๋ จ์˜ ์ค‘๊ฐ„ ์—ฐ์‚ฐ๊ณผ ์ตœ์ข… ์—ฐ์‚ฐ์„ ์ ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” ๊ฒƒ์„ ๊ฐ€๋Šฅ์ผ€ ํ•จ. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์€ ์ „ํ†ต์ ์ธ ๋ฐ˜๋ณต๋ฌธ์— ๋น„ํ•ด ๊ฐ„๊ฒฐํ•˜๊ณ  ์˜๋„์— ์ง‘์ค‘๋œ ์ฝ”๋“œ ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, ๋‚ด๋ถ€ ๋ฐ˜๋ณต์„ ํ†ตํ•ด ์ตœ์ ํ™” ์—ฌ์ง€๋ฅผ ๋‚จ๊ฒจ๋‘๊ฑฐ๋‚˜ ์†์‰ฝ๊ฒŒ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Œ.

์ŠคํŠธ๋ฆผ API ์˜ ๋„์ž… ๋ฐฐ๊ฒฝ์—๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Œ.

์ฒซ์งธ, ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์˜ ํ•„์š”์„ฑ ์ž„. ๋ฉ€ํ‹ฐ์ฝ”์–ด ์‹œ๋Œ€์— ํšจ๊ณผ์ ์œผ๋กœ ์ปฌ๋ ‰์…˜์„ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ผ์ผ์ด ์“ฐ๋ ˆ๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ณ ๋„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋ฅผ ๋ณ‘๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ์ˆ˜์ค€์˜ ์ถ”์ƒํ™”๊ฐ€ ์š”๊ตฌ๋˜์—ˆ์Œ. ์ŠคํŠธ๋ฆผ์€ parallelStream() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํžˆ ๋ฐ์ดํ„ฐ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ.

๋‘˜์งธ, ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ ๊ฐœ์„  ์ž„. ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฃจํ”„์™€ ์กฐ๊ฑด๋ฌธ์ด ๋’ค์„ž์ธ ์ฝ”๋“œ๋ณด๋‹ค ์˜๋„๊ฐ€ ๋ช…ํ™•ํ•œ ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , ์ด๋ฅผ ํ†ตํ•ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ผ๊ด€๋œ ํ˜•ํƒœ๋กœ ํ‘œํ˜„ ํ•  ์ˆ˜ ์žˆ์Œ.

๋งˆ์ง€๋ง‰์œผ๋กœ, ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ฐœ๋…์„ ๋„์ž…ํ•จ์œผ๋กœ์จ ๋ถ€์ž‘์šฉ ์—†๋Š” ์ฒ˜๋ฆฌ ๋ฅผ ์ง€ํ–ฅํ•˜๊ณ , ํ•„ํ„ฐ๋ง, ๋งคํ•‘, ์ •๋ ฌ, ๊ทธ๋ฃนํ•‘ ๋“ฑ ๊ณตํ†ต ์—ฐ์‚ฐ์„ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ‘œ์ค€ํ™” ํ•˜๊ณ ์ž ํ•œ ์˜๋„๊ฐ€ ์žˆ์Œ. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ณผ๊ฑฐ์—๋Š” ๋ฐ˜๋ณต๋ฌธ๊ณผ ์กฐ๊ฑด๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•ด ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ๋˜ ๋กœ์ง๋“ค์„ ์ด์ œ๋Š” filter , map , collect ๋“ฑ์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์—ฐ์‚ฐ์œผ๋กœ ํ•œ์ค„์”ฉ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Œ.

์ŠคํŠธ๋ฆผ ๊ตฌ์กฐ์™€ ์ฃผ์š” ์—ฐ์‚ฐ

์ŠคํŠธ๋ฆผ API ์˜ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ๋ฐ์ดํ„ฐ ์†Œ์Šค ๋กœ๋ถ€ํ„ฐ ์ŠคํŠธ๋ฆผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์—ฌ๋Ÿฌ ์ค‘๊ฐ„ ์—ฐ์‚ฐ (Intermediate Operation) ์„ ์—ฐ์†์œผ๋กœ ์ ์šฉํ•œ ๋’ค, ์ตœ์ข… ์—ฐ์‚ฐ (Terminal Operation) ์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” ํŒจํ„ด์œผ๋กœ ์š”์•ฝ๋จ. ์ด๋•Œ ์ค‘๊ฐ„ ์—ฐ์‚ฐ๋“ค์€ ์ŠคํŠธ๋ฆผ์„ ๋ฆฌํ„ดํ•˜์—ฌ ๋‹ค์Œ ์—ฐ์‚ฐ๊ณผ ์ฒด์ด๋‹๋˜๋ฉฐ, ์‹ค์ œ ์ฒ˜๋ฆฌ(load) ๋Š” ์ตœ์ข… ์—ฐ์‚ฐ์ด ํ˜ธ์ถœ๋  ๋•Œ ๋น„๋กœ์†Œ ์ผ์–ด๋‚˜๋Š” ์ง€์—ฐ ํ‰๊ฐ€(lazy evaluation) ํŠน์„ฑ์„ ๊ฐ€์ง. ์ŠคํŠธ๋ฆผ์˜ ์ „์ฒด์ ์ธ ๊ตฌ์„ฑ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ.

  • ๋ฐ์ดํ„ฐ ์†Œ์Šค(Data Source) : ์ŠคํŠธ๋ฆผ์˜ ์ถœ๋ฐœ์ ์ด ๋˜๋Š” ์š”์†Œ๋“ค์˜ ๋ชจ์ž„์ž„. ์˜ˆ๋ฅผ ๋“ค์–ด ์ปฌ๋ ‰์…˜์˜ stream() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜, ๋ฐฐ์—ด์— Arrays.stream(array) ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ํŒŒ์ผ I/O ์—์„œ Files.lines(path) ๋กœ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Œ.

  • ์ค‘๊ฐ„ ์—ฐ์‚ฐ(Intermediate Operation) : ์ŠคํŠธ๋ฆผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•˜๋Š” ์—ฐ์‚ฐ๋“ค์ž„. ๋Œ€ํ‘œ์ ์œผ๋กœ filter(Predicate) , map(Function) , sorted() , distinct() , limit() ๋“ฑ์ด ์žˆ์œผ๋ฉฐ, ์—ฌ๋Ÿฌ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์„ ํŒŒ์ดํ”„๋ผ์ธ ํ˜•ํƒœ ๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ. ์ค‘๊ฐ„ ์—ฐใ……๋‚˜์€ lazy ํ•˜๊ฒŒ ๋™์ž‘ํ•˜์—ฌ, ๋‹จ๋…์œผ๋กœ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๊ณ  ๊ฒฐ๊ณผ๋„ ๋ฐ”๋กœ ์–ป์„ ์ˆ˜ ์—†์Œ. ์ค‘๊ฐ„ ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ๋Š” ์—ฌ์ „ํžˆ ์ŠคํŠธ๋ฆผ์ด๋ฏ€๋กœ, ์ด์–ด์„œ ๋‹ค์Œ ์—ฐ์‚ฐ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Œ.

  • ์ตœ์ข… ์—ฐ์‚ฐ(Terminal Operation) : ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์˜ ๋์„ ๋งบ๋Š” ์—ฐ์‚ฐ์œผ๋กœ, ์ตœ์ข… ์—ฐ์‚ฐ์ด ํ˜ธ์ถœ๋  ๋•Œ ๊ทธ์ œ์„œ์•ผ ์ด์ „๊นŒ์ง€์˜ ๋ชจ๋“  ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ์ ์šฉ๋˜๋ฉด์„œ ์‹ค์ œ ์ฒ˜๋ฆฌ ๊ฐ€ ์ˆ˜ํ–‰๋˜๊ณ  ๊ฒฐ๊ณผ๊ฐ€ ์ƒ์„ฑ๋จ. ์ตœ์ข… ์—ฐ์‚ฐ์—๋Š” ์ŠคํŠธ๋ฆผ ์š”์†Œ๋ฅผ ์†Œ๋ชจํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” collect() , count() , reduce() ๋‚˜, ๋ถ€์ž‘์šฉ์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š” forEach() ๋“ฑ์ด ์žˆ์Œ. ์ตœ์ข…์—ฐ์‚ฐ์„ ํ˜ธ์ถœํ•˜๋ฉด ํ•ด๋‹น ์ŠคํŠธ๋ฆผ์€ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ(์†Œ๋ชจ๋œ ์ƒํƒœ๋กœ) ๋จ.

์˜ˆ์ œ

๋ฌธ์ž์—ด ๋ฆฌ์ŠคํŠธ ์—์„œ ํŠน์ • ์กฐ๊ฑด์— ๋งž๋Š” ๋ฌธ์ž์—ด๋งŒ ํ•„ํ„ฐ๋งํ•˜์—ฌ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•œ ๋’ค ์ •๋ ฌํ•˜์—ฌ ๊ฒฐ๊ณผ ๋ฆฌ์ŠคํŠธ๋ฅผ ์–ป๋Š” ์ž‘์—…์„, ๊ธฐ์กด ๋ฐฉ์‹๊ณผ ์ŠคํŠธ๋ฆผ์„ ํ™œ์šฉํ•œ ๋ฐฉ์‹์œผ๋กœ ๋น„๊ตํ•˜๋Š” ์˜ˆ์ œ์ž„.

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Anna", "Alex");
List<String> resultList = new ArrayList<>();

// ๊ธฐ์กด ๋ฐฉ์‹: ๋ฐ˜๋ณต๋ฌธ ์‚ฌ์šฉ
for(String name : names) {
    if(name.startWith("A")) {
        resultList.add(name,toUpperCase());
    }
}
Collections.sort(resultList); // ์ •๋ ฌ
System.out.println(resultList); // result : [ALEX, ALICE, ANNA]

//์ŠคํŠธ๋ฆผ ์‚ฌ์šฉ : ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์„ฑ
List<String> resultList2 = names.stream()
    .filter(n -> n.startWith("A"))
    .map(String::toUpperCase)
    .sorted()
    .collect(Collectors.toList());
System.out.println(resultList2);

์œ„ ์˜ˆ์ œ์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ณผ์ • ์„ ๋งˆ์น˜ SQL์˜ ์งˆ์˜๋ฌธ ์ฒ˜๋Ÿผ ์„ ์–ธ์ ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Œ. names.stream() ์œผ๋กœ ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•œ ์ŠคํŠธ๋ฆผ์„ ์–ป์€ ๋’ค, filter ๋กœ "A" ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ด๋ฆ„๋งŒ ๊ฑธ๋Ÿฌ๋‚ด๊ณ , map ์œผ๋กœ ๋Œ€๋ฌธ์ž ๋ณ€ํ™˜, sorted ๋กœ ์ •๋ ฌ, ๋งˆ์ง€๋ง‰์— collect ๋กœ ๋ฆฌ์ŠคํŠธ๋กœ ๋ชจ์œผ๋Š” ์ผ๋ จ์˜ ๊ณผ์ •์„ ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹ ์œผ๋กœ ํ‘œํ˜„ํ–ˆ์Œ. ๊ธฐ์กด ๋ฐฉ์‹๊ณผ ๋น„๊ตํ•˜๋ฉด ์ฝ”๋“œ์˜ ํ–‰ ์ˆ˜๊ฐ€ ์ค„์–ด๋“ค๊ณ , ๊ฐ ๋‹จ๊ณ„์˜ ์˜๋„๊ฐ€ ์ฝ”๋“œ์— ๋ช…ํ™•ํžˆ ๋“œ๋Ÿฌ๋‚˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ.

๋˜ํ•œ ์ŠคํŠธ๋ฆผ์˜ ์ง€์—ฐ ์‹คํ–‰ ๋•๋ถ„์—, ๋งŒ์•ฝ ์œ„ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ filter ํ›„ ๋ฐ”๋กœ ์ฒซ ๋ฒˆ์งธ ๋งค์นญ ์š”์†Œ๋งŒ ์ฐพ๋Š” ์—ฐ์‚ฐ(์˜ˆ: findFirst() ) ์„ ์ตœ์ข… ์—ฐ์‚ฐ์œผ๋กœ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ์กฐ๊ฑด์— ๋งž๋Š” ๋‚˜๋จธ์ง€ ์š”์†Œ๋“ค์€ ๊ตณ์ด ๋Œ€๋ฌธ์ž ๋ณ€ํ™˜์ด๋‚˜ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ณ ๋„ ์ฒ˜๋ฆฌ๋ฅผ ๋งˆ์น  ์ˆ˜ ์žˆ์Œ. ์ด๋Ÿฌํ•œ lazy ํŠน์„ฑ ์€ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ค„์—ฌ ์„ฑ๋Šฅ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋Š” ์š”์†Œ์ž„.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ŠคํŠธ๋ฆผ์—๋Š” ๊ธฐ๋ณธํ˜• ํŠนํ™” ์ŠคํŠธ๋ฆผ (IntStream , LongStream , DoubleStream ) ๋„ ์ œ๊ณต๋จ. ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋ฐ•์‹ฑ(boxing)/์–ธ๋ฐ•์‹ฑ ์—†์ด ๊ธฐ๋ณธ ํƒ€์ž…์˜ ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ๋„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ. ์˜ˆ๋ฅผ ๋“ค์–ด, IntStream.range(1,100) ์€ 1 ๋ถ€ํ„ฐ 99๊นŒ์ง€์˜ ์ •์ˆ˜ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•˜๋ฉฐ, mapToObj ๋‚˜ mapToInt ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด ์ŠคํŠธ๋ฆผ๊ณผ ๊ธฐ๋ณธํ˜• ์ŠคํŠธ๋ฆผ ๊ฐ„ ์ „ํ™˜๋„ ๊ฐ€๋Šฅํ•จ.

์ŠคํŠธ๋ฆผ์˜ ์žฅ์ 

  • ์ฝ”๋“œ ์„ ์–ธ์„ฑ & ๊ฐ„๊ฒฐํ•จ : ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋ฃŒ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ์˜๋„๋ฅผ ์ฝ”๋“œ์— ํ‘œํ˜„ํ•˜๊ธฐ ์‰ฌ์›€. ๋ฌด์—‡์„ ํ•˜๊ณ ์ž ํ•˜๋Š”์ง€๋ฅผ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ฒด์ธ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋ฏ€๋กœ, for-loop ๋“ฑ์— ๋น„ํ•ด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ณ  ๋…ผ๋ฆฌ์˜ ํ๋ฆ„์ด ๋ถ„๋ช…ํ•จ . ํŠนํžˆ ๋‹ค๋‹จ๊ณ„ ์ฒ˜๋ฆฌ (ํ•„ํ„ฐ๋ง -> ๋งคํ•‘ -> ์ •๋ ฌ -> ์ง‘๊ณ„ ๋“ฑ) ๋ฅผ ์ค‘์ฒฉ ๋ฃจํ”„ ์—†์ด ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์–ด, ๋ณต์žกํ•œ ์ฒ˜๋ฆฌ๋„ ๋น„๊ต์  ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Œ.

  • ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์—ฐ์‚ฐ : filter , map , reduce , collect ๋“ฑ ์ŠคํŠธ๋ฆผ์ด ์ œ๊ณตํ•˜๋Š” ๋งŽ์€ ์—ฐ์‚ฐ์€ ์ด๋ฏธ ์ตœ์ ํ™”๋˜์–ด ์žˆ๊ณ  ๋ฒ”์šฉ์ ์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ณ ์ˆ˜์ค€ ํ•จ์ˆ˜๋“ค์ž„. ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ €์ˆ˜์ค€์—์„œ ์ผ์ผ์ด ์ž‘์„ฑํ•ด์•ผ ํ–ˆ๋˜ ๋กœ์ง์„ ์ค„์ด๊ณ  ์ƒ์‚ฐ์„ฑ ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Œ.

  • ๋ถˆ๋ณ€์„ฑ๊ณผ ๋ถ€์ž‘์šฉ ์ตœ์†Œํ™” : ์ŠคํŠธ๋ฆผ ์—ฐ์‚ฐ์€ ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ๊ฒฐ๊ณผ๋ฅผ ์ž‘์„ฑํ•จ. ๋˜ํ•œ ์ค‘๊ฐ„ ์—ฐ์‚ฐ๋“ค์€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜•์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ๊ถŒ์žฅ๋˜๋ฏ€๋กœ(์™ธ๋ถ€ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š” ๋žŒ๋‹ค), ํ”„๋กœ๊ทธ๋žจ์˜ ๋ถ€์ž‘์šฉ(side effect) ์„ ์ค„์ด๊ณ  ๋ฒ„๊ทธ๋ฅผ ์˜ˆ๋ฐฉํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋จ. ์ด๋Ÿฐ ํŠน์„ฑ์€ ์ฝ”๋“œ์˜ ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ๊ณผ ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ๋„ ํ–ฅ์ƒ์‹œํ‚ด.

  • Lazy ์—ฐ์‚ฐ์œผ๋กœ ์ธํ•œ ์ตœ์ ํ™” : ์•ž์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ, ์ŠคํŠธ๋ฆผ์€ ์ง€์—ฐ ํ‰๊ฐ€๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•  ๋•Œ๋งŒ ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•˜๋ฏ€๋กœ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์— ๋„์›€์ด ๋จ. ์˜ˆ๋ฅผ ๋“ค์–ด ์—ฌ๋Ÿฌ ๋‹จ๊ณ„์˜ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ์žˆ๋”๋ผ๋„, ์ตœ์ข… ์—ฐใ……๋‚˜์ด findFirst ๋‚˜ anyMatch ์ฒ˜๋Ÿผ ์ผ๋ถ€๋งŒ ํ•„์š”๋กœ ํ•˜๋Š” ์ž‘์—…์ด๋ฉด ์ „์ฒด ์š”์†Œ๋ฅผ ๋๊นŒ์ง€ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Œ. ๋˜ํ•œ ํŒŒ์ดํ”„๋ผ์ธ ๋‚ด๋ถ€์—์„œ ์—ฐ์‚ฐ๋“ค์ด ๋ฃจํ”„ ํ“จ์ „(loop fusion) ๋˜์–ด ํ•œ ๋ฒˆ์˜ ์ˆœํšŒ๋กœ ์ฒ˜๋ฆฌ๋  ์ˆ˜๋„ ์žˆ์Œ.

  • ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ์šฉ์ด : ์ŠคํŠธ๋ฆผ์˜ ๊ฐ€์žฅ ํฐ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” ์†์‰ฌ์šด ๋ณ‘๋ ฌํ™”์ž„. stream() ๋Œ€์‹  parallelStream() ์„ ํ˜ธ์ถœํ•˜๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ Fork/Join ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์ฝ”์–ด์— ์ž‘์—…์„ ๋ถ„๋ฐฐํ•จ. ํฐ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•ด CPU ์ฝ”์–ด๋ฅผ ๋ชจ๋‘ ํ™œ์šฉํ•จ์œผ๋กœ์จ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋ณต์žกํ•œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Œ.

  • ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค ์ฒ˜๋ฆฌ : ์ปฌ๋ ‰์…˜ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ฐฐ์—ด, ํŒŒ์ผ , I/O ์ฑ„๋„ ๋“ฑ ๋‹ค์–‘ํ•œ ์†Œ์Šค๋กœ๋ถ€ํ„ฐ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•˜์—ฌ ๊ณตํ†ต๋œ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์ž‡์Œ. ์˜ˆ๋ฅผ ๋“ค์–ด Files.lines() ๋กœ ํŒŒ์ผ์˜ ๊ฐ ์ค„์„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์–ป์–ด ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜, Pattern.compile(...).splitAsStream() ์œผ๋กœ ๋ฌธ์ž์—ด์„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋‹ค๋ฃจ๋Š” ๋“ฑ ์‘์šฉ ๋ฒ”์œ„๊ฐ€ ๋„“์Œ.

์ŠคํŠธ๋ฆผ์˜ ๋‹จ์ 

  • ์†Œ๋Ÿ‰ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์˜ค๋ฒ„ํ—ค๋“œ : ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•˜๊ณ  ๋žŒ๋‹ค๋ฅผ ํ˜ธ์ถœํ•˜๋ฉฐ ์—ฌ๋Ÿฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋น„์šฉ ๋•Œ๋ฌธ์—, ์•„์ฃผ ๋‹จ์ˆœํ•œ ๋ฐ˜๋ณต์ด๋‚˜ ์†Œ๋Ÿ‰์˜ ๋ฐ์•„ํ„ฐ ์ฒ˜๋ฆฌ์—๋Š” ์˜คํžˆ๋ ค ์ „ํ†ต์ ์ธ ๋ฃจํ”„๋ณด๋‹ค ๋А๋ฆด ์ˆ˜ ์žˆ์Œ . ์˜ˆ์ปจ๋ฐ ๋‹จ์ˆœํžˆ ๋ฆฌ์ŠคํŠธ์˜ ๋‚ด์šฉ์„ ์ถœ๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ names.stream().forEach(...) ๋ณด๋‹ค๋Š” ๊ฐ•ํ™”๋œ for๋ฌธ(for(String name : names) ) ์ด ์„ฑ๋Šฅ์ƒ ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ. ์ž‘์€ ์ž‘์—…์— ์ผ๊ด„์ ์œผ๋กœ ์ŠคํŠธ๋ฆผ์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์€ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ.

  • ๋””๋ฒ„๊น… ๋ฐ ์ถ”์  ์–ด๋ ค์›€ : ๋žŒ๋‹ค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ์ฝ”๋“œ์˜ ํ๋ฆ„์ด ์—ฐ์‡„์ ์œผ๋กœ ์ด์–ด์ง€๋ฏ€๋กœ, ์ค‘๊ฐ„ ๋‹จ๊ณ„์—์„œ ๊ฐ’์„ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•˜๊ฑฐ๋‚˜ ๋””๋ฒ„๊น…ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ค์›€. ๋””๋ฒ„๊ฑฐ๋กœ๋Š” ๋žŒ๋‹ค ๋‚ด๋ถ€๋ฅผ ์ผ์ผ์ด ๋“ค์—ฌ๋‹ค ๋ด์•ผ ํ•˜๊ณ , ์ฝ”๋“œ์ƒ์œผ๋กœ๋Š” peek() ๊ฐ™์€ ๋””๋ฒ„๊น…์šฉ ์—ฐ์‚ฐ์„ ์ถ”๊ฐ€ํ•ด์•ผ ์ค‘๊ฐ„๊ฐ’์„ ๋ณผ ์ˆ˜ ์žˆ์Œ. ๋ณต์žกํ•œ ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ์œ ์ง€๋ณด์ˆ˜ ์‹œ์— ์ดํ•ดํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Œ.

  • ์žฌ์‚ฌ์šฉ ๋ถˆ๊ฐ€ ๋ฐ ํ•œ๊ณ„ : ์ผ๋‹จ ์ตœ์ข… ์—ฐ์‚ฐ์„ ํ†ตํ•ด ํ•œ ๋ฒˆ ์†Œ๋น„๋œ ์ŠคํŠธ๋ฆผ์€ ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆผ์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฏ€๋กœ, ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‘ ๋ฒˆ ์ˆœํšŒํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์ฐจ๋ผ๋ฆฌ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ทธ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ฉํ•˜๊ฑฐ๋‚˜ ๊ฒฐ๊ณผ๋ฅผ ์ปฌ๋ ‰์…˜์— ๋ชจ์€ ํ›„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•ด์•ผ ํ•จ. ๋˜ํ•œ ์ŠคํŠธ๋ฆผ์€ ๋ณธ์งˆ์ ์œผ๋กœ ์ˆœ์ฐจ์ ์ธ ์ฒ˜๋ฆฌ ์ถ”์ƒํ™” ์— ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์—, ํŠน์ • ์ผ€์ด์Šค (์˜ˆ : ์š”์†Œ๋ฅผ ํ•˜๋‚˜ ์ฒ˜๋ฆฌํ•˜๋‹ค๊ฐ€ ์™ธ๋ถ€ ์ €๊ฑด์— ๋”ฐ๋ผ ๋ฃจํ”„๋ฅผ ์ „์ฒด๋ฅผ ์ค‘๋‹จํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๋“ฑ) ์—์„œ๋Š” ์ŠคํŠธ๋ฆผ๋งŒ์œผ๋กœ ๊ตฌํ˜„์ด ๊นŒ๋‹ค๋กญ๊ฑฐ๋‚˜ ๋ถ€์ ํ•ฉ ํ•  ์ˆ˜ ์žˆ์Œ.

  • ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ ์ฃผ์˜์‚ฌํ•ญ : ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๊ณต์œ  ์ƒํƒœ ๋ณ€๊ฒฝ์ด๋‚˜ ์Šค๋ ˆ๋“œ ์•ˆ์ •์„ฑ ์— ์œ ์˜ํ•ด์•ผํ•จ. ์ž˜๋ชปํ•˜๋ฉด ๊ฒฝ์Ÿ ์กฐ๊ฑด (race condition) ์ด ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜, ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ์Œ. ๋˜ํ•œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ์ž์ฒด์˜ ์˜ค๋ฒ„ํ—ค๋“œ ๋•Œ๋ฌธ์—, ๋ฐ์ดํ„ฐ๋Ÿ‰์ด ์ถฉ๋ถ„ํžˆ ํฌ์ง€ ์•Š์œผ๋ฉด ๋ณ‘๋ ฌํ™”๊ฐ€ ์—ญํ™”๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ์Œ.

  • ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„ : ์ŠคํŠธ๋ฆผ์€ ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ํŒจํ„ด์ด๋ฏ€๋กœ, ํ•„ํ„ฐ๋ง์ด๋‚˜ ๋งคํ•‘ ๊ฒฐ๊ณผ๋ฅผ ์ƒˆ๋กœ์šด ์ปฌ๋ ‰์…˜์œผ๋กœ ์ˆ˜์ง‘ํ•˜๋ฉด ๊ทธ๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•จ. ์ผ๋ฐ˜์ ์ธ ๋ฃจํ”„์—์„œ ์ œ์ž๋ฆฌ์—์„œ ์ˆ˜์ •(in-place) ํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ฌ๋ฆฌ, ํ•„์š”์— ๋”ฐ๋ผ ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Œ. ํŠนํžˆ ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ ๋˜๋Š” ๋งค์šฐ ํฐ ์ŠคํŠธ๋ฆผ์„ ์ž˜๋ชป ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์— ์ฃผ์˜ํ•ด์•ผํ•จ.

Last updated

Was this helpful?