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,26 +121,26 @@ 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),
new Transaction(mario, 2012, 710), new Transaction(mario, 2012, 710),
new Transaction(mario, 2012, 700), new Transaction(mario, 2012, 700),
new Transaction(alan, 2012, 950) new Transaction(alan, 2012, 950)
); );
out.println("1)"); out.println("1)");
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()
@@ -180,19 +183,107 @@ public class StreamTest {
.flatMap(a -> IntStream.rangeClosed(a, 100) .flatMap(a -> IntStream.rangeClosed(a, 100)
.mapToObj(b -> new double[]{a, b, Math.sqrt(a * a + b * b)}) .mapToObj(b -> new double[]{a, b, Math.sqrt(a * a + b * b)})
.filter(t -> t[2] % 1 == 0) .filter(t -> t[2] % 1 == 0)
) )
.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),
@@ -200,7 +291,7 @@ public class StreamTest {
new Dish("tomato", 30, Dish.Type.VEGETARIAN), new Dish("tomato", 30, Dish.Type.VEGETARIAN),
new Dish("tunny", 120, Dish.Type.FISH), new Dish("tunny", 120, Dish.Type.FISH),
new Dish("potato", 70, Dish.Type.VEGETARIAN) new Dish("potato", 70, Dish.Type.VEGETARIAN)
); );
return Collections.unmodifiableList(dishes); return Collections.unmodifiableList(dishes);
} }