From 4786c46a24e2f7d0a749d34d585bb2c1d9f64c53 Mon Sep 17 00:00:00 2001 From: Mario Fusco Date: Fri, 24 Feb 2017 08:52:33 +0100 Subject: [PATCH] changes for 2nd edition --- pom.xml | 35 ++++++++++- .../chap10/OperationsWithOptional.java | 7 +++ .../lambdasinaction/chap10/OptionalMain.java | 11 ++++ src/main/java/lambdasinaction/chap6/Dish.java | 34 +++++++--- .../java/lambdasinaction/chap6/Grouping.java | 17 +++++ .../chap6/PartitionPrimeNumbers.java | 8 +-- .../chap7/ParallelStreamBenchmark.java | 62 +++++++++++++++++++ 7 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 src/main/java/lambdasinaction/chap7/ParallelStreamBenchmark.java diff --git a/pom.xml b/pom.xml index 32ca0b3e..10e5035e 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,16 @@ + + org.openjdk.jmh + jmh-core + 1.17.4 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.17.4 + junit junit @@ -27,11 +37,30 @@ maven-compiler-plugin 3.1 - 1.8 - 1.8 + 1.9 + 1.9 + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + benchmarks + + + org.openjdk.jmh.Main + + + + + + - \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java index de588759..d2940969 100644 --- a/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java +++ b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java @@ -10,6 +10,13 @@ public class OperationsWithOptional { public static void main(String... args) { System.out.println(max(of(3), of(5))); System.out.println(max(empty(), of(5))); + + Optional opt1 = of(5); + Optional opt2 = opt1.or(() -> of(4)); + + System.out.println( + of(5).or(() -> of(4)) + ); } public static final Optional max(Optional i, Optional j) { diff --git a/src/main/java/lambdasinaction/chap10/OptionalMain.java b/src/main/java/lambdasinaction/chap10/OptionalMain.java index 1826cb4a..dcd97792 100644 --- a/src/main/java/lambdasinaction/chap10/OptionalMain.java +++ b/src/main/java/lambdasinaction/chap10/OptionalMain.java @@ -2,6 +2,8 @@ import java.util.*; +import static java.util.stream.Collectors.toSet; + public class OptionalMain { public String getCarInsuranceName(Optional person) { @@ -10,4 +12,13 @@ public String getCarInsuranceName(Optional person) { .map(Insurance::getName) .orElse("Unknown"); } + + public Set getCarInsuranceNames(List persons) { + return persons.stream() + .map(Person::getCar) + .map(optCar -> optCar.flatMap(Car::getInsurance)) + .map(optInsurance -> optInsurance.map(Insurance::getName)) + .flatMap(Optional::stream) + .collect(toSet()); + } } diff --git a/src/main/java/lambdasinaction/chap6/Dish.java b/src/main/java/lambdasinaction/chap6/Dish.java index a353f1bc..adba6e93 100644 --- a/src/main/java/lambdasinaction/chap6/Dish.java +++ b/src/main/java/lambdasinaction/chap6/Dish.java @@ -2,6 +2,8 @@ import java.util.*; +import static java.util.Arrays.asList; + public class Dish { private final String name; @@ -40,13 +42,27 @@ public String toString() { } public static final List menu = - Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), - new Dish("beef", false, 700, Dish.Type.MEAT), - new Dish("chicken", false, 400, Dish.Type.MEAT), - new Dish("french fries", true, 530, Dish.Type.OTHER), - new Dish("rice", true, 350, Dish.Type.OTHER), - new Dish("season fruit", true, 120, Dish.Type.OTHER), - new Dish("pizza", true, 550, Dish.Type.OTHER), - new Dish("prawns", false, 400, Dish.Type.FISH), - new Dish("salmon", false, 450, Dish.Type.FISH)); + asList( new Dish("pork", false, 800, Dish.Type.MEAT), + new Dish("beef", false, 700, Dish.Type.MEAT), + new Dish("chicken", false, 400, Dish.Type.MEAT), + new Dish("french fries", true, 530, Dish.Type.OTHER), + new Dish("rice", true, 350, Dish.Type.OTHER), + new Dish("season fruit", true, 120, Dish.Type.OTHER), + new Dish("pizza", true, 550, Dish.Type.OTHER), + new Dish("prawns", false, 400, Dish.Type.FISH), + new Dish("salmon", false, 450, Dish.Type.FISH)); + + public static final Map> dishTags = new HashMap<>(); + + static { + dishTags.put("pork", asList("greasy", "salty")); + dishTags.put("beef", asList("salty", "roasted")); + dishTags.put("chicken", asList("fried", "crisp")); + dishTags.put("french fries", asList("greasy", "fried")); + dishTags.put("rice", asList("light", "natural")); + dishTags.put("season fruit", asList("fresh", "natural")); + dishTags.put("pizza", asList("tasty", "salty")); + dishTags.put("prawns", asList("tasty", "roasted")); + dishTags.put("salmon", asList("delicious", "fresh")); + } } \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap6/Grouping.java b/src/main/java/lambdasinaction/chap6/Grouping.java index bedb3470..9105cc80 100644 --- a/src/main/java/lambdasinaction/chap6/Grouping.java +++ b/src/main/java/lambdasinaction/chap6/Grouping.java @@ -3,6 +3,7 @@ import java.util.*; import static java.util.stream.Collectors.*; +import static lambdasinaction.chap6.Dish.dishTags; import static lambdasinaction.chap6.Dish.menu; public class Grouping { @@ -11,6 +12,9 @@ enum CaloricLevel { DIET, NORMAL, FAT }; public static void main(String ... args) { System.out.println("Dishes grouped by type: " + groupDishesByType()); + System.out.println("Dish names grouped by type: " + groupDishNamesByType()); + System.out.println("Dish tags grouped by type: " + groupDishTagsByType()); + System.out.println("Caloric dishes grouped by type: " + groupCaloricDishesByType()); System.out.println("Dishes grouped by caloric level: " + groupDishesByCaloricLevel()); System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel()); System.out.println("Count dishes in groups: " + countDishesInGroups()); @@ -24,6 +28,19 @@ private static Map> groupDishesByType() { return menu.stream().collect(groupingBy(Dish::getType)); } + private static Map> groupDishNamesByType() { + return menu.stream().collect(groupingBy(Dish::getType, mapping(Dish::getName, toList()))); + } + + private static Map> groupDishTagsByType() { + return menu.stream().collect(groupingBy(Dish::getType, flatMapping(dish -> dishTags.get( dish.getName() ).stream(), toSet()))); + } + + private static Map> groupCaloricDishesByType() { +// return menu.stream().filter(dish -> dish.getCalories() > 500).collect(groupingBy(Dish::getType)); + return menu.stream().collect(groupingBy(Dish::getType, filtering(dish -> dish.getCalories() > 500, toList()))); + } + private static Map> groupDishesByCaloricLevel() { return menu.stream().collect( groupingBy(dish -> { diff --git a/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java b/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java index 5122a6a3..69d7c4ca 100644 --- a/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java +++ b/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java @@ -32,10 +32,10 @@ public static Map> partitionPrimesWithCustomCollector(int public static boolean isPrime(List primes, Integer candidate) { double candidateRoot = Math.sqrt((double) candidate); - //return primes.stream().filter(p -> p < candidateRoot).noneMatch(p -> candidate % p == 0); - return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0); + //return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0); + return primes.stream().takeWhile(i -> i <= candidateRoot).noneMatch(i -> candidate % i == 0); } - +/* public static List takeWhile(List list, Predicate p) { int i = 0; for (A item : list) { @@ -46,7 +46,7 @@ public static List takeWhile(List list, Predicate p) { } return list; } - +*/ public static class PrimeNumbersCollector implements Collector>, Map>> { diff --git a/src/main/java/lambdasinaction/chap7/ParallelStreamBenchmark.java b/src/main/java/lambdasinaction/chap7/ParallelStreamBenchmark.java new file mode 100644 index 00000000..cdd16aca --- /dev/null +++ b/src/main/java/lambdasinaction/chap7/ParallelStreamBenchmark.java @@ -0,0 +1,62 @@ +package lambdasinaction.chap7; + +import java.util.concurrent.TimeUnit; +import java.util.stream.LongStream; +import java.util.stream.Stream; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Fork(value=2, jvmArgs={"-Xms4G", "-Xmx4G"}) +@Measurement(iterations=2) +@Warmup(iterations=3) +public class ParallelStreamBenchmark { + + private static final long N = 10_000_000L; + + @Benchmark + public long iterativeSum() { + long result = 0; + for (long i = 1L; i <= N; i++) { + result += i; + } + return result; + } + + @Benchmark + public long sequentialSum() { + return Stream.iterate( 1L, i -> i + 1 ).limit(N).reduce( 0L, Long::sum ); + } + + @Benchmark + public long parallelSum() { + return Stream.iterate(1L, i -> i + 1).limit(N).parallel().reduce( 0L, Long::sum); + } + + @Benchmark + public long rangedSum() { + return LongStream.rangeClosed( 1, N ).reduce( 0L, Long::sum ); + } + + @Benchmark + public long parallelRangedSum() { + return LongStream.rangeClosed(1, N).parallel().reduce( 0L, Long::sum); + } + + @TearDown(Level.Invocation) + public void tearDown() { + System.gc(); + } +}