์คํธ๋ฆผ์ผ๋ก ๋ฐ์ดํฐ ์์ง
์ฐ๋ฆฌ๋ ์ด ์ฅ์์ reduce์ฒ๋ผ collect๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ํ ์์ ๋์ ๋ฐฉ์์ ์ธ์๋ก ๋ฐ์ ์ต์ข
๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํ ๊ฒ์ด๋ค. ๋ค์ํ ์์ ๋์ ๋ฐฉ์์ Collector ์ธํฐํ์ด์ค์ ์ ์๋์ด ์๋๋ฐ ์ปฌ๋ ์
, ์ปฌ๋ ํฐ collect๋ฅผ ํท๊ฐ๋ฆฌ์ง ์๋๋ก ๋ฐ๋ผ์์ผํ๋ค.
๋จผ์ ํ๋ ์์๋ฅผ ๋ค๊ฒ ๋ค.
- ํตํ๋ณ๋ก ํธ๋์ญ์
์ ๊ทธ๋ฃนํํ ๋ค์ ํด๋น ํตํ๋ก ์ผ์ด๋ ๋ชจ๋ ํธ๋์ญ์
ํฉ๊ณ๋ฅผ ๊ณ์ฐ
- ํธ๋์ญ์
์ ๋น์ผ ํธ๋์ญ์
๊ณผ ์ ๋ ดํ ํธ๋์ญ์
๋ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฅ
- ํธ๋์ญ์
์ ๋์ ๋ฑ ๋ค์์ค์ผ๋ก ๊ทธ๋ฃนํํ์์ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ ํธ๋์ญ์
์ด ๋น์ผ์ง ์ ๋ ดํ์ง ๊ตฌ๋ถํ์์ค
๋ค์์ ์๋ฐ 8 ์ด์ ์ฝ๋๋ก ์์ฑํ ์ฝ๋์ด๋ค.
Map<Currency, List<Transcation>> transactionsByCurrencies = new HashMap<>();
for (Transaction transaction : transactions) {
Currency currency = transaction.getCurrency();
List<Transcation> transactionsForCurrency = transactionsByCurrencies.get(currency);
if(transactionsForCurrency == null){
transactionsForCurrency = new ArrayList<>();
transactionsByCurrencies.put(currency, transactionsForCurrency);
}
transactionsForCurrency.add(transaction);
}
ํธ๋์ญ์
์ ๋ฆฌ์คํธ๋ฅผ ๋ฐ๋ณตํ์ฌ ๋ถ๋ฅธ ํ ๊ฐ์ ํตํ๋ฅผ ๊ฐ์ง ํธ๋์ญ์
๋ฆฌ์คํธ์ ํ์ฌ ํ์ ์ค์ธ ํธ๋์ญ์
์ ์ถ๊ฐํ๋ค.
๋ง์ฝ ํ์ฌ ๊ฐ์ ํตํ๊ฐ ์์ผ๋ฉด ์๋ก์ด ํญ๋ชฉ์ ๋ง๋ ๋ค.
์์ ์ฝ๋๋ ํ๋์ ์์๋ณด๊ธฐ๋ ์ด๋ ต๊ณ ๊ตฌํํ๊ธฐ๋ ์ด๋ ต๋ค. ์ด๋ฅผ collect ๋ฉ์๋๋ฅผ ํ์ฉํ์ฌ ์ํ๋ ์ฐ์ฐ์ ๋์ฑ ๊ฐ๊ฒฐํ๊ฒ ๊ตฌํํ ์ ์๋ค.
Map<Currency, List<Transaction>> transactionsByCurrencies =
transactions.stream().collect(groupingBy(Transaction::getCurrency));
์์ ์ฝ๋์ ๋น๊ตํ์ ๋ ํ๋์ ์์๋ณด๊ธฐ๋ ์ฝ๊ณ ์ฝ๋ ๋ํ ์งง์ ์ก๋ค.
์ปฌ๋ ํฐ๋ ๋ฌด์์ธ๊ฐ?
์์ ์์ ๋ฅผ ๋ณด๋ฉด ๋ช
๋ นํ ํ๋ก๊ทธ๋๋ฐ์ ๋นํด ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ด ์ผ๋ง๋ ํธ๋ฆฌํ์ง ๋ช
ํํ๊ฒ ๋ณด์ฌ์ฃผ๊ณ ์๋ค.
์์ ์์ collect ๋ฉ์๋๋ก Collector ์ธํฐํ์ด์ค ๊ตฌํ์ ์ ๋ฌํ๋ค. Collector ์ธํฐํ์ด์ค ๊ตฌํ์ ์คํธ๋ฆผ์ ์์๋ฅผ ์ด๋ค ์์ผ๋ก ๋์ถํ ์ง ์ง์ ํ๋ค. ์ด๋ฒ์ ๋ณผ ๋ฉ์๋๋ groupingBy ๋ฉ์๋๋ก ์ด๋ฅผ ์ด์ฉํ์ฌ, ๊ฐ ํค์ ๊ฐ ํค์ ๋์ํ๋ ์์ ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ผ๋ก ํฌํจํ์ฌ ๋งต์ ๋ง๋ค์ด ๋ผ ๊ฒ์ด๋ค.
๋ฏธ๋ฆฌ ์ ์๋ ์ปฌ๋ ํฐ
์ปฌ๋ ํฐ์์ ๋ฏธ๋ฆฌ ์ ์๋ groupingBy์ ๊ฐ์ Collectors ํด๋์ค์์ ์ ๊ณตํ๋ ํฉํ ๋ฆฌ ๋ฉ์๋์ ๊ธฐ๋ฅ์ ์ดํด๋ณผ ๊ฒ์ด๋ค.
Collectors์์ ์ ๊ณตํ๋ ๋ฉ์๋์ ๊ธฐ๋ฅ์ ํฌ๊ฒ ์ธ ๊ฐ์ง๋ก ๊ตฌ๋ถํ ์ ์๋ค.
- ์คํธ๋ฆผ ์์๋ฅผ ํ๋์ ๊ฐ์ผ๋ก ๋ฆฌ๋์คํ๊ณ ์์ฝ
- ์์ ๊ทธ๋ฃนํ
- ์์ ๋ถํ
๋ฆฌ๋์ฑ๊ณผ ์์ฝ
5์ฅ์์ ๋ค๋ฃฌ ์๋ฆฌ ์์ ๋ฅผ ์ด์ฉํ์ฌ ์ดํด๋ณด๊ฒ ๋ค.
์ฒซ ๋ฒ์งธ ์๋ก counting()์ด๋ผ๋ ํฉํ ๋ฆฌ ๋ฉ์๋๊ฐ ๋ฐํํ๋ ์ปฌ๋ ํฐ๋ก ๋ฉ๋ด์์ ์๋ฆฌ ์๋ฅผ ๊ณ์ฐํด์ค๋ค.
long howManyDishs = menu.stream().collect(Collectors.counting());
->
long howManyDishs = menu.stream().count();
์์ ์ฝ๋์ฒ๋ผ ๋ถํ์ํ ๊ณผ์ ์ ์๋ตํ ์ ์๋ค.
Collectors ํด๋์ค๋ฅผ ์ํฌํธ๋ฅผ ํ๊ฒ๋๋ฉด ์์ ์์ ์ฒ๋ผ Collectors.counting()์ ๊ฐ๋จํ๊ฒ counting()์ผ๋ก ํํํ ์ ์๋ค.
์คํธ๋ฆผ ๊ฐ์์ ์ต๋๊ฐ ์ต์๊ฐ ๊ฒ์
๋ง์ฝ ๋ฉ๋ด์์ ์นผ๋ก๋ฆฌ๊ฐ ๊ฐ์ฅ ๋์ ์๋ฆฌ๋ฅผ ์ฐพ๋๋ค๊ณ ๊ฐ์ ํ์. Collectors์ ์ ์๋์ด ์๋ maxBy(), minBy()๋ฅผ ์ด์ฉํ์ฌ ์ต๋๊ฐ ์ต์๊ฐ์ ๊ณ์ฐํ ์ ์๋ค.
Comparator<Dish> dishCaloriesComparator = Comparator.comparingInt(Dish::getCalories);
Optional<Dish> mostCalorieDish = menu.stream().collect(maxBy(dishCaloriesComparator));
์์ฝ ์ฐ์ฐ
Collectors ํด๋์ค๋ ์คํธ๋ฆผ์ ์๋ ๊ฐ์ฒด์ ์ซ์ ํ๋์ ํฉ๊ณ๋ ํ๊ท ๋ฑ์ ๋ฐํํ๋ ์ฐ์ฐ ๋ํ ์ง์ํ๋ค.
summingInt, averagingInt ๋ฑ ํฉ, ํ๊ท ๊ฐ ๊ณ์ฐ ๋ฑ ์ฌ๋ฌ๊ฐ์ง ์ฐ์ฐ์ด ์ง์๋๋ค.
int totalCalories = menu.stream().collect(summingInt(Dish::getCalories));
์์ ์ฝ๋๋ ๋ฉ๋ด ๋ฆฌ์คํธ์ ํฉ๊ณ๋ฅผ ๊ณ์ฐํ๋ ์ฝ๋์ด๋ค. ์ด์ฒ๋ผ Collectors ๋ํ ์คํธ๋ฆผ์ ๋ฆฌ๋์ฑ์ฒ๋ผ ์ฌ๋ฌ๊ฐ์ง ์ฐ์ฐ์ ํ ์ ์๋ค.
์ด๋ฌํ ๋จ์ ํฉ๊ณ์ธ์ ์์ ์, ์ต๋๊ฐ ์ต์๊ฐ, ํฉ๊ณ์ ํ๊ท ์ ํ๊บผ๋ฒ์ ๊ณ์ฐํ์ฌ ๋ฐํํด์ฃผ๋ summarizingInt ๋ํ ์ง์ํด์ค๋ค.
IntSummaryStatistics menuStatistics = menu.stream().collect(summarizingInt(Dish::getCalories));
์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด IntSummaryStatistics๋ก ๋ชจ๋ ์ ๋ณด๊ฐ ์์ง๋๋ค. menuStaticstics ๊ฐ์ฒด๋ฅผ ์ถ๋ ฅํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์๋ค.
IntSummaryStatistics { count = 9, sum=4300, min=120, average=477.777778, max=800}
์์์๋ int๋ง ์ค๋ช
ํ์ง๋ง ์ด์ ๋น์ทํ Double, Long์ ๋ํ ํด๋์ค๋ ์๋ค.
๋ฌธ์์ด ์ฐ๊ฒฐ
์ปฌ๋ ํฐ๋ ์คํธ๋ฆผ์ ๊ฐ ๊ฐ์ฒด๋ฅผ ์ฐ๊ฒฐํ์ฌ ํ๋์ ๋ฌธ์์ด๋ก ์ฐ๊ฒฐํ๋ joining ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ์ง์ํ๋ค.
String shortMenu = menu.stream().map(Dish::getName).collect(joining(", "));
์์ ์ฝ๋๋ ๊ฐ ๊ฐ์ฒด๋ฅผ , ๋ก ์ฐ๊ฒฐํด์ฃผ๋ ์ฝ๋์ด๋ค.
๋ฒ์ฉ ๋ฆฌ๋์ฑ ์์ฝ ์ฐ์ฐ
์ง๊ธ๊น์ง ์ดํด๋ณธ ๋ชจ๋ ์ปฌ๋ ํฐ๋ reducing ํฉํ ๋ฆฌ ๋ฉ์๋๋ก๋ ์ ์ํ ์ ์๋ค. ์ฆ, ๋ฒ์ฉ Collectors.reducing์ผ๋ก๋ ๊ตฌํํ ์ ์๋ค.
int totalCalories = menu.stream().collect(reducing(0, Dish::getCalories, (i, j) -> i + j));
์์ ์ฝ๋๋ reducing ๋ฉ์๋๋ก ๋ง๋ค์ด์ง ์ปฌ๋ ํฐ๋ก ๋ฉ๋ด์ ๋ชจ๋ ์นผ๋ก๋ฆฌ ํฉ๊ณ๋ฅผ ๊ณ์ฐํ ์ ์๋ค.
reducing์ ์ธ์ ์ธ ๊ฐ๋ฅผ ๋ฐ๋๋ค.
- ์ฒซ ๋ฒ์งธ ์ธ์๋ ๋ฆฌ๋์ฑ ์ฐ์ฐ์ ์์๊ฐ์ด๊ฑฐ๋ ์คํธ๋ฆผ์ ์ธ์๊ฐ ์์ ๋๋ ๋ฐํ๊ฐ์ด๋ค.
- ๋ ๋ฒ์งธ ์ธ์๋ ์๋ฆฌ๋ฅผ ์นผ๋ก๋ฆฌ ์ ์๋ก ๋ณํํ ๋ ์ฌ์ฉํ ๋ณํ ํจ์๋ค.
- ์ธ ๋ฒ์งธ ์ธ์๋ ๊ฐ์ ์ข
๋ฅ์ ๋ ํญ๋ชฉ์ ํ๋์ ๊ฐ์ผ๋ก ๋ํ๋ BinaryOperator๋ค. ์์ ์์๋ ๋ ๊ฐ์ int๊ฐ ์ฌ์ฉ๋์๋ค.
๊ทธ๋ฃนํ
๋งจ ์ฒ์ ๋ณด์๋ ํตํ ๊ทธ๋ฃนํ ์์ ์์ ํ์ธ ํ๋ฏ์ด ๋ช
๋ นํ ํ๋ก๊ทธ๋๋ฐ์ผ๋ก ๊ทธ๋ฃนํ๋ฅผ ๊ตฌํํ๋ ค๋ฉด ๊น๋ค๋กญ๊ณ , ํ ์ผ์ด ๋ง์ผ๋ฉฐ, ์๋ฌ๋ ๋ง์ด ๋ฐ์ํ๋ค. ํ์ง๋ง ์๋ฐ 8์ ํจ์ํ์ ์ด์ฉํ๋ฉด ๊ฐ๋
์ฑ ์๋ ํ ์ค์ ์ฝ๋๋ก ๊ทธ๋ฃนํ๋ฅผ ๊ตฌํํ ์ ์๋ค.
์ด๋ฒ ์ฝ๋๋ ์๋ฆฌ๋ฅผ ๊ณ ๊ธฐ, ์์ , ๋๋จธ์ง ๊ทธ๋ฃน์ผ๋ก ๊ทธ๋ฃนํํ๋ ์ฝ๋์ด๋ค.
Map<Dish.Type, List<Dish>> dishesByType = menu.stream().collect(groupingBy(Dish::getType));
// result
{FISH =[prawns, salmon], OTHER={french fries, rice, season fruit, pizza], MEAT=[pork, beef, chicken]}
์ด์ฒ๋ผ groupingBy๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฅํ ์ ์๋ค. ๋ฐ๋ผ์ ์ด๋ฅผ ๋ถ๋ฅ ํจ์๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์์ฒ๋ผ ๋จ์ ์์ฑ ์ ๊ทผ์ ๋์ ๋ ๋ณต์กํ ๋ถ๋ฅ ๊ธฐ์ค์ด ํ์ํ ์ํฉ์์๋ ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๋ค์์ 400 ์นผ๋ก๋ฆฌ ์ดํ๋ฅผ diet
๋ก 400~ 700์นผ๋ก๋ฆฌ๋ฅผ normal
๋ก, 700 ์นผ๋ก๋ฆฌ ์ด๊ณผ๋ฅผ fat
์๋ฆฌ๋ก ๋ถ๋ฅํ๋ค๊ณ ๊ฐ์ ํ๋ค.
์ด ๋ถ๋ฅ ๊ธฐ์ค์ ๋ฉ์๋ ์ฐธ์กฐ๋์ ๋๋ค ํํ์์ผ๋ก ๋ํ๋ผ ์ ์๋ค.
public enumCaloricLevel { DIET, NORMAL, FAT}
Map<CaloricLevel, List<Dish>> dishesByCaloricLevel = menu.stream().collect(groupingBy(dish->{
if(dish.getCalories() <= 400) return CaloricLevel.DIET;
else if(dish.getCalories() <= 700) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT;
}));
๊ทธ๋ฃนํ๋ ์์ ์กฐ์
์์ ์์ ๋ฅผ ํตํด groupBy ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ํ ๊ฐ์ง ๊ธฐ์ค์ผ๋ก ๊ทธ๋ฃนํํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์๋ค. ๊ทธ๋ ๋ค๋ฉด 2๊ฐ์ง ์ด์์ ๊ธฐ์ค์ผ๋ก ๊ทธ๋ฃนํํ ์ ์์๊น?
์ฐ์ ์คํธ๋ฆผ์ filter ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ ์ ์๋ค.
Map<Dish.Type, List<Dish>> caloricDishesByType =
menu.stream().filter(dish -> dish.getCalories() > 500)
.collect(groupingBy(Dish::getType));
์ ์ฝ๋๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ง๋ง ๋จ์ ์ด ์กด์ฌํ๋ค.
{ OTHER=[french fries, pizza], MEAT=[pork, beef]}
๋ฌธ์ ๊ฐ ๋ฌด์์ธ์ง ๋ฐ๊ฒฌํ๋๊ฐ? FISH๋ filter๋ฅผ ๋ง์กฑํ๋ ์์๊ฐ ์์ผ๋ฏ๋ก FISH ํญ๋ชฉ์ด ์์ ๋น ์ ธ์๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Collectors ํด๋์ค๋ groupingBy ํฉํ ๋ฆฌ ๋ฉ์๋์ ๋ ๋ฒ์งธ ์ธ์๋ฅผ ๊ฐ๋ ์ค๋ฒ๋ก๋ฉ์ ์ฌ์ฉํ๋ค.
Map<Dish.Type, List<Dish>> caloricDishesByType =
menu.stream()
.collect(groupingBy(Dish::getType,
filtering(dish -> dish.getCalories() > 500, toList())));
// result
{OTHER=[french fries, pizza], MEAT=[pork, beef], FISH=[]}
๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์์ ์๋ฏ์ด ๋ชฉ๋ก์ด ๋น์ด์๋ FISH๋ ํญ๋ชฉ์ผ๋ก ์ถ๊ฐ๋๋ค.
๋ค์์ค ๊ทธ๋ฃนํ
๋ ์ธ์๋ฅผ ๋ฐ๋ ํฉํ ๋ฆฌ ๋ฉ์๋ Collectors.groupingBy๋ฅผ ์ด์ฉํด์ ํญ๋ชฉ์ ๋ค์์ค์ผ๋ก ๊ทธ๋ฃนํํ ์ ์๋ค. Collectors.groupingBy๋ ์ผ๋ฐ์ ์ธ ๋ถ๋ฅ ํจ์์ ์ปฌ๋ ํฐ๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค. ์ฆ, ๋ ๊ฐ์ง ๊ธฐ์ค์ผ๋ก ํญ๋ชฉ์ ๊ทธ๋ฃนํํ ์ ์๋ค.
Map<Dish.Type, Map<CaloricLevel, List<Dish>>> dishesByTypeCaloricLevel =
menu.stream().collect(
groupingBy(Dish::getType,
groupingBy(dish -> {
if(dish.getCalories() <= 400)
return CaloricLevel.DIET;
else if(dish.getCalories() <= 700)
return CaloricLevel.NORMAL;
else
return CaloricLevel.FAT;
})
})
);
๊ทธ๋ฃนํ ๊ฒฐ๊ณผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋ ์์ค์ ๋งต์ด ๋ง๋ค์ด ์ง๋ค.
{MEAT={DIET=[chicken], NORMAL=[beef], FAT=[pork]}, FISH={DIET=[prawns], NORMAL=[salmon]},
OTHER={DIET=[rice, sasonal fruit], NORMAL=[french fries, pizza]}}
์ฒซ ๋ฒ์งธ ๋ถ๋ฅ ํจ์์์๋ fish
, meat
, other
๋ฅผ ๊ธฐ์ค์ผ๋ก, ๋ ๋ฒ์งธ๋ normal
, diet
, fat
์ ๊ธฐ์ค์ผ๋ก ๊ทธ๋ฃนํ ๋๋ค.
์๋ธ๊ทธ๋ฃน์ผ๋ก ๋ฐ์ดํฐ ์์ง
groupingBy ์ปฌ๋ ํฐ์ ๋ ๋ฒ์งธ ์ธ์๋ก counting ์ปฌ๋ ํฐ๋ฅผ ์ ๋ฌํด์ ๋ฉ๋ด์์ ์๋ฆฌ ์๋ฅผ ์ข
๋ฅ๋ณ๋ก ๊ณ์ฐํ ์ ์๋ค.
Map<Dish.Type, Long> typesCount = menu.stream().collect(groupingBy(Dish::getType, counting()));
// result
{MEAT=3, FISH=2, OTHER=4}
๋ถ๋ฅ ํจ์ ํ ๊ฐ์ ์ธ์๋ฅผ ๊ฐ๋ groupingBy(f)๋ ์ฌ์ค groupingBy(f, toList())์ ์ถ์ฝํ์ด๋ค.
์ปฌ๋ ํฐ ๊ฒฐ๊ณผ๋ฅผ ๋ค๋ฅธ ํ์์ ์ ์ฉํ๊ธฐ
๋ง์ง๋ง ๊ทธ๋ฃนํ ์ฐ์ฐ์์ ๋งต์ ๋ชจ๋ ๊ฐ์ Optional๋ก ๊ฐ์ ํ์๊ฐ ์์ผ๋ฏ๋ก Optional์ ์ญ์ ํ ์ ์๋ค. ์ฆ, ๋ค์์ฒ๋ผ ํฉํ ๋ฆฌ ๋ฉ์๋ Collectros.collectingAndThen
์ผ๋ก ์ปฌ๋ ํฐ๊ฐ ๋ฐํํ ๊ฒฐ๊ณผ๋ฅผ ๋ค๋ฅธ ํ์์ผ๋ก ํ์ฉํ ์ ์๋ค.
Map<Dish.Type, Dish> mostCaloricByType =
menu.stream()
.collect(groupingBy(Dish::getType,
collectingAndThen(
maxBy(comparingInt(Dish::getCalories)),
Optional::get)));
ํฉํ ๋ฆฌ ๋ฉ์๋ collectingAndThen
์ ์ ์ฉํ ์ปฌ๋ ํฐ์ ๋ณํ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ์ ๋ค๋ฅธ ์ปฌ๋ ํฐ๋ฅผ ๋ฐํํ๋ค.
๋ถํ
๋ถํ ์ ๋ถํ ํจ์๋ผ ๋ถ๋ฆฌ๋ ํ๋ ๋ ์ผ์ดํธ๋ฅผ ๋ถ๋ฅ ํจ์๋ก ์ฌ์ฉํ๋ ํน์ํ ๊ทธ๋ฃนํ ๊ธฐ๋ฅ์ด๋ค. ๋ถํ ํจ์๋ ๋ถ๋ฆฌ์ธ์ ๋ฐํํ๋ฏ๋ก ๋งต์ ํค ํ์์ Boolean์ด๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๊ทธ๋ฃนํ ๋งต์ ์ต๋ (true or false) ๋ ๊ฐ์ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฅ๋๋ค.
์๋ฅผ ๋ค์ด ์ฑ์์ธ ์๋ฆฌ์ ์๋ ์๋ฆฌ๋ก ๊ตฌ๋ถํ๊ณ ์ถ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด๋๋ค.
Map<Boolean, List<Dish>> partitioneMenu = menu.stream().collect(partitioningBy(Dish::isVegetarina));
// result
{false=[pork, beef, chicken, prawns, salmon],
true=[french fries, rice, season fruit, pizza]}
์ด์ ์ฐธ๊ฐ์ ํค๋ก ๋งต์์ ๋ชจ๋ ์ฑ์ ์๋ฆฌ๋ฅผ ์ป์ ์ ์๋ค.
List<Dish> vegetarianDishes = partitionedMenu.get(true);
Collector ์ธํฐํ์ด์ค
์ด๋ฒ ์ฅ์์๋ Collector ์ธํฐํ์ด์ค๋ฅผ ์ง์ ๊ตฌํํด์ ๋ ํจ์จ์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ปฌ๋ ํฐ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณธ๋ค.
public interface Collector<T, A, R> {
Supplier<A> supplier();
BiConsumer<A, T> accumulator();
Function<A, R> finisher();
BinaryOperator<A> combiner();
Set<Characteristics> characteristics();
}
์์ ์ฝ๋๋ Collector ์ธํฐํ์ด์ค์ ์๊ทธ๋์ฒ์ ๋ค์ฏ ๊ฐ์ ๋ฉ์๋ ์ ์๋ฅผ ๋ณด์ฌ์ค๋ค. ์ด๊ฒ์ ๋ค์์ฒ๋ผ ์ค๋ช
ํ ์ ์๋ค.
- T๋ ์์ง๋ ์คํธ๋ฆผ ํญ๋ชฉ์ ์ ๋ค๋ฆญ ํ์์ด๋ค.
- A๋ ๋์ ์, ์ฆ ์์ง ๊ณผ์ ์์ ์ค๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋์ ํ๋ ๊ฐ์ฒด์ ํ์์ด๋ค.
- R์ ์์ง ์ฐ์ฐ ๊ฒฐ๊ณผ ๊ฐ์ฒด์ ํ์(ํญ์ ๊ทธ๋ฐ ๊ฒ์ ์๋์ง๋ง ๋๊ฐ ์ปฌ๋ ์
ํ์)์ด๋ค.
์ด Collector ์ธํฐํ์ด์ค์ 5๊ฐ์ง ๋ฉ์๋๋ฅผ ํ๋์ฉ ์ดํด๋ณด์. ๋จผ์ ์ดํด๋ณผ ๋ค ๊ฐ์ ๋ฉ์๋๋ collect ๋ฉ์๋์์ ์คํํ๋ ํจ์๋ฅผ ๋ฐํํ๋ ๋ฐ๋ฉด, ๋ค์ฏ ๋ฒ์งธ ๋ฉ์๋ characteristics๋ collect ๋ฉ์๋๊ฐ ์ด๋ค ์ต์ ํ๋ฅผ ์ด์ฉํด์ ๋ฆฌ๋์ฑ ์ฐ์ฐ์ ์ํํ ๊ฒ์ธ์ง ๊ฒฐ์ ํ๋๋ก ๋๋ ํํธ ํน์ฑ ์งํฉ์ ์ ๊ณตํ๋ค.
- supplier ๋ฉ์๋ : ์๋ก์ด ๊ฒฐ๊ณผ ์ปจํ
์ด๋ ๋ง๋ค๊ธฐ
- accumulator ๋ฉ์๋ : ๊ฒฐ๊ณผ ์ปจํ
์ด๋์ ์์ ์ถ๊ฐํ๊ธฐ
- finisher ๋ฉ์๋ : ์ต์ข
๋ณํ๊ฐ์ ๊ฒฐ๊ณผ ์ปจํ
์ด๋๋ก ์ ์ฉํ๊ธฐ
- combiner ๋ฉ์๋ : ๋ ๊ฒฐ๊ณผ ์ปจํ
์ด๋ ๋ณํฉ
- Characteristics ๋ฉ์๋ : ์ปฌ๋ ํฐ์ ์ฐ์ฐ์ ์ ์ํ๋ Characteristics ํ์์ ๋ถ๋ณ ์งํฉ์ ๋ฐํํ๋ค.
์ด๋ฅผ ์ด์ฉํ์ฌ ์ปค์คํ
์ปฌ๋ ํฐ๋ฅผ ๊ฐ๋ฐํ ์ ์๋ค.
๋ง์น๋ฉฐ
- collect๋ ์คํธ๋ฆผ์ ์์๋ฅผ ์์ฝ ๊ฒฐ๊ณผ๋ก ๋์ ํ๋ ๋ค์ํ ๋ฐฉ๋ฒ(์ปฌ๋ ํฐ๋ผ ๋ถ๋ฆฌ๋)์ ์ธ์๋ก ๊ฐ๋ ์ต์ข
์ฐ์ฐ์ด๋ค.
- ์คํธ๋ฆผ์ ์์๋ฅผ ํ๋์ ๊ฐ์ผ๋ก ๋ฆฌ๋์คํ๊ณ ์์ฝํ๋ ์ปฌ๋ ํฐ๋ฟ ์๋๋ผ ์ต์๊ฐ, ์ต๋๊ฐ, ํ๊ท ๊ฐ์ ๊ณ์ฐํ๋ ์ปฌ๋ ํฐ ๋ฑ์ด ๋ฏธ๋ฆฌ ์ ์๋์ด ์๋ค.
- ๋ฏธ๋ฆฌ ์ ์๋ ์ปฌ๋ ํฐ์ธ groupingBy๋ก ์คํธ๋ฆผ์ ์์๋ฅผ ๊ทธ๋ฃนํํ๊ฑฐ๋, partitioningBy๋ก ์คํธ๋ฆผ์ ์์๋ฅผ ๋ถํ ํ ์ ์๋ค.
- ์ปฌ๋ ํฐ๋ ๋ค์์ค์ ๊ทธ๋ฃนํ, ๋ถํ , ๋ฆฌ๋์ฑ ์ฐ์ฐ์ ์ ํฉํ๊ฒ ์ค๊ณ๋์ด ์๋ค.
- Collector ์ธํฐํ์ด์ค์ ์ ์๋ ๋ฉ์๋๋ฅผ ๊ตฌํํด์ ์ปค์คํ
์ปฌ๋ ํฐ๋ฅผ ๊ฐ๋ฐํ ์ ์๋ค.