<commit_before>package com.marshall.Java8InAction.stream;

import com.marshall.Java8InAction.domain.Dish;

import java.util.*;
import java.util.Map;

import static com.marshall.Java8InAction.domain.Dish.menu;
import static java.util.stream.Collectors.*;

/**
 * Created by yaojie.hou on 2017/3/14.
 *
 * 分组（group）和分区（partition）
 */
public class Group {
    public static void main(String[] args) {
        //根据已有方法分组
        Map<Dish.Type, List<Dish>> dishedByType = menu.stream().collect(groupingBy(Dish::getType));
        //{OTHER=[french fries, rice, season fruit, pizza], MEAT=[pork, beef, chicken], FISH=[prawns, salmon]}
        System.out.println(dishedByType);

        //根据自定义方法分组
        Map<String, List<Dish>> dishesByCaloriesLevel = menu.stream().collect(groupingBy(d -> {
            if (d.getCalories() <= 400) {
                return "diet";
            } else if (d.getCalories() <= 700) {
                return "normal";
            } else {
                return "fat";
            }
        }));
        //{normal=[beef, french fries, pizza, salmon], fat=[pork], diet=[chicken, rice, season fruit, prawns]}
        System.out.println(dishesByCaloriesLevel);

        //多级分组
        Map<Dish.Type, Map<String, List<Dish>>> dishedByTypeCaloricLevel = menu.stream().collect(groupingBy(Dish::getType, groupingBy(d -> {
            if (d.getCalories() <= 400) {
                return "diet";
            } else if (d.getCalories() <= 700) {
                return "normal";
            } else {
                return "fat";
            }
        })));
        //{OTHER={normal=[french fries, pizza], diet=[rice, season fruit]}, MEAT={normal=[beef], fat=[pork], diet=[chicken]}, FISH={normal=[salmon], diet=[prawns]}}
        System.out.println(dishedByTypeCaloricLevel);
        
        //groupingBy的第二个参数还可以传递其它收集器
        Map<Dish.Type, Long> typesCount = menu.stream().collect(groupingBy(Dish::getType, counting()));
        //{OTHER=4, MEAT=3, FISH=2}
        System.out.println(typesCount);

        menu.stream().collect(groupingBy(Dish::getType), collectingAndThen(maxBy(Dish::getCalories), ))
    }
}<commit_msg>分组-多级分组<commit_after>package com.marshall.Java8InAction.stream;

import com.marshall.Java8InAction.domain.Dish;

import java.util.*;
import java.util.Map;

import static com.marshall.Java8InAction.domain.Dish.menu;
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.*;

/**
 * Created by yaojie.hou on 2017/3/14.
 *
 * 分组（group）和分区（partition）
 */
public class Group {
    public static void main(String[] args) {
        //根据已有方法分组
        Map<Dish.Type, List<Dish>> dishedByType = menu.stream().collect(groupingBy(Dish::getType));
        //{OTHER=[french fries, rice, season fruit, pizza], MEAT=[pork, beef, chicken], FISH=[prawns, salmon]}
        System.out.println(dishedByType);

        //根据自定义方法分组
        Map<String, List<Dish>> dishesByCaloriesLevel = menu.stream().collect(groupingBy(d -> {
            if (d.getCalories() <= 400) {
                return "diet";
            } else if (d.getCalories() <= 700) {
                return "normal";
            } else {
                return "fat";
            }
        }));
        //{normal=[beef, french fries, pizza, salmon], fat=[pork], diet=[chicken, rice, season fruit, prawns]}
        System.out.println(dishesByCaloriesLevel);

        //多级分组
        Map<Dish.Type, Map<String, List<Dish>>> dishedByTypeCaloricLevel = menu.stream().collect(groupingBy(Dish::getType, groupingBy(d -> {
            if (d.getCalories() <= 400) {
                return "diet";
            } else if (d.getCalories() <= 700) {
                return "normal";
            } else {
                return "fat";
            }
        })));
        //{OTHER={normal=[french fries, pizza], diet=[rice, season fruit]}, MEAT={normal=[beef], fat=[pork], diet=[chicken]}, FISH={normal=[salmon], diet=[prawns]}}
        System.out.println(dishedByTypeCaloricLevel);
        
        //groupingBy的第二个参数还可以传递其它收集器
        Map<Dish.Type, Long> typesCount = menu.stream().collect(groupingBy(Dish::getType, counting()));
        //{OTHER=4, MEAT=3, FISH=2}
        System.out.println(typesCount);

        //把收集器返回的结果转换为另外一种类型
        Map<Dish.Type, Dish> mostCaloricByType = menu.stream().collect(
                groupingBy(Dish::getType, collectingAndThen(
                        maxBy(comparingInt(Dish::getCalories)), Optional::get)));
        //{OTHER=pizza, MEAT=pork, FISH=salmon}
        System.out.println(mostCaloricByType);

        Map<Dish.Type, Integer> totalCaloriesByType = menu.stream().collect(
                groupingBy(Dish::getType, summingInt(Dish::getCalories)));
        //{OTHER=1550, MEAT=1900, FISH=850}
        System.out.println(totalCaloriesByType);
    }
}
{'fraction_non_alphanumeric': 0.15349417637271215, 'fraction_numerical': 0.012687188019966721, 'mean_word_length': 2.580789277736411, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5561004', 'n_tokens_mistral': 1662, 'n_tokens_neox': 1604, 'n_words': 266}