๐ฆ chap5. ์คํธ๋ฆผ ํ์ฉ
chap5. ์คํธ๋ฆผ ํ์ฉ
5.1 ํํฐ๋ง
5.1.1 ํ๋ ๋์ผ์ดํธ๋ก ํํฐ๋ง
์คํธ๋ฆผ ์ธํฐํ์ด์ค๋ filter ๋ฉ์๋๋ฅผ ์ง์ํ๋ค.
filter ๋ ํ๋ ๋์ผ์ดํธ๋ฅผ ์ธ์๋ก ๋ฐ์ ํ๋ ๋์ผ์ดํธ์ ์ผ์นํ๋ ๋ชจ๋ ์์๋ฅผ ํฌํจํ๋ ์คํธ๋ฆผ์ ๋ฐํํ๋ค.
1
2
3
List<Dish> vegetarianMenu = menu.stream()
.filter(Dish::isVegetarian) // ์ฑ์ ์๋ฆฌ์ธ์ง ํ์ธํ๋ ๋ฉ์๋ ์ฐธ์กฐ
.collect(toList());
5.1.2 ๊ณ ์ ์์ ํํฐ๋ง
๊ณ ์ ์์๋ก ์ด๋ฃจ์ด์ง ์คํธ๋ฆผ์ ๋ฐํํ๋ distinct ๋ฉ์๋๋ฅผ ์ง์ํ๋ค.
๊ณ ์ ์ฌ๋ถ๋ ๊ฐ์ฒด์ hashCode, equals ๋ก ๊ฒฐ์ ๋๋ค.
1
2
3
4
5
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream()
.filter(i -> i % 2 == 0)
**.distinct()**
.forEach(System.out::println);
์ด ์ฝ๋๋ ๋ฆฌ์คํธ์ ๋ชจ๋ ์ง์๋ฅผ ์ ํํ๊ณ ์ค๋ณต์ ํํฐ๋งํ๋ค.
5.2 ์คํธ๋ฆผ ์ฌ๋ผ์ด์ฑ
5.2.1 ํ๋ ๋์ผ์ดํธ๋ฅผ ์ด์ฉํ ์ฌ๋ผ์ด์ฑ
์๋ฐ 9๋ ์คํธ๋ฆผ์ ์์๋ฅผ ์ ํํ ์ ์๋๋ก takeWhile
, dropWhile
์ด๋ผ๋ ๋ฉ์๋๋ฅผ ์ง์ํ๋ค.
TAKEWHILE ํ์ฉ
takeWhile
์ ์ด์ฉํ๋ฉด ๋ฌดํ ์คํธ๋ฆผ์ ํฌํจํ ๋ชจ๋ ์คํธ๋ฆผ์ ํ๋ ๋์ผ์ดํธ๋ฅผ ์ ์ฉํด ์คํธ๋ฆผ์ ์ฌ๋ผ์ด์คํ ์ ์๋ค.
ํนํ ๋ฆฌ์คํธ๊ฐ ์ด๋ฏธ ์ ๋ ฌ๋์ด ์๋ค๋ ์ฌ์ค์ ์ด์ฉํด ๋ฐ๋ณต ์์ ์ ์ค๋จํ ์ ์๋ค.
1
2
3
4
List<Dish> slicedMenu1
= specialMenu.stream()
.takeWhile(dish -> dish.getCalories() < 320)
.collect(toList());
DROPWHILE ํ์ฉ
dropWhile
์ takeWhile
์ ์ ๋ฐ๋์ ์์
์ ์ํํ๋ค.
dropWhile
์ ํ๋ ๋์ผ์ดํธ๊ฐ ์ฒ์์ผ๋ก ๊ฑฐ์ง์ด ๋๋ ์ง์ ๊น์ง ๋ฐ๊ฒฌ๋ ์์๋ฅผ ๋ฒ๋ฆฐ๋ค.
๊ทธ๋ฆฌ๊ณ ๋จ์ ์์๋ฅผ ๋ฐํํ๋ค.
1
2
3
4
List<Dish> slicedMenu2
= specialMenu.stream()
.dropWhile(dish -> dish.getCalories() < 320)
.collect(toList());
5.2.2 ์คํธ๋ฆผ ์ถ์
์ฃผ์ด์ง ๊ฐ ์ดํ์ ํฌ๊ธฐ๋ฅผ ๊ฐ๋ ์๋ก์ด ์คํธ๋ฆผ์ ๋ฐํํ๋ limit(n)
๋ฉ์๋๋ฅผ ์ง์ํ๋ค.
์คํธ๋ฆผ์ด ์ ๋ ฌ๋์ด ์์ผ๋ฉด ์ต๋ ์์ n๊ฐ๋ฅผ ๋ฐํํ ์ ์๋ค.
1
2
3
4
List<Dish> dishes = specialMenu.stream()
.filter(dish -> dish.getCalories() > 300)
.limit(3)
.collect(toList());
ํ๋ ๋์ผ์ดํธ์ ์ผ์นํ๋ ์ฒ์ ์ธ ์์๋ฅผ ์ ํํ ๋ค์์ ์ฆ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
5.2.3 ์์ ๊ฑด๋๋ฐ๊ธฐ
์ฒ์ n๊ฐ ์์๋ฅผ ์ ์ธํ ์คํธ๋ฆผ์ ๋ฐํํ๋ skip(n)
๋ฉ์๋๋ฅผ ์ง์ํ๋ค.
n๊ฐ ์ดํ์ ์์๋ฅผ ํฌํจํ๋ ์คํธ๋ฆผ์์ ํธ์ถํ๋ฉด ๋น ์คํธ๋ฆผ์ด ๋ฐํ๋๋ค.
1
2
3
4
List<Dish> dishes = menu.stream()
.filter(d -> d.getCalories() > 300)
.skip(2)
.collect(toList());
5.3 ๋งคํ
5.3.1 ์คํธ๋ฆผ์ ๊ฐ ์์์ ํจ์ ์ ์ฉํ๊ธฐ
ํจ์๋ฅผ ์ธ์๋ก ๋ฐ๋ map
๋ฉ์๋๋ฅผ ์ง์ํ๋ค.
์ธ์๋ก ์ ๊ณต๋ ํจ์๋ ๊ฐ ์์์ ์ ์ฉ๋๋ฉฐ ๊ทธ ๊ฒฐ๊ณผ๊ฐ ์๋ก์ด ์์๋ก ๋งคํ๋๋ค.
1
2
3
List<String> dishNames = menu.stream()
.map(Dish::getName)
.collect(toList());
getName
์ ๋ฌธ์์ด์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ map
์ ์ถ๋ ฅ ์คํธ๋ฆผ์ Stream<String>
ํ์์ ๊ฐ๋๋ค.
1
2
3
4
List<String> words = Arrays.asList("Modern", "Java", "In", "Action");
List<Integer> wordLengths = words.stream()
.map(String::length)
.collect(toList());
๊ฐ ๋จ์ด๊ฐ ํฌํจํ๋ ๊ธ์ ์์ ๋ฆฌ์คํธ๋ฅผ ๋ฐํํ๋ค.
1
2
3
4
List<Integer> dishNameLengths = menu.stream()
.map(Dish::getName)
**.map(String::length)**
.collect(toList());
์ด๋ฒ์ ๊ฐ ์๋ฆฌ๋ช ์ ๊ธธ์ด๋ฅผ ํฌํจํ๋ ๋ฆฌ์คํธ๋ฅผ ๋ฐํํ๋ค.
5.3.2 ์คํธ๋ฆผ ํ๋ฉดํ
๋ฆฌ์คํธ์์ ๊ณ ์ ๋ฌธ์๋ก ์ด๋ฃจ์ด์ง ๋ฆฌ์คํธ๋ฅผ ๋ฐํํด๋ณด์.
[โHelloโ, โWorldโ] ๋ฆฌ์คํธ๊ฐ ์๋ค๋ฉด ๊ฒฐ๊ณผ๋ก [โHโ, โeโ, โlโ, โoโ, โWโ, โrโ, โdโ] ๋ฅผ ํฌํจํ๋ ๋ฆฌ์คํธ๊ฐ ๋ฐํ๋์ด์ผ ํ๋ค.
1
2
3
4
words.stream()
.map(word -> word.split(""))
.distinct()
.collect(toList());
distinct ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์์ง๋ง map ์ผ๋ก ์ ๋ฌํ ๋๋ค๋ String[]
์ ๋ฐํํ๋ค๋ ์ ์ด ๋ฌธ์ ์ด๋ค.
์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ฒ์ ๋ฌธ์์ด์ ์คํธ๋ฆผ์ ํํํ Stream<String>
์ด๋ค.
map๊ณผ Arrays.stream ํ์ฉ
๋ฐฐ์ด ์คํธ๋ฆผ ๋์ ๋ฌธ์์ด ์คํธ๋ฆผ์ด ํ์ํ๋ค.
๋ฌธ์์ด์ ๋ฐ์ ์คํธ๋ฆผ์ ๋ง๋๋ Arrrays.stream()
๋ฉ์๋๊ฐ ์๋ค.
1
2
String[] arrayOfWords = {"Goodbye", "World"};
Stream<String> streamOfwords = Arrays.stream(arrayOfWords);
์ด ํ์ดํ๋ผ์ธ์ Arrays.stream()
๋ฉ์๋๋ฅผ ์ ์ฉํด๋ณด์.
1
2
3
4
5
words.stream()
.map(word -> word.split("")) // ๊ฐ ๋จ์ด๋ฅผ ๊ฐ๋ณ ๋ฌธ์์ด ๋ฐฐ์ด๋ก ๋ณํ
.map(Arrays::stream) // ๊ฐ ๋ฐฐ์ด์ ๋ณ๋์ ์คํธ๋ฆผ์ผ๋ก ์์ฑ
.distinct()
.collect(toList());
๊ฒฐ๊ตญ ์คํธ๋ฆผ ๋ฆฌ์คํธ๊ฐ ๋ง๋ค์ด์ง๋ฉด์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ง ์์๋ค.
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ๊ฐ ๋จ์ด๋ฅผ ๊ฐ๋ณ ๋ฌธ์์ด๋ก ์ด๋ฃจ์ด์ง ๋ฐฐ์ด๋ก ๋ง๋ ๋ค์์ ๊ฐ ๋ฐฐ์ด์ ๋ณ๋์ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ค์ด์ผ ํ๋ค.
flatMap ์ฌ์ฉ
flatMap
์ ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
1
2
3
4
5
6
List<String> uniqueCharacters =
words.stream()
.map(word -> word.split("")) // ๊ฐ ๋จ์ด๋ฅผ ๊ฐ๋ณ ๋ฌธ์๋ฅผ ํฌํจํ๋ ๋ฐฐ์ด๋ก ๋ณํ
.flatMap(Arrays::stream) // ์์ฑ๋ ์คํธ๋ฆผ์ ํ๋์ ์คํธ๋ฆผ์ผ๋ก ํ๋ฉดํ
.distinct()
.collect(toList());
flatMap ์ ๊ฐ ๋ฐฐ์ด์ ์คํธ๋ฆผ์ด ์๋๋ผ ์คํธ๋ฆผ์ ์ฝํ ์ธ ๋ก ๋งคํํ๋ค.
์ฆ ํ๋์ ํ๋ฉดํ๋ ์คํธ๋ฆผ์ ๋ฐํํ๋ค.
์คํธ๋ฆผ์ ๊ฐ ๊ฐ์ ๋ค๋ฅธ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ ๋ค์์ ๋ชจ๋ ์คํธ๋ฆผ์ ํ๋์ ์คํธ๋ฆผ์ผ๋ก ์ฐ๊ฒฐํ๋ ๊ธฐ๋ฅ์ ์ํํ๋ค.
5.4 ๊ฒ์๊ณผ ๋งค์นญ
5.4.1 ํ๋ ๋์ผ์ดํธ๊ฐ ์ ์ด๋ ํ ์์์ ์ผ์นํ๋์ง ํ์ธ
anyMatch
๋ ํ๋ ๋์ผ์ดํธ๊ฐ ์ฃผ์ด์ง ์คํธ๋ฆผ์์ ์ ์ด๋ ํ ์์์ ์ผ์นํ๋์ง ํ์ธํ๋ค.
1
2
3
if(menu.stream().anyMatch(Dish::isVegetarian)) {
System.out.println("The menu is (somewhat) vegetarian friendly!!");
}
boolean
์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ต์ข
์ฐ์ฐ์ด๋ค.
5.4.2 ํ๋ ๋์ผ์ดํธ๊ฐ ๋ชจ๋ ์์์ ์ผ์นํ๋์ง ๊ฒ์ฌ
allMatch
๋ ์คํธ๋ฆผ์ ๋ชจ๋ ์์๊ฐ ์ฃผ์ด์ง ํ๋ ๋์ผ์ดํธ์ ์ผ์นํ๋์ง ๊ฒ์ฌํ๋ค.
1
2
3
if(menu.stream().anyMatch(Dish::isVegetarian)) {
System.out.println("The menu is (somewhat) vegetarian friendly!!");
}
NONEMATCH
noneMatch
๋ allMatch
์ ๋ฐ๋ ์ฐ์ฐ์ ์ํํ๋ค.
์ฆ, ์ฃผ์ด์ง ํ๋ ๋์ผ์ดํธ์ ์ผ์นํ๋ ์์๊ฐ ์๋์ง ํ์ธํ๋ค.
1
2
boolean isHealthy = menu.stream()
.noneMatch(d -> d.getCalories >= 1000);
์ด ์ธ ๊ฐ์ง ๋ฉ์๋๋ ์คํธ๋ฆผ ์ผํธ์ํท ๊ธฐ๋ฒ์ ํ์ฉํ๋ค.
์ ์ฒด ์คํธ๋ฆผ์ ์ ์นํ์ง ์์๋๋ผ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๊ฒ์ด๋ค.
5.4.3 ์์ ๊ฒ์
findAny
๋ฉ์๋๋ ํ์ฌ ์คํธ๋ฆผ์์ ์์์ ์์๋ฅผ ๋ฐํํ๋ค.
1
2
3
4
Optional<Dish> dish =
menu.stream()
.filter(Dish::isVegetarian)
.findAny();
์ผํธ์ํท์ ์ด์ฉํด์ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ๋ ์ฆ์ ์คํ์ ์ข ๋ฃํ๋ค.
Optional์ด๋?
Optional<T>
ํด๋์ค๋ ๊ฐ์ ์กด์ฌ๋ ๋ถ์ฌ ์ฌ๋ถ๋ฅผ ํํํ๋ ์ปจํ
์ด๋ ํด๋์ค์ด๋ค.
null
์ด ์ฝ๊ฒ ์๋ฌ๋ฅผ ์ผ์ผํฌ ์ ์์ผ๋ฏ๋ก ์๋ฐ 8 ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค๊ณ์๊ฐ ๋ง๋ค์๋ค.
isPresent()
๋ Optional ์ด ๊ฐ์ ํฌํจํ๋ฉด ์ฐธ, ์์ผ๋ฉด ๊ฑฐ์ง์ด๋ค.ifPresent(Consumer<T> block)
์ ๊ฐ์ด ์์ผ๋ฉด ์ฃผ์ด์ง ๋ธ๋ก์ ์คํํ๋ค.T get()
์ ๊ฐ์ด ์กด์ฌํ๋ฉด ๊ฐ์ ๋ฐํํ๊ณ ์์ผ๋ฉดNoSuchElementException
์ ๋์ง๋ค.T orElse(T other)
์ ๊ฐ์ด ์์ผ๋ฉด ๊ฐ์ ๋ฐํํ๊ณ , ๊ฐ์ด ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ ๋ฐํํ๋ค.
5.4.4 ์ฒซ ๋ฒ์งธ ์์ ์ฐพ๊ธฐ
์ผ๋ถ ์คํธ๋ฆผ์๋ ๋ ผ๋ฆฌ์ ์ธ ์์ดํ ์์๊ฐ ์ ํด์ ธ ์์ ์ ์๋ค.
๋ค์์ ์ซ์ ๋ฆฌ์คํธ์์ 3์ผ๋ก ๋๋์ด ๋จ์ด์ง๋ ์ฒซ ๋ฒ์งธ ์ ๊ณฑ๊ฐ์ ๋ฐํํ๋ ์ฝ๋์ด๋ค.
1
2
3
4
5
6
List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> firstSquareDivisibleByTree =
someNumbers.stream()
.map(n -> n * n)
.filter(n -> n % 3 == 0)
.findFirst();
findFirst์ findAny ๋ ์ธ์ ์ฌ์ฉํ๋?
๋ ๋ฉ์๋๊ฐ ์ ๋ชจ๋ ํ์ํ๊ฐ?
๋ฐ๋ก ๋ณ๋ ฌ์ฑ ๋๋ฌธ์ด๋ค.
๋ณ๋ ฌ ์คํ์์๋ ์ฒซ ๋ฒ์งธ ์์๋ฅผ ์ฐพ๊ธฐ ์ด๋ ต๋ค.
๋ฐ๋ผ์ ์์์ ๋ฐํ ์์๊ฐ ์๊ด์๋ค๋ฉด ๋ณ๋ ฌ ์คํ์์๋ ์ ์ฝ์ด ์ ์ findAny
๋ฅผ ์ฌ์ฉํ๋ค.
5.5 ๋ฆฌ๋์ฑ
์คํธ๋ฆผ ์์๋ฅผ ์กฐํฉํด์ ๋ ๋ณต์กํ ์ง์๋ฅผ ํํํ๋ ๋ฐฉ๋ฒ์ ๋ฆฌ๋์ฑ ์ฐ์ฐ์ด๋ผ๊ณ ํ๋ค.
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด ์ฉ์ด๋ก๋ ์ด ๊ณผ์ ์ด ๋ง์น ์ข ์ด๋ฅผ ์์ ์กฐ๊ฐ์ด ๋ ๋๊น์ง ๋ฐ๋ณตํด์ ์ ๋ ๊ฒ๊ณผ ๋น์ทํ๋ค๋ ์๋ฏธ๋ก ํด๋(fold) ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
5.5.1 ์์์ ํฉ
๋ค์์ forEach
๋ฃจํ๋ฅผ ์ด์ฉํด์ ๋ฆฌ์คํธ์ ์ซ์ ์์๋ฅผ ๋ํ๋ ์ฝ๋์ด๋ค.
1
2
3
4
5
// ๋ฆฌ์คํธ์ ์ซ์ ์์์ ํฉ
int sum = 0;
for (int x : numbers) {
sum += x;
}
nubmers ์ ๊ฐ ์์๋ ๊ฒฐ๊ณผ์ ๋ฐ๋ณต์ ์ผ๋ก ๋ํด์ง๋ค.
์ด ์ฝ๋๋ฅผ ๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ ํ์ง ์๊ณ ๋ชจ๋ ์ซ์๋ฅผ ๊ณฑํ๋ ์ฐ์ฐ์ ๊ตฌํํ ์ ์๋ค๋ฉด
๋ค์์ฒ๋ผ reduce
๋ฅผ ์ด์ฉํด์ ์คํธ๋ฆผ์ ๋ชจ๋ ์์๋ฅผ ๋ํ ์ ์๋ค.
1
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
reduce
๋ ๋ ์์๋ฅผ ์ธ์๋ก ๊ฐ์ง๋ค.
- ์ด๊น๊ฐ 0
- ๋ ์์๋ฅผ ์กฐํฉํด์ ์๋ก์ด ๊ฐ์ ๋ง๋๋
BinaryOperator<T>
reduce
๋ ์คํธ๋ฆผ์ ์์๋ฅผ ์๋นํ์ฌ ๋์ ๊ฐ์ผ๋ก ๋๋ค๋ฅผ ๋ค์ ํธ์ถํ๋ค.
์ด๊น๊ฐ ์์
์ด๊น๊ฐ์ ๋ฐ์ง ์๋๋ก ์ค๋ฒ๋ก๋๋ reduce
๋ฅผ ์ดํด๋ณด์.
1
Optional<Integer> sum = numbers.stream().reduce((a, b) -> (a + b));
์คํธ๋ฆผ์ ์๋ฌด ์์๋ ์๋ ์ํฉ์์ ์ด๊น๊ฐ์ด ์์ผ๋ฏ๋ก reduce
๋ ํฉ๊ณ๋ฅผ ๋ฐํํ ์ ์๋ค.
๋ฐ๋ผ์ ํฉ๊ณ๊ฐ ์์์ ๊ฐ๋ฆฌํฌ ์ ์๋๋ก Optional
๋ก ๊ฐ์ผ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
5.5.2 ์ต๋๊ฐ๊ณผ ์ต์๊ฐ
๋ค์์ฒ๋ผ reduce
๋ฅผ ์ด์ฉํด์ ์คํธ๋ฆผ์ ์ต๋๊ฐ๊ณผ ์ต์๊ฐ์ ์ฐพ์ ์ ์๋ค.
1
Optional<Integer> max = numbers.stream().reduce(Integer::max);
1
Optional<Integer> min = numbers.stream().reduce(Integer::min);
5.6 ์ค์ ์ฐ์ต
- 2011๋ ์ ์ผ์ด๋ ๋ชจ๋ ํธ๋์ญ์ ์ ์ฐพ์ ๊ฐ์ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ฆฌํ์์ค.
- ๊ฑฐ๋์๊ฐ ๊ทผ๋ฌดํ๋ ๋ชจ๋ ๋์๋ฅผ ์ค๋ณต ์์ด ๋์ดํ์์ค.
- ์ผ์๋ธ๋ฆฌ์ง์์ ๊ทผ๋ฌดํ๋ ๋ชจ๋ ๊ฑฐ๋์๋ฅผ ์ฐพ์์ ์ด๋ฆ์์ผ๋ก ์ ๋ ฌํ์์ค.
- ๋ชจ๋ ๊ฑฐ๋์์ ์ด๋ฆ์ ์ํ๋ฒณ์์ผ๋ก ์ ๋ ฌํด์ ๋ฐํํ์์ค.
- ๋ฐ๋ผ๋ ธ์ ๊ฑฐ๋์๊ฐ ์๋๊ฐ?
- ์ผ์๋ธ๋ฆฌ์ง์ ๊ฑฐ์ฃผํ๋ ๊ฑฐ๋์์ ๋ชจ๋ ํธ๋์ญ์ ๊ฐ์ ์ถ๋ ฅํ์์ค.
- ์ ์ฒด ํธ๋์ญ์ ์ค ์ต๋๊ฐ์ ์ผ๋ง์ธ๊ฐ?
- ์ ์ฒด ํธ๋์ญ์ ์ค ์ต์๊ฐ์ ์ผ๋ง์ธ๊ฐ?
5.7 ์ซ์ํ ์คํธ๋ฆผ
1
2
3
int calories = menu.stream()
.map(Dish::getCalories)
.reduce(0, Integer::sum);
reduce ๋ฉ์๋๋ก ์คํธ๋ฆผ ์์์ ํฉ์ ๊ตฌํ๋ ์์ ์ด๋ค.
์ด ์ฝ๋์๋ ๋ฐ์ฑ ๋น์ฉ์ด ์จ์ด์๋ค.
๋ด๋ถ์ ์ผ๋ก ํฉ๊ณ๋ฅผ ๊ณ์ฐํ๊ธฐ ์ ์ Integer ๋ฅผ ๊ธฐ๋ณธํ์ผ๋ก ์ธ๋ฐ์ฑํด์ผ ํ๋ค.
1
2
3
int calories = menu.stream()
.map(Dish::getCalories)
.sum();
์ต์ ํ๋ฅผ ์ํด sum ๋ฉ์๋๋ฅผ ์ง์ ํธ์ถํ๊ณ ์ถ์ง๋ง ์ง์ ํธ์ถ์ ๋ถ๊ฐ๋ฅํ๋ค.
map
๋ฉ์๋๋ Stream<T>
๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ด๋ค.
์คํธ๋ฆผ์ ์์ ํ์์ Integer
์ด์ง๋ง ์ธํฐํ์ด์ค์๋ sum
๋ฉ์๋๊ฐ ์๋ค.
๋คํํ๋ ์คํธ๋ฆผ API ์ซ์ ์คํธ๋ฆผ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ๊ธฐ๋ณธํ ํนํ ์คํธ๋ฆผ์ ์ ๊ณตํ๋ค.
5.7.1 ๊ธฐ๋ณธํ ํนํ ์คํธ๋ฆผ
์๋ฐ 8์์๋ ์ธ ๊ฐ์ง ๊ธฐ๋ณธํ ํนํ ์คํธ๋ฆผ์ ์ ๊ณตํ๋ค.
IntStream
DoubleStream
LongStream
ํนํ ์คํธ๋ฆผ์ ์ค์ง ๋ฐ์ฑ ๊ณผ์ ์์ ์ผ์ด๋๋ ํจ์จ์ฑ๊ณผ ๊ด๋ จ ์์ผ๋ฉฐ ์คํธ๋ฆผ์ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ ์๋๋ค.
์ซ์ ์คํธ๋ฆผ์ผ๋ก ๋งคํ
์คํธ๋ฆผ์ ํนํ ์คํธ๋ฆผ์ผ๋ก ๋ณํํ ๋๋ mapToInt
mapToDouble
mapToLong
์ธ ๊ฐ์ง ๋ฉ์๋๋ฅผ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ค.
1
2
3
int calories = menu.stream()
.map(Dish::getCalories)
.sum();
mapToInt
๋ ๋ชจ๋ Integer ํ์ ์นผ๋ก๋ฆฌ๋ฅผ ์ถ์ถํ ๋ค์์ IntStream
์ ๋ฐํํ๋ค.
๋ฐ๋ผ์ IntStream
์์ ์ ๊ณตํ๋ sum
๋ฉ์๋๋ฅผ ์ด์ฉํด์ ์นผ๋ก๋ฆฌ ํฉ๊ณ๋ฅผ ๊ณ์ฐํ ์ ์๋ค.
์คํธ๋ฆผ์ด ๋น์ด์๋ค๋ฉด ๊ธฐ๋ณธ๊ฐ 0์ ๋ฐํํ๋ค.
๊ฐ์ฒด ์คํธ๋ฆผ์ผ๋ก ๋ณต์ํ๊ธฐ
์ซ์ ์คํธ๋ฆผ์ ๋ง๋ ๋ค์์ ์์ํ์ธ ํนํ๋์ง ์์ ์คํธ๋ฆผ์ผ๋ก ๋ณต์ํ ์ ์๋ค.
1
2
IntStream intStream = menu.stream().mapToInt(Dish::getCalories); // ์คํธ๋ฆผ์ ์ซ์ ์คํธ๋ฆผ์ผ๋ก ๋ณํ
Stream<Integer> stream = intStream.boxed(); // ์ซ์ ์คํธ๋ฆผ์ ์คํธ๋ฆผ์ผ๋ก ๋ณํ
๊ธฐ๋ณธ๊ฐ : OptionalInt
ํฉ๊ณ์์๋ 0์ด๋ผ๋ ๊ธฐ๋ณธ๊ฐ์ด ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ์์ง๋ง
IntStream
์์ ์ต๋๊ฐ์ ์ฐพ์ ๋๋ 0์ด๋ผ๋ ๊ธฐ๋ณธ๊ฐ ๋๋ฌธ์ ์๋ชป๋ ๊ฒฐ๊ณผ๊ฐ ๋์ถ๋ ์ ์๋ค.
์คํธ๋ฆผ์ ์์๊ฐ ์๋ ์ํฉ์ ๊ตฌ๋ณํ ์ ์๋๋ก Optioanl
์ฐธ์กฐ ํ์์ผ๋ก ํ๋ผ๋ฏธํฐํ ํ ์ ์๋ค.
1
2
3
OptionalInt maxCalories = menu.stream()
.mapToInt(Dish::getCalories)
.max();
OptionalInt
OptionalDouble
OptionalLong
์ธ ๊ฐ์ง ๊ธฐ๋ณธํ ํนํ ์คํธ๋ฆผ ๋ฒ์ ์ ์ ๊ณตํ๋ค.
1
int max = maxCalories.orElse(1); // ๊ฐ์ด ์์ ๋ ๊ธฐ๋ณธ ์ต๋๊ฐ์ ๋ช
์์ ์ผ๋ก ์ค์
5.7.2 ์ซ์ ๋ฒ์
ํน์ ๋ฒ์์ ์ซ์๋ฅผ ์ด์ฉํด์ผ ํ๋ ์ํฉ์ด ์์ฃผ ๋ฐ์ํ๋ค.
์๋ฐ 8์ IntStream
๊ณผ LongStream
์์๋ range
์ rangeClosed
๋ผ๋ ์ ์ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.
range
๋ ์์๊ฐ๊ณผ ์ข
๋ฃ๊ฐ์ด ๊ฒฐ๊ณผ์ ํฌํจ๋์ง ์๋ ๋ฐ๋ฉด
rangeClosed
๋ ์์๊ฐ๊ณผ ์ข
๋ฃ๊ฐ์ด ๊ฒฐ๊ณผ์ ํฌํจ๋๋ค๋ ์ ์ด ๋ค๋ฅด๋ค.
1
2
3
IntStream evenNumbers = IntStream.rangeClosed(1, 100) // [1, 100] ๋ฒ์
.filter(n -> n % 2 == 0); // ์ง์ ์คํธ๋ฆผ
System.out.println(evenNumbers.count());
์ด ์ฝ๋๋ 1๋ถํฐ 100๊น์ง์ ์ซ์๋ฅผ ๋ง๋ค๊ณ ์ง์๋ง ํํฐ๋งํ ํ ์ง์ 50๊ฐ๋ฅผ ๋ฐํํ๋ค.
5.7.3 ์ซ์ ์คํธ๋ฆผ ํ์ฉ : ํผํ๊ณ ๋ผ์ค ์
์ธ ์ ํํํ๊ธฐ
์ธ ์์๋ฅผ ๊ฐ๋ int ๋ฐฐ์ด์ ์ฌ์ฉํ๋ค. ์๋ฅผ ๋ค๋ฉด (3,4,5) ๋ฅผ new int[]{3, 4, 5} ๋ก ํํํ ์ ์๋ค.
์ข์ ํํฐ๋ง ์กฐํฉ
ํผ๋ผ๊ณ ๋ผ์ค ๊ณต์์ ๋ง์กฑํ๋ ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ๋ค.
1
Math.sqrt(a*a + b*b) % 1 == 0
1
filter(b -> Math.sqrt(a*a + b*b) % 1 == 0)
์งํฉ ์์ฑ
์ด์ ๋ง์ง๋ง ์ธ ๋ฒ์งธ ์๋ฅผ ์ฐพ์์ผ ํ๋ค.
map
์ ์ฌ์ฉํด์ ๊ฐ ์์๋ฅผ ํผํ๊ณ ๋ผ์ค ์๋ก ๋ณํํ ์ ์๋ค.
1
2
stream.filter(b -> Math.sqrt(a*a + b*b) % 1 == 0)
**.map(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)});**
b๊ฐ ์์ฑ
Stream.rangeClosed
๋ก ์ฃผ์ด์ง ๋ฒ์์ ์๋ฅผ ๋ง๋ค ์ ์๋ค.
1
2
3
4
**IntStream.rangeClosed(1, 100)**
.filter(b -> Math.sqrt(a*a + b*b) % 1 == 0)
.**boxed()**
****.map(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)});
๊ฐ์ฒด๊ฐ ์คํธ๋ฆผ์ ๋ฐํํ๋ IntStream
์ mapToObj
๋ฉ์๋๋ฅผ ์ด์ฉํด์ ์ฌ๊ตฌํ ํ๋ค.
1
2
3
IntStream.rangeClosed(1, 100)
**** .filter(b -> Math.sqrt(a*a + b*b) % 1 == 0)
**.mapToObj**(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)});
a๊ฐ ์์ฑ
๋ง์ง๋ง์ผ๋ก a๊ฐ์ ์์ฑํ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ฌ ์์ฑํ๋ค.
1
2
3
4
5
6
7
Stream<int[]> pythagoreanTriples =
IntStream.rangeClosed(1, 100).boxed()
.flatMap(a ->
IntStream.rangeClosed(a, 100)
.filter(b -> Math.sqrt(a*a + b*b) % 1 == 0)
.mapToObj(b -> new int[]{a, b, (int)Math.sqrt(a*a+b*b)})
);
์ฝ๋ ์คํ
limit ์ ์ด์ฉํด์ ์ผ๋ง๋ ๋ง์ ์ธ ์๋ฅผ ํฌํจํ๋ ์คํธ๋ฆผ์ ๋ง๋ค ๊ฒ์ธ์ง๋ง ๊ฒฐ์ ํ๋ฉด ๋๋ค.
1
2
3
pythagoreamTriples.limit(5)
.forEach(t ->
System.out.println(t[0] + ", " + t[1] + ", " + t[2]));
๊ฐ์ ํ ์ ?
ํ์ฌ ์ฝ๋์์๋ ์ ๊ณฑ๊ทผ์ ๋ ๋ฒ ๊ณ์ฐํ๋ค.
๋ฐ๋ผ์ ์ธ ์๋ฅผ ๋ง๋ ๋ค์์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ์กฐ๊ฑด์ ๋ง๋ ๊ฒฐ๊ณผ๋ง ํํฐ๋งํ๋ ๊ฒ์ด ๋ ์ต์ ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
1
2
3
4
5
6
Stream<double[]> pythagoreanTriples2 =
IntStream.rangeClosed(1, 100).boxed()
.flatMap(a -> IntStream.rangeClosed(a, 100)
.mapToObj(
b -> new double[]{a, b, Math.sqrt(a*a + b*b)}) // ๋ง๋ค์ด์ง ์ธ ์
.filter(t -> t[2] % 1 == 0); // ์ธ ์์ ์ธ ๋ฒ์งธ ์์๋ ๋ฐ๋์ ์ ์์ฌ์ผ ํ๋ค.
5.8 ์คํธ๋ฆผ ๋ง๋ค๊ธฐ
์ผ๋ จ์ ๊ฐ, ๋ฐฐ์ด, ํ์ผ, ํจ์๋ฅผ ์ด์ฉํ ๋ฌดํ ์คํธ๋ฆผ ๋ง๋ค๊ธฐ๊ฐ ๊ฐ๋ฅํ๋ค.
5.8.1 ๊ฐ์ผ๋ก ์คํธ๋ฆผ ๋ง๋ค๊ธฐ
์์์ ์๋ฅผ ์ธ์๋ก ๋ฐ๋ ์ ์ ๋ฉ์๋ Stream.of
๋ฅผ ์ด์ฉํด์ ์คํธ๋ฆผ์ ๋ง๋ค ์ ์๋ค.
1
2
Stream<String> stream = Stream.of("Modern ", "Java ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);
๋ค์์ฒ๋ผ empty
๋ฉ์๋๋ฅผ ์ด์ฉํด์ ์คํธ๋ฆผ์ ๋น์ธ ์ ์๋ค.
1
Stream<String> emptyStream = Stream.empty();
5.8.2 null์ด ๋ ์ ์๋ ๊ฐ์ฒด๋ก ์คํธ๋ฆผ ๋ง๋ค๊ธฐ
์๋ฐ 9์์๋ null
์ด ๋ ์ ์๋ ๊ฐ์ฒด๋ฅผ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ค ์ ์๋ ์๋ก์ด ๋ฉ์๋๊ฐ ์ถ๊ฐ๋์๋ค.
์๋ฅผ ๋ค์ด System.getProperty
๋ ํค์ ๋์๋๋ ์์ฑ์ด ์์ผ๋ฉด null
์ ๋ฐํํ๋ค.
์ด๋ฐ ๋ฉ์๋๋ฅผ ์คํธ๋ฆผ์ ํ์ฉํ๋ ค๋ฉด ๋ค์์ฒ๋ผ null
์ ๋ช
์์ ์ผ๋ก ํ์ธํด์ผ ํ๋ค.
1
2
3
String homeValue = System.getProperty("home");
Stream<String> homeValueStream
= homeValue == null ? Stream.empty() : Stream.of(value);
Stream.ofNullable
์ ์ด์ฉํด ๋ค์์ฒ๋ผ ๊ตฌํ ๊ฐ๋ฅํ๋ค.
1
2
Stream<String> homeValueStream
= Stream.ofNullable(System.getProperty("home"));
null์ด ๋ ์ ์๋ ๊ฐ์ฒด๋ฅผ ํฌํจํ๋ ์คํธ๋ฆผ์ flatMap
๊ณผ ํจ๊ป ์ฌ์ฉํ๋ ์ํฉ์์๋ ์ด ํจํด์ด ๋ ์ ์ฉํ ๊ฒ์ด๋ค.
1
2
3
Stream<String> values =
Stream.of("config", "home", "user")
.flatMap(key -> Stream.ofNullable(System.getProperty(key)));
5.8.3 ๋ฐฐ์ด๋ก ์คํธ๋ฆผ ๋ง๋ค๊ธฐ
[Arrays.stream](http://Arrays.stream)
์ ์ด์ฉํด์ ๋ฐฐ์ด์ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ค ์ ์๋ค.
1
2
int[] numbers = {2, 3, 5, 7, 11, 13};
int sum = Arrays.stream(numbers).sum(); // ํฉ๊ณ๋ 41
5.8.4 ํ์ผ๋ก ์คํธ๋ฆผ ๋ง๋ค๊ธฐ
ํ์ผ์ ์ฒ๋ฆฌํ๋ ๋ฑ์ I/O
์ฐ์ฐ์ ์ฌ์ฉํ๋ ์๋ฐ์ NIO API
๋ ์คํธ๋ฆผ API์ ํ์ฉํ ์ ์๋ค.
1
2
3
4
5
6
7
8
9
10
11
long uniqueWords = 0;
try(Stream<String> lines =
Files.lines(Paths.get("data.txt"), Charset.defaultCharset()))
{
uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" "))) // ๊ณ ์ ๋จ์ด์ ๊ณ์ฐ
.distinct() // ์ค๋ณต ์ ๊ฑฐ
.count(); // ๋จ์ด ์คํธ๋ฆผ ์์ฑ
}
catch(IOException e) {
// ํ์ผ์ ์ด๋ค๊ฐ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ์ฒ๋ฆฌํ๋ค.
}
5.8.5 ํจ์๋ก ๋ฌดํ ์คํธ๋ฆผ ๋ง๋ค๊ธฐ
ํจ์์์ ์คํธ๋ฆผ์ ๋ง๋ค ์ ์๋ ๋ ์ ์ ๋ฉ์๋ Stream.iterate
์ Stream.generate
๋ฅผ ์ ๊ณตํ๋ค.
์ด ์คํธ๋ฆผ์ ์์ฒญํ ๋๋ง๋ค ์ฃผ์ด์ง ํจ์๋ฅผ ์ด์ฉํด์ ๊ฐ์ ๋ง๋ ๋ค.
๋ฐ๋ผ์ ๋ฌด์ ํ์ผ๋ก ๊ฐ์ ๊ณ์ฐํ ์ ์๋ค.
๋ณดํต ๋ฌดํํ ๊ฐ์ ์ถ๋ ฅํ์ง ์๋๋ก limit(n)
ํจ์๋ฅผ ์ฐ๊ฒฐํด์ ์ฌ์ฉํ๋ค.
iterate ๋ฉ์๋
1
2
3
Stream.iterate(0, n -> n + 2)
.limit(10)
.forEach(System.out::println);
iterate
๋ฉ์๋๋ ์ด๊น๊ฐ๊ณผ ๋๋ค๋ฅผ ์ธ์๋ก ๋ฐ์์ ์๋ก์ด ๊ฐ์ ๋์์์ด ์์ฐํ ์ ์๋ฐ.
์์ ์์๋ ๋๋ค๋ก ์ธํด ์ด์ ๊ฒฐ๊ณผ์ 2๋ฅผ ๋ํ ๊ฐ์ ๋ฐํํ๋ค.
์ฆ ์ง์ ์คํธ๋ฆผ์ ์์ฑํ๋ค.
iterate
๋ ์์ฒญํ ๋ ๋ง๋ค ๊ฐ์ ์์ฐํ๊ณ ๋์ด ์์ผ๋ฏ๋ก ๋ฌดํ ์คํธ๋ฆผ์ ๋ง๋ ๋ค.
์ด๋ฌํ ์คํธ๋ฆผ์ ์ธ๋ฐ์ด๋ ์คํธ๋ฆผ์ด๋ผ๊ณ ํํํ๋ค.
๋ฐ๋ก ์ด๋ฐ ํน์ง์ด ์คํธ๋ฆผ๊ณผ ์ปฌ๋ ์ ์ ํฐ ์ฐจ์ด์ ์ด๋ค.
์๋ฐ 9์ iterate
๋ฉ์๋๋ ํ๋ ๋์ผ์ดํธ๋ฅผ ์ง์ํ๋ค.
์ด ์ฝ๋๋ 0์์ ์์ํด์ 100๋ณด๋ค ํฌ๋ฉด ์ซ์ ์์ฑ์ ์ค๋จํ๋ ์ฝ๋์ด๋ค.
1
2
3
// 0์์ ์์ํด์ 100๋ณด๋ค ํฌ๋ฉด ์ซ์ ์์ฑ ์ค๋จ
IntStream.iterate(0, n -> n < 100, n -> n + 4)
.forEach(System.out::println)
๋ ๋ฒ์งธ ์ธ์๋ก ํ๋ ๋์ผ์ดํธ๋ฅผ ๋ฐ์ ์ธ์ ๊น์ง ์์ ์ ์ํํ ๊ฒ์ธ์ง ๊ธฐ์ค์ผ๋ก ์ฌ์ฉํ๋ค.
filter
๋์์ผ๋ก๋ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์๊น?
1
2
3
IntStream.iterate(0, n -> n + 4)
.filter(n -> n < 100)
.forEach(System.out::println);
๊ทธ๋ ์ง ์๋ค.
filter
๋ฉ์๋๋ ์ธ์ ์ด ์์
์ ์ค๋จํด์ผ ํ๋์ง ์ ์ ์๋ค.
์คํธ๋ฆผ ์ผํธ์ํท์ ์ง์ํ๋ takeWhile
์ ์ด์ฉํ๋ ๊ฒ์ด ํด๋ฒ์ด๋ค.
1
2
3
IntStream.iterate(0, n -> n + 4)
.takeWhile(n -> n < 100)
.forEach(System.out::println);
generate ๋ฉ์๋
generate
๋ฉ์๋๋ ์๊ตฌํ ๋ ๊ฐ์ ๊ณ์ฐํ๋ ๋ฌดํ ์คํธ๋ฆผ์ ๋ง๋ค ์ ์๋ค.
ํ์ง๋ง ์์ฐ๋ ๊ฐ ๊ฐ์ ์ฐ์์ ์ผ๋ก ๊ณ์ฐํ์ง ์๋๋ค.
generate
๋ Supplier<T>
๋ฅผ ์ธ์๋ก ๋ฐ์์ ์๋ก์ด ๊ฐ์ ์์ฐํ๋ค.
1
2
3
Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println);
์ด ์ฝ๋๋ 0์์ 1์ฌ์ด์ ์์์ Double
ํ ์ซ์ ๋ค์ฏ ๊ฐ๋ฅผ ๋ง๋ ๋ค.
1
2
3
4
5
0.9410810294106129
0.6586270755634592
0.9592859117266873
0.13743396659487006
0.3942776037651241
์ด๋ฒ์๋ ๋ช
์์ ์ผ๋ก limit
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์คํธ๋ฆผ์ ํฌ๊ธฐ๋ฅผ ํ์ ํ๋ค.
limit
์ด ์๋ค๋ฉด ์คํธ๋ฆผ์ ์ธ๋ฐ์ด๋ ์ํ๊ฐ ๋๋ค.
generate
๋ ์ธ์ ์ฌ์ฉํ ๊น?
generate
๋ ์ํ๊ฐ ์๋ ๋ฉ์๋, ์ฆ ๋์ค์ ๊ณ์ฐํ ์ด๋ค ๊ฐ๋ ์ ์ฅํ์ง ์๋ ๋ฉ์๋๋ฅผ ํ์ฉํ๋ค.
๋ณ๋ ฌ ์ฝ๋์์๋ ๋ฐํ์(Supplier)์ ์ํ๊ฐ ์์ผ๋ฉด ์์ ํ์ง ์๋ค.
IntStream
์ ์ด์ฉํ๋ฉด ๋ฐ์ฑ ์ฐ์ฐ ๋ฌธ์ ๋ฅผ ํผํ ์ ์์๋ค.
IntStream
์ generate
๋ฉ์๋๋ Supplier<T>
๋์ ์ IntSupplier
๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค.
1
IntStream ones = IntStream.generate(() -> 1);
๋๋ค๋ก ํจ์ํ ์ธํฐํ์ด์ค์ ์ธ์คํด์ค๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด ์ ๋ฌํ ์ ์์๋ค.
1
2
3
4
5
IntStream twos = IntStream.generate(new IntSupplier(){
public int getAsInt() {
return 2;
}
});
generate
๋ฉ์๋๋ ์ฃผ์ด์ง Supplier ๋ฅผ ํ์ฉํด์ 2๋ฅผ ๋ฐํํ๋ getAsInt
๋ฉ์๋๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ํธ์ถํ ๊ฒ์ด๋ค.
์ต๋ช ํด๋์ค์ ๋๋ค๋ ๋น์ทํ ์ฐ์ฐ์ ์ํํ์ง๋ง ์ต๋ช ํด๋์ค์์๋ ๋ฉ์๋์ ์ฐ์ฐ์ ์ปค์คํฐ๋ง์ด์ฆํ ์ ์๋ค๋ ์ ์ด ๋ค๋ฅด๋ค.
๋ฐ๋ก ๋ถ์์ฉ์ด ์๊ธธ ์ ์๋ค๋ ์ ์ ๋ณด์ฌ์ค๋ค.
ํผ๋ณด๋์น ์์ด ์์
์์ ๊ธฐ์กด ์์ด ์ํ๋ฅผ ์ ์ฅํ๊ณ getAsInt
๋ก ๋ค์ ์์๋ฅผ ๊ฒ์ฐํ๋๋ก IntSupplier
๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค. ๋ ๋ค์์ ํธ์ถ๋ ๋๋ IntSupplier
์ ์ํ๋ฅผ ๊ฐฑ์ ํ ์ ์์ด์ผ ํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
// ํผ๋ณด๋์น ์์๋ฅผ ๋ฐํํ๋๋ก IntSupplier ๊ตฌํ
IntSupplier fib = new IntSupplier() {
private int previous = 0;
private int current = 1;
public int getAsInt() {
int oldPrevious = this.previous;
int nextValue = this.previous + this.current;
this.previous = this.current;
this.current = nextValue;
return oldPrevious;
}
};
IntStream.generate(fib).limit(10).forEach(System.out::println);
๋ง๋ค์ด์ง IntSupplier
์ธ์คํด์ค๋ ๊ฐ๋ณ ์ํ ๊ฐ์ฒด์ด๋ค.
getAsInt
๋ฅผ ํธ์ถํ๋ฉด ๊ฐ์ฒด ์ํ๊ฐ ๋ฐ๋๋ฉฐ ์๋ก์ด ๊ฐ์ ์์ฐํ๋ค.
iterate
๋ฅผ ์ฌ์ฉํ์ ๋๋ ๊ธฐ์กด ์ํ๋ฅผ ๋ฐ๊พธ์ง ์๊ณ ์๋ก์ด ๊ฐ์ ์์ฑํ๋ ์์ํ ๋ถํธ ์ํ๋ฅผ ์ ์งํ๋ค.
์คํธ๋ฆผ์ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๋ฉด์ ์ฌ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ป์ผ๋ ค๋ฉด ๋ถ๋ณ ์ํ ๊ธฐ๋ฒ์ ๊ณ ์ํด์ผ ํ๋ค.
๋ฌดํ ์คํธ๋ฆผ์์๋ limit
์ ์ด์ฉํด์ ๋ช
์์ ์ผ๋ก ์คํธ๋ฆผ ํฌ๊ธฐ๋ฅผ ์ ํํด์ผ ํ๋ค.
๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ฌด ๊ฒฐ๊ณผ๋ ๊ณ์ฐ๋์ง ์๋๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก ๋ฌดํ์ ์ผ๋ก ๊ณ์ฐ์ด ๋ฐ๋ณต๋๋ฏ๋ก ์ ๋ ฌํ๊ฑฐ๋ ๋ฆฌ๋์ค ํ ์ ์๋ค.