Algoritmi di collector

This commit is contained in:
Fabio Scotto di Santolo
2019-11-21 17:43:50 +01:00
parent 0f0ae0ccec
commit 60630cd7f1

View File

@@ -1,11 +1,13 @@
package org.gym.fp.moderjava; package org.gym.fp.moderjava;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
import static java.lang.System.out; 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 { public class StreamTest {
@@ -14,13 +16,14 @@ public class StreamTest {
doStreamMappingDemo(); doStreamMappingDemo();
doStreamFindOrMatchingDemo(); doStreamFindOrMatchingDemo();
doStreamReducingDemo(); doStreamReducingDemo();
doStreamCollectingDemo();
} }
private static void doStreamFilterDemo() { private static void doStreamFilterDemo() {
out.println("FILTER EXAMPLE"); out.println("FILTER EXAMPLE");
getDishes().stream() getDishes().stream()
.filter(Dish::isVegetarian) .filter(Dish::isVegetarian)
.collect(Collectors.toList()) .collect(toList())
.forEach(out::println); .forEach(out::println);
out.println("----------------------------------------"); out.println("----------------------------------------");
out.println("DISTINCT EXAMPLE"); out.println("DISTINCT EXAMPLE");
@@ -42,26 +45,26 @@ public class StreamTest {
} }
private static void doStreamMappingDemo() { private static void doStreamMappingDemo() {
List<String> words = Arrays.asList("Hello", "World"); List<String> words = asList("Hello", "World");
List<String> uniqueCharacters = words.stream() List<String> uniqueCharacters = words.stream()
.map(word -> word.split("")) .map(word -> word.split(""))
.flatMap(Arrays::stream) .flatMap(Arrays::stream)
.distinct() .distinct()
.collect(Collectors.toList()); .collect(toList());
out.println(uniqueCharacters); out.println(uniqueCharacters);
out.println("----------------------------------------"); out.println("----------------------------------------");
out.println("Permutations"); out.println("Permutations");
List<Integer> numbers1 = Arrays.asList(1, 2, 3); List<Integer> numbers1 = asList(1, 2, 3);
List<Integer> numbers2 = Arrays.asList(3, 4); List<Integer> numbers2 = asList(3, 4);
List<int[]> pairs1 = numbers1.stream() List<int[]> pairs1 = numbers1.stream()
.flatMap(i -> numbers2.stream().map(j -> new int[]{i, j})) .flatMap(i -> numbers2.stream().map(j -> new int[]{i, j}))
.collect(Collectors.toList()); .collect(toList());
pairs1.forEach(pair -> out.println(Arrays.toString(pair))); pairs1.forEach(pair -> out.println(Arrays.toString(pair)));
out.println("----------------------------------------"); out.println("----------------------------------------");
List<int[]> pairs2 = numbers1.stream() List<int[]> pairs2 = numbers1.stream()
.flatMap(i -> numbers2.stream().map(j -> new int[]{i, j})) .flatMap(i -> numbers2.stream().map(j -> new int[]{i, j}))
.filter(pair -> (pair[0] + pair[1]) % 3 == 0) .filter(pair -> (pair[0] + pair[1]) % 3 == 0)
.collect(Collectors.toList()); .collect(toList());
pairs2.forEach(pair -> out.println(Arrays.toString(pair))); pairs2.forEach(pair -> out.println(Arrays.toString(pair)));
out.println("----------------------------------------"); out.println("----------------------------------------");
} }
@@ -89,7 +92,7 @@ public class StreamTest {
dish.ifPresent(out::println); dish.ifPresent(out::println);
out.println("----------------------------------------"); out.println("----------------------------------------");
out.println("FINDFIRST EXAMPLE"); out.println("FINDFIRST EXAMPLE");
List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> someNumbers = asList(1, 2, 3, 4, 5);
someNumbers.stream() someNumbers.stream()
.map(n -> n * n) .map(n -> n * n)
.filter(n -> n % 3 == 0) .filter(n -> n % 3 == 0)
@@ -118,7 +121,7 @@ public class StreamTest {
Trader mario = new Trader("Mario", "Milan"); Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge"); Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge"); Trader brian = new Trader("Brian", "Cambridge");
List<Transaction> transactions = Arrays.asList( List<Transaction> transactions = asList(
new Transaction(brian, 2011, 300), new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000), new Transaction(raoul, 2012, 1000),
new Transaction(raoul, 2011, 400), new Transaction(raoul, 2011, 400),
@@ -130,14 +133,14 @@ public class StreamTest {
transactions.stream() transactions.stream()
.filter(t -> t.getYear() == 2011) .filter(t -> t.getYear() == 2011)
.sorted(Comparator.comparing(Transaction::getValue)) .sorted(Comparator.comparing(Transaction::getValue))
.collect(Collectors.toList()) .collect(toList())
.forEach(out::println); .forEach(out::println);
out.println("2)"); out.println("2)");
transactions.stream() transactions.stream()
.map(Transaction::getTrader) .map(Transaction::getTrader)
.map(Trader::getCity) .map(Trader::getCity)
.distinct() .distinct()
.collect(Collectors.toList()) .collect(toList())
.forEach(out::println); .forEach(out::println);
out.println("3)"); out.println("3)");
transactions.stream() transactions.stream()
@@ -145,7 +148,7 @@ public class StreamTest {
.filter(trader -> "Cambridge".equalsIgnoreCase(trader.getCity())) .filter(trader -> "Cambridge".equalsIgnoreCase(trader.getCity()))
.distinct() // anche se sul testo non è specificato che dovevano essere diversi .distinct() // anche se sul testo non è specificato che dovevano essere diversi
.sorted(Comparator.comparing(Trader::getName)) .sorted(Comparator.comparing(Trader::getName))
.collect(Collectors.toList()) .collect(toList())
.forEach(out::println); .forEach(out::println);
out.println("4)"); out.println("4)");
String result = transactions.stream() String result = transactions.stream()
@@ -184,15 +187,103 @@ public class StreamTest {
.limit(5) .limit(5)
.forEach(triple -> out.printf("(%.0f, %.0f, %.0f)\n", triple[0], triple[1], triple[2])); .forEach(triple -> out.printf("(%.0f, %.0f, %.0f)\n", triple[0], triple[1], triple[2]));
out.println("----------------------------------------"); 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) .limit(20)
.forEach(pair -> out.printf("(%d, %d) ", pair[0], pair[1])); .forEach(pair -> out.printf("(%d, %d) ", pair[0], pair[1]));
out.println(); out.println();
out.println("----------------------------------------"); out.println("----------------------------------------");
} }
private static void doStreamCollectingDemo() {
List<Dish> menu = getDishes();
long howManyDishes = menu.stream().count();
out.println(howManyDishes);
out.println("----------------------------------------");
Comparator<Dish> 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<Dish.Type, List<Dish>> dishesByType = menu.stream().collect(groupingBy(Dish::getType));
out.println(dishesByType);
out.println("----------------------------------------");
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;
}));
out.println(dishesByCaloricLevel);
out.println("----------------------------------------");
Map<Dish.Type, List<Dish>> caloricDishesByType =
menu.stream()
.collect(groupingBy(Dish::getType,
filtering(dish -> dish.getCalories() > 500,
toList())));
out.println(caloricDishesByType);
out.println("----------------------------------------");
Map<Dish.Type, List<String>> dishNamesByType =
menu.stream()
.collect(groupingBy(Dish::getType,
mapping(Dish::getName, toList())));
out.println(dishNamesByType);
out.println("----------------------------------------");
Map<String, List<String>> 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<Dish.Type, Set<String>> dishNamesByType2 =
menu.stream()
.collect(groupingBy(Dish::getType,
flatMapping(dish -> {
// FIXME: The example of book is not safety
List<String> tags = dishTags.get(dish.getName());
if (tags != null) {
return tags.stream();
}
return Stream.empty();
}, toSet())));
out.println(dishNamesByType2);
out.println("----------------------------------------");
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;
})));
out.println(dishesByTypeCaloricLevel);
out.println("----------------------------------------");
}
enum CaloricLevel {DIET, NORMAL, FAT}
private static List<Dish> getDishes() { private static List<Dish> getDishes() {
List<Dish> dishes = Arrays.asList( List<Dish> dishes = asList(
new Dish("pork", 300, Dish.Type.MEAT), new Dish("pork", 300, Dish.Type.MEAT),
new Dish("salad", 50, Dish.Type.VEGETARIAN), new Dish("salad", 50, Dish.Type.VEGETARIAN),
new Dish("chicken", 100, Dish.Type.MEAT), new Dish("chicken", 100, Dish.Type.MEAT),