diff --git a/modern-java/src/main/java/org/gym/fp/moderjava/StreamTest.java b/modern-java/src/main/java/org/gym/fp/moderjava/StreamTest.java index 032cb6a..5046252 100644 --- a/modern-java/src/main/java/org/gym/fp/moderjava/StreamTest.java +++ b/modern-java/src/main/java/org/gym/fp/moderjava/StreamTest.java @@ -1,11 +1,13 @@ package org.gym.fp.moderjava; import java.util.*; -import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import static java.lang.System.out; +import static java.util.Arrays.asList; +import static java.util.Comparator.comparingInt; +import static java.util.stream.Collectors.*; public class StreamTest { @@ -14,13 +16,14 @@ public class StreamTest { doStreamMappingDemo(); doStreamFindOrMatchingDemo(); doStreamReducingDemo(); + doStreamCollectingDemo(); } private static void doStreamFilterDemo() { out.println("FILTER EXAMPLE"); getDishes().stream() .filter(Dish::isVegetarian) - .collect(Collectors.toList()) + .collect(toList()) .forEach(out::println); out.println("----------------------------------------"); out.println("DISTINCT EXAMPLE"); @@ -42,26 +45,26 @@ public class StreamTest { } private static void doStreamMappingDemo() { - List words = Arrays.asList("Hello", "World"); + List words = asList("Hello", "World"); List uniqueCharacters = words.stream() .map(word -> word.split("")) .flatMap(Arrays::stream) .distinct() - .collect(Collectors.toList()); + .collect(toList()); out.println(uniqueCharacters); out.println("----------------------------------------"); out.println("Permutations"); - List numbers1 = Arrays.asList(1, 2, 3); - List numbers2 = Arrays.asList(3, 4); + List numbers1 = asList(1, 2, 3); + List numbers2 = asList(3, 4); List pairs1 = numbers1.stream() .flatMap(i -> numbers2.stream().map(j -> new int[]{i, j})) - .collect(Collectors.toList()); + .collect(toList()); pairs1.forEach(pair -> out.println(Arrays.toString(pair))); out.println("----------------------------------------"); List pairs2 = numbers1.stream() .flatMap(i -> numbers2.stream().map(j -> new int[]{i, j})) .filter(pair -> (pair[0] + pair[1]) % 3 == 0) - .collect(Collectors.toList()); + .collect(toList()); pairs2.forEach(pair -> out.println(Arrays.toString(pair))); out.println("----------------------------------------"); } @@ -89,7 +92,7 @@ public class StreamTest { dish.ifPresent(out::println); out.println("----------------------------------------"); out.println("FINDFIRST EXAMPLE"); - List someNumbers = Arrays.asList(1, 2, 3, 4, 5); + List someNumbers = asList(1, 2, 3, 4, 5); someNumbers.stream() .map(n -> n * n) .filter(n -> n % 3 == 0) @@ -118,26 +121,26 @@ public class StreamTest { Trader mario = new Trader("Mario", "Milan"); Trader alan = new Trader("Alan", "Cambridge"); Trader brian = new Trader("Brian", "Cambridge"); - List transactions = Arrays.asList( + List transactions = asList( new Transaction(brian, 2011, 300), new Transaction(raoul, 2012, 1000), new Transaction(raoul, 2011, 400), new Transaction(mario, 2012, 710), new Transaction(mario, 2012, 700), new Transaction(alan, 2012, 950) - ); + ); out.println("1)"); transactions.stream() .filter(t -> t.getYear() == 2011) .sorted(Comparator.comparing(Transaction::getValue)) - .collect(Collectors.toList()) + .collect(toList()) .forEach(out::println); out.println("2)"); transactions.stream() .map(Transaction::getTrader) .map(Trader::getCity) .distinct() - .collect(Collectors.toList()) + .collect(toList()) .forEach(out::println); out.println("3)"); transactions.stream() @@ -145,7 +148,7 @@ public class StreamTest { .filter(trader -> "Cambridge".equalsIgnoreCase(trader.getCity())) .distinct() // anche se sul testo non รจ specificato che dovevano essere diversi .sorted(Comparator.comparing(Trader::getName)) - .collect(Collectors.toList()) + .collect(toList()) .forEach(out::println); out.println("4)"); String result = transactions.stream() @@ -180,19 +183,107 @@ public class StreamTest { .flatMap(a -> IntStream.rangeClosed(a, 100) .mapToObj(b -> new double[]{a, b, Math.sqrt(a * a + b * b)}) .filter(t -> t[2] % 1 == 0) - ) + ) .limit(5) .forEach(triple -> out.printf("(%.0f, %.0f, %.0f)\n", triple[0], triple[1], triple[2])); out.println("----------------------------------------"); - Stream.iterate(new int[] {0, 1}, t -> new int[] {t[1], t[0] + t[1]}) + Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]}) .limit(20) .forEach(pair -> out.printf("(%d, %d) ", pair[0], pair[1])); out.println(); out.println("----------------------------------------"); } + private static void doStreamCollectingDemo() { + List menu = getDishes(); + long howManyDishes = menu.stream().count(); + out.println(howManyDishes); + out.println("----------------------------------------"); + Comparator dishCaloriesComparator = comparingInt(Dish::getCalories); + menu.stream() + .collect(maxBy(dishCaloriesComparator)) + .ifPresent(out::println); + out.println("----------------------------------------"); + int totalCalories = menu.stream().collect(summingInt(Dish::getCalories)); + out.println(totalCalories); + out.println("----------------------------------------"); + double avgCalories = menu.stream().collect(averagingInt(Dish::getCalories)); + out.println(avgCalories); + out.println("----------------------------------------"); + IntSummaryStatistics menuStatistics = menu.stream().collect(summarizingInt(Dish::getCalories)); + out.println(menuStatistics); + out.println("----------------------------------------"); + String shortMenu = menu.stream() + .map(Dish::getName) + .collect(joining(", ")); + out.println(shortMenu); + out.println("----------------------------------------"); + Map> dishesByType = menu.stream().collect(groupingBy(Dish::getType)); + out.println(dishesByType); + out.println("----------------------------------------"); + Map> 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; + })); + out.println(dishesByCaloricLevel); + out.println("----------------------------------------"); + Map> caloricDishesByType = + menu.stream() + .collect(groupingBy(Dish::getType, + filtering(dish -> dish.getCalories() > 500, + toList()))); + out.println(caloricDishesByType); + out.println("----------------------------------------"); + Map> dishNamesByType = + menu.stream() + .collect(groupingBy(Dish::getType, + mapping(Dish::getName, toList()))); + out.println(dishNamesByType); + out.println("----------------------------------------"); + Map> dishTags = Map.of( + "pork", asList("greasy", "salty"), + "beef", asList("salty", "roasted"), + "chicken", asList("fried", "crisp"), + "french fries", asList("greasy", "fried"), + "rice", asList("light", "natural"), + "season fruit", asList("fresh", "natural"), + "pizza", asList("tasty", "salty"), + "prawns", asList("tasty", "roasted"), + "salmon", asList("delicious", "fresh") + ); + Map> dishNamesByType2 = + menu.stream() + .collect(groupingBy(Dish::getType, + flatMapping(dish -> { + // FIXME: The example of book is not safety + List tags = dishTags.get(dish.getName()); + if (tags != null) { + return tags.stream(); + } + return Stream.empty(); + }, toSet()))); + out.println(dishNamesByType2); + out.println("----------------------------------------"); + Map>> 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; + }))); + out.println(dishesByTypeCaloricLevel); + out.println("----------------------------------------"); + } + + enum CaloricLevel {DIET, NORMAL, FAT} + private static List getDishes() { - List dishes = Arrays.asList( + List dishes = asList( new Dish("pork", 300, Dish.Type.MEAT), new Dish("salad", 50, Dish.Type.VEGETARIAN), new Dish("chicken", 100, Dish.Type.MEAT), @@ -200,7 +291,7 @@ public class StreamTest { new Dish("tomato", 30, Dish.Type.VEGETARIAN), new Dish("tunny", 120, Dish.Type.FISH), new Dish("potato", 70, Dish.Type.VEGETARIAN) - ); + ); return Collections.unmodifiableList(dishes); }