Java 8๋ถํฐ Lambda์์ด ๋์
๋์๊ณ Stream์ด๋ผ๋ API๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.
Labmda๋ฅผ ํตํด ๋ฐ์ดํฐ Collection์ ๋ฐ๋ณต ์ฒ๋ฆฌ๊ฐ ๊ฐ๋จ๋ช
๋ฃํด์ก๊ณ , Stream์ ํตํด ๋ถ๊ธฐ ์ฒ๋ฆฌ ์์ด ๋ฐ์ดํฐ Collection์ ์์๋ฅผ ๋ฐ๋ณต ์ฒ๋ฆฌํ ์ ์๊ฒ ๋์์ต๋๋ค.
Lambda ํํ์์ด๋ ๋ฉ์๋๋ฅผ ํ๋์ ์์ผ๋ก ํํํ๋ ๊ฒ์ผ๋ก, ๋งค๊ฐ๋ณ์์ ํ์ดํ(->), {๋ชธํต} ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ง๋๋ค.
๊ธฐ์กด์ ์ต๋ช
ํจ์๋ก ์์ฑํ๋ ์ฝ๋๋ฅผ ์ค์ฌ ๊ฐ๋จํ๊ฒ ์์ฑ์ด ๊ฐ๋ฅํ์ฌ ๊ฐ๋
์ฑ์ด ์ข๊ณ ๋ณ๋ ฌ ํ๋ก๊ทธ๋๋ฐ์ ์ฉ์ดํฉ๋๋ค.
ํ์ง๋ง ๋จ์ฉํ๋ฉด ์คํ๋ ค ๊ฐ๋
์ฑ์ด ๋จ์ด์ง ์ ์์ผ๋ฉฐ ์ต๋ช
ํจ์ ๊ธฐ๋ฐ์ด๊ธฐ ๋๋ฌธ์ ๋๋ฒ๊น
์ด ์ด๋ ต๊ณ ์ฌ๊ท ํ์ฉ์ด ๊น๋ค๋กญ์ต๋๋ค.
์๋ฐ์ ๋๋ค ํํ์์ ํจ์ํ ์ธํฐํ์ด์ค๋ก๋ง ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
ํจ์ํ ์ธํฐํ์ด์ค๋ 1๊ฐ์ ์ถ์ ๋ฉ์๋๋ฅผ ๊ฐ๋ ์ธํฐํ์ด์ค๋ฅผ ๋งํฉ๋๋ค.
์ธํฐํ์ด์ค ๊ฒ์ฆ๊ณผ ์ ์ง๋ณด์๋ฅผ ์ํด @FunctionalInterface ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํฉ๋๋ค.
ํจ์ํ ์ธํฐํ์ด์ค | Descripter | Method |
---|---|---|
Predicate | T -> boolean | boolean test(T t) |
Consumer | T -> void | void accept(T t) |
Supplier | () -> T | T get() |
Function<T, R> | T -> R | R apply(T t) |
Comparator | (T, T) -> int | int compare(T o1, T o2) |
Runnable | () -> void | void run() |
Callable | () -> T | V call() |
๐ก ๋ช
๋ นํ ํ๋ก๊ทธ๋๋ฐ: ์ ํ๋ฆฌ์ผ์ด์
์ ์ํ์ ์ํ๋ฅผ ๋ณ๊ฒฝ์ํค๋ ๊ตฌ๋ฌธ์ ๊ด์ฌ์์ ์ฐ์ฐ์ ์ค๋ช
ํ๋ ๋ฐฉ์์ผ๋ก ์ด๋ป๊ฒ ํ ๊ฒ์ธ์ง ํํํฉ๋๋ค.
โโ ์ ์ฐจ ์งํฅ ํ๋ก๊ทธ๋๋ฐ
โโ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ
๐ก ์ ์ธํ ํ๋ก๊ทธ๋๋ฐ: ๋ฌด์์ ํ ๊ฒ์ธ์ง ํํํ๋ ๋ฐฉ์์
๋๋ค.
โโ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ
โ
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ
ํ๋์จ์ด ๋ฐ์ ๊ณผ ํจ๊ป ์ํํธ์จ์ด ํจ๋ฌ๋ค์์ Text ๊ธฐ๋ฐ์ ์ ์ฐจ์ ํ๋ก๊ทธ๋๋ฐ -> GUI ๊ธฐ๋ฐ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ -> ๋ฉํฐ์ฝ์ด ๊ธฐ๋ฐ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ผ๋ก ๋ณํํด์์ต๋๋ค.
๋์ฉ๋์ ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด์ ๋ฉํฐ์ฝ์ด๋ฅผ ํ์ฉํ๋ ๋ณ๋ ฌ์ฒ๋ฆฌ ํ๋ก๊ทธ๋๋ฐ ๋์
์ด ํ์ํด์ ธ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ด ํ์ฐ์ ์ผ๋ก ์ ํ๋์์ต๋๋ค.
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ด๋ ํจ์๋ฅผ 1๊ธ ๊ฐ์ฒด๋ก ์ฌ์ฉํ์ฌ ๊ณ์ฐ์ ์ํ์ ํจ์์ ์กฐํฉ์ผ๋ก ์๊ฐํ๋ ๋ฐฉ์์
๋๋ค.
1๊ธ ๊ฐ์ฒด๊ฐ ๋ ์ ์๋ ์กฐ๊ฑด์ ์๋์ ๊ฐ์ต๋๋ค.
- ๋ณ์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ ์์ ๋ด์ ์ ์๋ ๊ฐ์ฒด
- ํจ์์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ ๊ฐ๋ฅ
- ๋ฐํ๊ฐ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅ
- ํ ๋น์ ์ฌ์ฉ๋ ์ด๋ฆ๊ณผ ๊ด๊ณ์์ด ๊ณ ์ ํ ๊ตฌ๋ณ ๊ฐ๋ฅ
- ๋์ ์ผ๋ก ํ๋กํผํฐ ํ ๋น ๊ฐ๋ฅ
์ ํ๋ฆฌ์ผ์ด์
์ ์ํ๋ ๊ฐ์ ์
๋ ฅ์ด ์ฃผ์ด์ง๋ฉด ํญ์ ๊ฐ์ ์ถ๋ ฅ์ ๋ฐํํ๋ ์์ ํจ์๋ฅผ ํตํด ์ ๋ฌํฉ๋๋ค.
๋ ๋ช
๋ นํ ํ๋ฆ ์ ์ด๋ณด๋ค ์๋ก์ด ํจ์๋ฅผ ๋ง๋ค๊ฑฐ๋ ๊ณ์ฐํ๊ธฐ ์ํด ๋ ์ด์์ ํจ์๋ฅผ ์กฐํฉํ์ฌ ํฉ์ฑ ํจ์๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํฉ๋๋ค. ex) ๋ฉ์๋ ์ฒด์ด๋
Stream์ด๋ ์ ์ธํ์ผ๋ก ๋ฐ์ดํฐ Collection์ ๋ฐ๋ณต์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ API์
๋๋ค.
Lambda์์ ์ง์ํ๋ฉฐ ์ค๊ฐ ์ฐ์ฐ(filter, map...)๊ณผ ์ต์ข
์ฐ์ฐ(foreach, count, collect...)์ด ์์ต๋๋ค.
์ฌ๋ฌ ์ฐ์ฐ์ ์กฐ๋ฆฝํด์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ด ์ข์ต๋๋ค.
// Java 8 ์ด์
Iterator<String> iter = items.iterator();
while(iter.hasNext()) {
if(iter.next()!=null){
System.out.println(iter.next());
}
}
// Java 8 ์ดํ
Stream<String> stream = list.stream();
stream.filter(item->item!=null).forEach(item -> System.out.println(item));
๋ถํ ์ด ์ ์ด๋ฃจ์ด์ง ์ ์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ด๊ฑฐ๋, ์ฐ์ฐ ์์
์ด ๋
๋ฆฝ์ ์ด๋ฉด์ CPU ์ฌ์ฉ๋ฅ ์ด ๋์ ์์
์ ์ ํฉํฉ๋๋ค.
ํ์ง๋ง Parallel()์ ๊ณต์ ๋ thread pool์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ฅ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ด์ ์ฃผ์ ๊น๊ฒ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
โ
Collection vs Stream
๐ก Collection
๋ชจ๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๋ ์๋ฃ๊ตฌ์กฐ๋ก, ์ธ๋ถ ๋ฐ๋ณต์ ํตํด ์ฌ์ฉ์๊ฐ ์์
๋ฐ๋ณต ์์
์ ๊ฑฐ์ณ ์์๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. (for-each๋ฌธ)
Collection์ ์ถ๊ฐํ๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ๊ณ์ฐ์ด ์๋ฃ๋์ด ์์ด์ผ ํฉ๋๋ค.
์ธ๋ถ ๋ฐ๋ณต์ ๋ช
์์ ์ผ๋ก Collection ํญ๋ชฉ์ ํ๋์ฉ ๊ฐ์ ธ์์ ์ฒ๋ฆฌํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ต์ ํ์๋ ๋ถ๋ฆฌํฉ๋๋ค.
Collection์์ ๋ณ๋ ฌ์ฑ์ ์ด์ฉํ๋ ค๋ฉด ์ง์ synchronized ๋ฅผ ํตํด ๊ด๋ฆฌํด์ผ ํฉ๋๋ค.
๐ก Stream
์์ฒญํ ๋๋ง ์์๋ฅผ ๊ณ์ฐํ๋ ๋ฐฉ์์ผ๋ก, ๋ด๋ถ ๋ฐ๋ณต์ ์ฌ์ฉํ๋ฏ๋ก ์ถ์ถ ์์๋ง ์ ์ธํด์ฃผ๋ฉด ์์์ ๋ฐ๋ณต ์ฒ๋ฆฌ๋ฅผ ์งํํ๊ฒ ๋ฉ๋๋ค.
๋ด๋ถ ๋ฐ๋ณต์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ํตํด ์ต์ ํ๋ ์์๋ก ์ฒ๋ฆฌํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ด ๋ ์ข์ต๋๋ค.
์คํธ๋ฆผ์ ์์๋ฅผ ์ถ๊ฐ, ์ ๊ฑฐํ๋ ์์
์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
๐ Collection์ ์์
ํ์ผ์ ์ ์ฅํ์ฌ ์ฌ์ํ๋ ํ๋ ์ด์ด๋ผ๋ฉด, Stream์ ํ์ํ ๋ ๊ฒ์ํด์ ๋ฃ๋ ์คํธ๋ฆฌ๋ฐ ์๋น์ค๋ผ๊ณ ์๊ฐํ๋ฉด ์ฝ์ต๋๋ค.
ํ์ดํ๋ผ์ด๋์ด ๊ฐ๋ฅํ ์ฐ์ฐ์ผ๋ก ์คํธ๋ฆผ์ ๋ฐํํฉ๋๋ค.
filter(Predicate) // Predicate๋ฅผ ์ธ์๋ก ๋ฐ์ true์ธ ์์๋ฅผ ํฌํจํ ์คํธ๋ฆผ ๋ฐํ
distinct() // ์ค๋ณต ํํฐ๋ง
limit(n) // ์ฃผ์ด์ง ์ฌ์ด์ฆ ์ดํ ํฌ๊ธฐ๋ฅผ ๊ฐ๋ ์คํธ๋ฆผ ๋ฐํ
skip(n) // ์ฒ์ ์์ n๊ฐ ์ ์ธํ ์คํธ๋ฆผ ๋ฐํ
map(Function) // ๋งคํ ํจ์์ result๋ก ๊ตฌ์ฑ๋ ์คํธ๋ฆผ ๋ฐํ
flatMap() // ์คํธ๋ฆผ์ ์ฝํ
์ธ ๋ก ๋งคํํจ. map๊ณผ ๋ฌ๋ฆฌ ํ๋ฉดํ๋ ์คํธ๋ฆผ ๋ฐํ
์คํธ๋ฆผ์ ๋ซ๋ ์ฐ์ฐ์ผ๋ก ์ค๊ฐ ์ฐ์ฐ ๊ฐ์ ํ๊บผ๋ฒ์ ์ฒ๋ฆฌํฉ๋๋ค.
(boolean) allMatch(Predicate) // ๋ชจ๋ ์คํธ๋ฆผ ์์๊ฐ Predicate์ ์ผ์นํ๋์ง ๊ฒ์ฌ
(boolean) anyMatch(Predicate) // ํ๋๋ผ๋ ์ผ์นํ๋ ์์๊ฐ ์๋์ง ๊ฒ์ฌ
(boolean) noneMatch(Predicate) // ๋งค์น๋๋ ์์๊ฐ ์๋์ง ๊ฒ์ฌ
(Optional) findAny() // ํ์ฌ ์คํธ๋ฆผ์์ ์์์ ์์ ๋ฐํ
(Optional) findFirst() // ์คํธ๋ฆผ์ ์ฒซ๋ฒ์งธ ์์
reduce() // ๋ชจ๋ ์คํธ๋ฆผ ์์๋ฅผ ์ฒ๋ฆฌํด ๊ฐ์ ๋์ถ. ๋ ๊ฐ์ ์ธ์๋ฅผ ๊ฐ์ง
collect() // ์คํธ๋ฆผ์ reduceํ์ฌ list, map, ์ ์ ํ์ ์ปฌ๋ ์
์ ๋ง๋ฌ
(void) forEach() // ์คํธ๋ฆผ ๊ฐ ์์๋ฅผ ์๋นํ๋ฉฐ ๋๋ค ์ ์ฉ
(Long) count // ์คํธ๋ฆผ ์์ ๊ฐ์ ๋ฐํ