import java.util.*;
import java.util.stream.Collectors;

public class Ch4 {
    public void all() {
        filterWithJava7();
        filterWithJava8_1();
        filterWithJava8_1_2();
        filterWithJava8_2();
    }

    private void filterWithJava8_1() {
        List<Dish> menu = createMenu();
        List<Dish> lowCaloricDishes = menu.stream()
                .filter(d->d.getCalories()<500)
                .collect(Collectors.toList());

        Collections.sort(lowCaloricDishes, Comparator.comparing(Dish::getCalories));
        for(Dish d: lowCaloricDishes) {
            System.out.println("Low calorie dish: " + d.getName() );
        }
    }
    private void filterWithJava8_1_2() {
        List<Dish> menu = createMenu();
        int limit = 2;
        List<Dish> limitedLowCaloricDishes = menu.stream()
                .filter(d->d.getCalories()<500)
                .limit(limit) //SEEE!!!
                .collect(Collectors.toList());

        for(Dish d : limitedLowCaloricDishes) {
            System.out.println("Limited list: " + d.getName());
        }

        List<String> limitedLowCalorieNames = limitedLowCaloricDishes.stream()
                .map(Dish::getName)//same as: .map(d->d.getName())
                .collect(Collectors.toList());

        System.out.println("Names of low calorie dishes: " + limitedLowCalorieNames);

        System.out.println("Low calories using streams. Alt 1");
        limitedLowCaloricDishes.stream().map(Dish::getName).forEach(System.out::println);
        System.out.println("Low calories using streams. Alt 2");
        limitedLowCalorieNames.forEach(System.out::println);
    }

    private void filterWithJava8_2() {
        List<Dish> menu = createMenu();

        List<String> lowCaloricDishesName =
                menu.stream()
                        .filter(d->d.getCalories()<500)
                        .sorted(Comparator.comparing(Dish::getCalories))
                        .map(Dish::getName)
                        .collect(Collectors.toList());
        System.out.println("Printing using stream works fine here:");
        lowCaloricDishesName.stream().forEach(System.out::println);

    }

    private void filterWithJava7() {
        List<Dish> menu = createMenu();

        List<Dish> lowCaloricDishes = new ArrayList<>();
        for(Dish d: menu) {
            if(d.getCalories() < 500) {
                lowCaloricDishes.add(d);
            }
        }

        Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
            @Override
            public int compare(Dish d1, Dish d2) {
                return Integer.compare(d1.getCalories(), d2.getCalories());
            }
        });

        for(Dish d:lowCaloricDishes) {
            System.out.println("Low calorie: " + d.getName() + " has " + d.getCalories() + " calories.");
        }
        System.out.println("Printing names using stream. Works fine here:");
        lowCaloricDishes.stream().map(Dish::getName).forEach(System.out::println);

    }

    public List<Dish> createMenu() {
        return Dish.createMenu();
    }
}
