๐ฆ chap4. ์คํธ๋ฆผ ์๊ฐ
์ปฌ๋ ์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ฃนํํ๊ณ ์ฒ๋ฆฌํ ์ ์์ผ๋ฉฐ ๋๋ถ๋ถ์ ํ๋ก๊ทธ๋๋ฐ ์์ ์ ์ฌ์ฉ๋๋ค.
๊ทธ๋ฌ๋ ์๋ฒฝํ ์ปฌ๋ ์ ๊ด๋ จ ์ฐ์ฐ์ ์ง์ํ๋ ค๋ฉด ๋ฉ์๋ค.
SQL ์ง์์์๋ ์ ์ธํ์ผ๋ก ์ฐ์ฐ์ ํํํ ์ ์์ผ๋ฉฐ ๊ตฌํ์ ์๋์ผ๋ก ์ ๊ณต๋๋ค.
1
SELECT name FROM dishes WHERE calorie < 400
์ปฌ๋ ์ ์ ์์๊ฐ ๋ง๋ค๋ฉด? ๋ณ๋ ฌ๋ก ์ปฌ๋ ์ ์ ์ฒ๋ฆฌํด์ผ ํ๋ค.
๊ทธ๋ฌ๋ ๋จ์ ๋ฐ๋ณต ์ฒ๋ฆฌ ์ฝ๋์ ๋นํด ๋ณ๋ ฌ ์ฒ๋ฆฌ ์ฝ๋๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๋ณต์กํ๊ณ ์ด๋ ค์ฐ๋ฉฐ ๋๋ฒ๊น ์ด ํ๋ค๋ค.
4.1 ์คํธ๋ฆผ์ด๋ ๋ฌด์์ธ๊ฐ?
์คํธ๋ฆผ์ ์๋ฐ 8 API ์ ์ถ๊ฐ๋ ๊ธฐ๋ฅ์ด๋ค.
์คํธ๋ฆผ์ ์ฌ์ฉํ๋ฉด ์ ์ธํ์ผ๋ก ์ปฌ๋ ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
๋ฉํฐ์ค๋ ๋ ์ฝ๋๋ฅผ ๊ตฌํํ์ง ์์๋ ๋ฐ์ดํฐ๋ฅผ ํฌ๋ช ํ๊ฒ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
List<Dish> lowCaloricDishes = new ArrayList<>();
for(Dish dish: menu) {
if(dish.getCalories() < 400) {
lowCaloricDishes.add(dish);
}
}
Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
public int compare(Dish dish1, Dish dish2) {
return Integer.compare(dish1.getCalories(), dish2.getCalories());
}
});
List<String> lowCaloricDishesName = new ArrayList<>();
for(Dish dish: lowCaloricDishes) {
lowCaloricDishesName.add(dish.getName());
}
์ด ์ฝ๋์์๋ lowCaloricDishes ๋ผ๋ ์ปจํ
์ด๋ ์ญํ ๋ง ํ๋ ์ค๊ฐ ๋ณ์์ธ ๊ฐ๋น์ง ๋ณ์
๋ฅผ ์ฌ์ฉํ๋ค.
์๋ฐ 8์์๋ ์ด๋ฐ ์ธ๋ถ ๊ตฌํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์คํธ๋ฆผ) ๋ด์์ ๋ชจ๋ ์ฒ๋ฆฌํ๋ค.
1
2
3
4
5
6
List<String> lowCaloricDishesName =
menu.stream()
.filter(d -> d.getCalories() < 400)
.sorted(comapring(Dish::getCalories))
.map(Dish::getName)
.collect(toList());
๋ง์ฝ stream()
์ parallelStream()
์ผ๋ก ๋ฐ๊พธ๋ฉด ๋ณ๋ ฌ ์คํ์ด ๊ฐ๋ฅํ๋ค.
1
2
3
4
5
6
List<String> lowCaloricDishesName =
menu.parallelStream()
.filter(d -> d.getCalories() < 400)
.sorted(comapring(Dish::getCalories))
.map(Dish::getName)
.collect(toList());
์คํธ๋ฆผ์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ํํธ์จ์ด๊ณตํ์ ์ผ๋ก ๋ค์ํ ์ด๋์ ์ค๋ค.
- ์ ์ธํ์ผ๋ก ์ฝ๋๋ฅผ ๊ตฌํํ ์ ์๋ค.
- ์ด๋ป๊ฒ ๋์์ ๊ตฌํํ ์ง ์ง์ ํ ํ์ ์์ด ๋์์ ์ํ์ ์ง์ ํ๋ค.
- ์ ์ธํ ์ฝ๋์ ๋์ ํ๋ผ๋ฏธํฐํ, ๋๋ค๋ฅผ ์ด์ฉํ์ฌ ์ฝ๊ฒ ์ฝ๋ ๊ตฌํ์ด ๊ฐ๋ฅํ๊ณ ์๊ตฌ์ฌํญ์ ์ฝ๊ฒ ๋์ํ ์ ์๋ค.
- ๋ณต์กํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๋ง๋ค ์ ์๋ค.
- ์ฌ๋ฌ ์ฐ์ฐ์ ์ฐ๊ฒฐํด๋ ๊ฐ๋ ์ฑ๊ณผ ๋ช ํ์ฑ์ด ์ ์ง๋๋ค.
filter, sorted, map, colllect ์ ๊ฐ์ ์ฐ์ฐ์ ๊ณ ์์ค ๋น๋ฉ ๋ธ๋ก์ผ๋ก ์ด๋ฃจ์ด์ ธ ํน์ ์ค๋ ๋ฉ ๋ชจ๋ธ์ ์ ํ๋์ง ์๊ณ ์์ ๋กญ๊ฒ ์ด๋ค ์ํฉ์์๋ ์ฌ์ฉํ ์ ์๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ๋ณ๋ ฌ ์ฒ๋ฆฌ์์๋ ์ค๋ ๋์ ๋ฝ์ ๊ฑฑ์ ํ ํ์๊ฐ ์์ด์ง๋ค.
4.2 ์คํธ๋ฆผ ์์ํ๊ธฐ
์๋ฐ 8 ์ปฌ๋ ์
์๋ ์คํธ๋ฆผ์ ๋ฐํํ๋ stream
๋ฉ์๋๊ฐ ์ถ๊ฐ๋๋ค.
์คํธ๋ฆผ์ด๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ฐ์ฐ์ ์ง์ํ๋๋ก ์์ค์์ ์ถ์ถ๋ ์ฐ์๋ ์์
๋ผ๊ณ ์ ์ํ ์ ์๋ค.
- ์ฐ์๋ ์์
- ์ปฌ๋ ์ ์ฒ๋ผ ํน์ ์์ ํ์์ผ๋ก ์ด๋ฃจ์ด์ง ์ฐ์๋ ๊ฐ ์งํฉ์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
- ์ปฌ๋ ์ ์ ์๋ฃ๊ตฌ์กฐ์ด๊ธฐ ๋๋ฌธ์ ์๊ณต๊ฐ ๋ณต์ก์ฑ๊ณผ ๊ด๋ จ๋ ์์ ์ ์ฅ ๋ฐ ์ ๊ทผ ์ฐ์ฐ์ด ์ฃผ๊ฐ ๋๋ค.
- ๋ฐ๋ฉด ์คํธ๋ฆผ์ ํํ ๊ณ์ฐ์์ด ์ฃผ๋ฅผ ์ด๋ฃฌ๋ค.
- ์ปฌ๋ ์ ์ ์ฃผ์ ๋ ๋ฐ์ดํฐ, ์คํธ๋ฆผ์ ์ฃผ์ ๋ ๊ณ์ฐ์ด๋ค.
- ์์ค
- ์คํธ๋ฆผ์ ์ปฌ๋ ์ , ๋ฐฐ์ด, I/O ์์ ๋ฑ์ ๋ฐ์ดํฐ ์ ๊ณต ์์ค๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์๋นํ๋ค.
- ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ฐ์ฐ
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ ์ง์ํ๋ ์ฐ์ฐ๊ณผ DB์ ๋น์ทํ ์ฐ์ฐ์ ์ง์ํ๋ค.
filter
map
reduce
find
match
sort
๋ฑ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ ์ ์๋ค.
- ํ์ดํ๋ผ์ด๋
- ๋๋ถ๋ถ์ ์คํธ๋ฆผ ์ฐ์ฐ์ ์คํธ๋ฆผ ์์ฐ์ ๋ฐํํ๋ค. ์ด๋ ์คํธ๋ฆผ ์ฐ์ฐ๋ผ๋ฆฌ ์ฐ๊ฒฐํด์ ์ปค๋ค๋ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ ์ ์๋๋ก ํ๋ค.
- Laziness, Short-Circuiting ๊ฐ์ ์ต์ ํ๋ ๊ฐ๋ฅํ๋ค.
- ๋ด๋ถ ๋ฐ๋ณต
- ๋ฐ๋ณต์๋ฅผ ์ด์ฉํ์ฌ ๋ช ์์ ์ผ๋ก ๋ฐ๋ณตํ๋ ์ปฌ๋ ์ ๊ณผ ๋ฌ๋ฆฌ ์คํธ๋ฆผ์ ๋ด๋ถ ๋ฐ๋ณต์ ์ง์ํ๋ค.
4.3 ์คํธ๋ฆผ๊ณผ ์ปฌ๋ ์
๋ฐ์ดํฐ๋ฅผ ์ธ์ ๊ณ์ฐํ๋๋๊ฐ ์ปฌ๋ ์ ๊ณผ ์คํธ๋ฆผ์ ๊ฐ์ฅ ํฐ ์ฐจ์ด๋ค.
์ปฌ๋ ์ ์ ํ์ฌ ์๋ฃ๊ตฌ์กฐ๊ฐ ํฌํจํ๋ ๋ชจ๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
์ฆ, ์ปฌ๋ ์ ์ ๋ชจ๋ ์์๋ ์ปฌ๋ ์ ์ ์ถ๊ฐํ๊ธฐ ์ ์ ๊ณ์ฐ๋์ด์ผ ํ๋ค.
์คํธ๋ฆผ์ ์ด๋ก ์ ์ผ๋ก ์์ฒญํ ๋๋ง ์์๋ฅผ ๊ณ์ฐํ๋ ๊ณ ์ ๋ ์๋ฃ๊ตฌ์กฐ๋ค.
์์ฐ์์ ์๋น์ ๊ด๊ณ๋ฅผ ํ์ฑํ๊ณ , ๊ฒ์ผ๋ฅด๊ฒ ๋ง๋ค์ด์ง๋ ์ปฌ๋ ์ ๊ณผ ๊ฐ๋ค.
4.3.1 ๋ฑ ํ ๋ฒ๋ง ํ์ํ ์ ์๋ค.
์คํธ๋ฆผ์ ํ ๋ฒ๋ง ํ์ํ ์ ์๋ค. ํ์๋ ์คํธ๋ฆผ์ ์์๋ ์๋น๋๋ค.
1
2
3
4
List<String> title = Arrays.asList("Java8", "In", "Action");
Stream<String> s = title.stream();
s.forEach(System.out::println);
s.forEach(System.out::println); // throws IllegalStateException
4.3.2 ์ธ๋ถ ๋ฐ๋ณต๊ณผ ๋ด๋ถ ๋ฐ๋ณต
- ์ปฌ๋ ์ ์ธํฐํ์ด์ค - ์ธ๋ถ ๋ฐ๋ณต
์ฌ์ฉ์๊ฐ ์ง์ ์์๋ฅผ ๋ฐ๋ณตํด์ผ ํ๋ค.
1
2
3
4
List<String> names = new ArrayList<>();
for(Dish dish: menu) {
names.add(dish.getName());
}
- ์คํธ๋ฆผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ - ๋ด๋ถ ๋ฐ๋ณต
ํจ์์ ์ด๋ค ์์ ์ ์ํํ ์ง๋ง ์ง์ ํ๋ฉด ๋ชจ๋ ๊ฒ์ด ์์์ ์ฒ๋ฆฌ๋๋ค.
1
2
3
List<String> names = menu.stream()
.map(Dish::getName)
.collect(toList());
4.4 ์คํธ๋ฆผ ์ฐ์ฐ
- ์ค๊ฐ ์ฐ์ฐ
์ฐ๊ฒฐํ ์ ์๋ ์คํธ๋ฆผ ์ฐ์ฐ
- ์ต์ข ์ฐ์ฐ
์คํธ๋ฆผ์ ๋ซ๋ ์ฐ์ฐ
4.4.1 ์ค๊ฐ ์ฐ์ฐ
์ค๊ฐ ์ฐ์ฐ์ ๋จ๋ง ์ฐ์ฐ์ ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ ์คํํ๊ธฐ ์ ๊น์ง๋ ์๋ฌด ์ฐ์ฐ๋ ์ํํ์ง ์๋๋ค (Lazy)
1
2
3
4
5
6
7
8
9
10
11
12
13
List<String> names =
menu.stream()
.fliter(dish -> {
System.out.println("filtering:" + dish.getName());
return dish.getCalories() > 300;
})
.map(dish -> {
System.out.println("mapping:" + dish.getName());
return dish.getName();
)}
.limit(3)
.collect(toList());
System.out.println(names);
- ์ถ๋ ฅ ๊ฒฐ๊ณผ
1
2
3
4
5
6
7
8
// output
filtering:pork
mapping:pork
filtering:beef
mapping:beef
filtering:chicken
mapping:chicken
[pork, beef, chicken]
์คํธ๋ฆผ์ ๊ฒ์ผ๋ฅธ ํน์ฑ์ผ๋ก ๋ช ๊ฐ์ง ์ต์ ํ ํจ๊ณผ๋ฅผ ์ป์ ์ ์์๋ค.
- 300 ์นผ๋ก๋ฆฌ๊ฐ ๋๋ ์๋ฆฌ๋ ์ฌ๋ฌ ๊ฐ์ง๋ง ์ค์ง ์ฒ์ 3๊ฐ๋ง ์ ํ๋์๋ค. (์ผํธ์ํท)
- filter์ map์ ์๋ก ๋ค๋ฅธ ์ฐ์ฐ์ด์ง๋ง ํ ๊ณผ์ ์ผ๋ก ๋ณํฉ๋์๋ค. (๋ฃจํํจ์ )
4.4.2 ์ต์ข ์ฐ์ฐ
์ต์ข ์ฐ์ฐ์ ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์์ ๊ฒฐ๊ณผ๋ฅผ ๋์ถํ๋ค.
๋ณดํต List
Integer
void
๋ฑ ์คํธ๋ฆผ ์ด์ธ์ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ๋๋ค.
4.4.3 ์คํธ๋ฆผ ์ด์ฉํ๊ธฐ
์คํธ๋ฆผ์ ์ด์ฉ ๊ณผ์ ์ ์ธ ๊ฐ์ง๋ก ์์ฝํ ์ ์๋ค.
- ์ง์๋ฅผ ์ํํ ๋ฐ์ดํฐ ์์ค (์ปฌ๋ ์ )
- ์ค๊ฐ ์ฐ์ฐ ์ฐ๊ฒฐ
- ์ต์ข ์ฐ์ฐ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ฌ
์ค๊ฐ ์ฐ์ฐ
1
filter, map, limit, sorted, distinct
์ต์ข ์ฐ์ฐ
1
forEach, count, collect