diff --git a/README.md b/README.md index 73664d8a..9ee848d5 100644 --- a/README.md +++ b/README.md @@ -3,28 +3,30 @@ Java8InAction This repository contains all the source code for the examples and quizzes in the book Java 8 in Action: Lambdas, Streams and functional-style programming. -You can purchase the early access here: [http://manning.com/urma/](http://manning.com/urma/) - -We are very keen to hear your feedback and improve the book based on your comments! +You can purchase the book here: [http://manning.com/urma/](http://manning.com/urma/) or on Amazon The source code for all examples can be found in the directory [src/main/java/lambdasinaction](https://github.com/java8/Java8InAction/tree/master/src/main/java/lambdasinaction) * Chapter 1: Java 8: why should you care? * Chapter 2: Passing code with behavior parameterization * Chapter 3: Lambda expressions -* Chapter 4: Processing data with streams -* Chapter 5: Collecting data with streams -* Chapter 6: Parallel data processing and performance -* Chapter 7: Refactoring, testing, debugging -* Chapter 8: Default methods -* Chapter 9: Optional: a better alternative to null -* Chapter 10: CompletableFuture: composable asynchronous programming -* Chapter 11: New Date and Time API -* Chapter 12: Thinking functionally -* Chapter 13: Functional programming techniques -* Chapter 14: Blending OOP and FP: comparing Java 8 and Scala -* Chapter 15: Conclusions and "where next" for Java - +* Chapter 4: Working with Streams +* Chapter 5: Processing data with streams +* Chapter 6: Collecting data with streams +* Chapter 7: Parallel data processing and performance +* Chapter 8: Refactoring, testing, debugging +* Chapter 9: Default methods +* Chapter 10: Using Optional as a better alternative to null +* Chapter 11: CompletableFuture: composable asynchronous programming +* Chapter 12: New Date and Time API +* Chapter 13: Thinking functionally +* Chapter 14: Functional programming techniques +* Chapter 15: Blending OOP and FP: comparing Java 8 and Scala +* Chapter 16: Conclusions and "where next" for Java +* Appendix A: Miscellaneous language updates +* Appendix B: Miscellaneous library updates +* Appendix C: Performing multiple operations in parallel on a Stream +* Appendix D: Lambdas and JVM bytecode We will update the repository as we update the book. Stay tuned! ### Make sure to have JDK8 installed @@ -50,3 +52,8 @@ $ java lambdasinaction/chap1/FilteringApples Alternatively you can compile the files manually inside the directory src/main/java + +You can also import the project in your favorite IDE: + * In IntelliJ use "File->Open" menu and navigate to the folder where the project resides + * In Eclipse use "File->Import->Existing Maven Projects" (also modify "Reduntant super interfaces" to report as Warnings instead of Errors + * In Netbeans use "File->Open Project" menu \ No newline at end of file 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/appc/StreamForkerExample.java b/src/main/java/lambdasinaction/appc/StreamForkerExample.java index fe2dacd5..1d1ffdbc 100644 --- a/src/main/java/lambdasinaction/appc/StreamForkerExample.java +++ b/src/main/java/lambdasinaction/appc/StreamForkerExample.java @@ -1,9 +1,9 @@ package lambdasinaction.appc; -import lambdasinaction.chap5.*; +import lambdasinaction.chap6.*; import static java.util.stream.Collectors.*; -import static lambdasinaction.chap5.Dish.menu; +import static lambdasinaction.chap6.Dish.menu; import java.util.*; import java.util.stream.*; diff --git a/src/main/java/lambdasinaction/chap9/Car.java b/src/main/java/lambdasinaction/chap10/Car.java similarity index 84% rename from src/main/java/lambdasinaction/chap9/Car.java rename to src/main/java/lambdasinaction/chap10/Car.java index 1b0f77db..36f00727 100644 --- a/src/main/java/lambdasinaction/chap9/Car.java +++ b/src/main/java/lambdasinaction/chap10/Car.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap9; +package lambdasinaction.chap10; import java.util.*; diff --git a/src/main/java/lambdasinaction/chap9/Insurance.java b/src/main/java/lambdasinaction/chap10/Insurance.java similarity index 77% rename from src/main/java/lambdasinaction/chap9/Insurance.java rename to src/main/java/lambdasinaction/chap10/Insurance.java index d48eb927..69409686 100644 --- a/src/main/java/lambdasinaction/chap9/Insurance.java +++ b/src/main/java/lambdasinaction/chap10/Insurance.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap9; +package lambdasinaction.chap10; public class Insurance { diff --git a/src/main/java/lambdasinaction/chap9/OperationsWithOptional.java b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java similarity index 67% rename from src/main/java/lambdasinaction/chap9/OperationsWithOptional.java rename to src/main/java/lambdasinaction/chap10/OperationsWithOptional.java index cc5491db..d2940969 100644 --- a/src/main/java/lambdasinaction/chap9/OperationsWithOptional.java +++ b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap9; +package lambdasinaction.chap10; import java.util.*; @@ -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 new file mode 100644 index 00000000..dcd97792 --- /dev/null +++ b/src/main/java/lambdasinaction/chap10/OptionalMain.java @@ -0,0 +1,24 @@ +package lambdasinaction.chap10; + +import java.util.*; + +import static java.util.stream.Collectors.toSet; + +public class OptionalMain { + + public String getCarInsuranceName(Optional person) { + return person.flatMap(Person::getCar) + .flatMap(Car::getInsurance) + .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/chap9/Person.java b/src/main/java/lambdasinaction/chap10/Person.java similarity index 81% rename from src/main/java/lambdasinaction/chap9/Person.java rename to src/main/java/lambdasinaction/chap10/Person.java index eb4d3726..5e84e552 100644 --- a/src/main/java/lambdasinaction/chap9/Person.java +++ b/src/main/java/lambdasinaction/chap10/Person.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap9; +package lambdasinaction.chap10; import java.util.*; diff --git a/src/main/java/lambdasinaction/chap9/ReadPositiveIntParam.java b/src/main/java/lambdasinaction/chap10/ReadPositiveIntParam.java similarity index 98% rename from src/main/java/lambdasinaction/chap9/ReadPositiveIntParam.java rename to src/main/java/lambdasinaction/chap10/ReadPositiveIntParam.java index ee2cf434..acac12b9 100644 --- a/src/main/java/lambdasinaction/chap9/ReadPositiveIntParam.java +++ b/src/main/java/lambdasinaction/chap10/ReadPositiveIntParam.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap9; +package lambdasinaction.chap10; import org.junit.*; diff --git a/src/main/java/lambdasinaction/chap10/AsyncShop.java b/src/main/java/lambdasinaction/chap11/AsyncShop.java similarity index 89% rename from src/main/java/lambdasinaction/chap10/AsyncShop.java rename to src/main/java/lambdasinaction/chap11/AsyncShop.java index 4d230e7d..9d537368 100644 --- a/src/main/java/lambdasinaction/chap10/AsyncShop.java +++ b/src/main/java/lambdasinaction/chap11/AsyncShop.java @@ -1,7 +1,7 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; -import static lambdasinaction.chap10.Util.delay; -import static lambdasinaction.chap10.Util.format; +import static lambdasinaction.chap11.Util.delay; +import static lambdasinaction.chap11.Util.format; import java.util.Random; import java.util.concurrent.CompletableFuture; diff --git a/src/main/java/lambdasinaction/chap10/AsyncShopClient.java b/src/main/java/lambdasinaction/chap11/AsyncShopClient.java similarity index 95% rename from src/main/java/lambdasinaction/chap10/AsyncShopClient.java rename to src/main/java/lambdasinaction/chap11/AsyncShopClient.java index 029e9b30..9a78f827 100644 --- a/src/main/java/lambdasinaction/chap10/AsyncShopClient.java +++ b/src/main/java/lambdasinaction/chap11/AsyncShopClient.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; import java.util.concurrent.Future; diff --git a/src/main/java/lambdasinaction/chap10/BestPriceFinder.java b/src/main/java/lambdasinaction/chap11/BestPriceFinder.java similarity index 98% rename from src/main/java/lambdasinaction/chap10/BestPriceFinder.java rename to src/main/java/lambdasinaction/chap11/BestPriceFinder.java index 25cf3870..51412e93 100644 --- a/src/main/java/lambdasinaction/chap10/BestPriceFinder.java +++ b/src/main/java/lambdasinaction/chap11/BestPriceFinder.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/lambdasinaction/chap10/BestPriceFinderMain.java b/src/main/java/lambdasinaction/chap11/BestPriceFinderMain.java similarity index 96% rename from src/main/java/lambdasinaction/chap10/BestPriceFinderMain.java rename to src/main/java/lambdasinaction/chap11/BestPriceFinderMain.java index 1f4f5612..43ec8fba 100644 --- a/src/main/java/lambdasinaction/chap10/BestPriceFinderMain.java +++ b/src/main/java/lambdasinaction/chap11/BestPriceFinderMain.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; import java.util.List; import java.util.function.Supplier; diff --git a/src/main/java/lambdasinaction/chap10/Discount.java b/src/main/java/lambdasinaction/chap11/Discount.java similarity index 81% rename from src/main/java/lambdasinaction/chap10/Discount.java rename to src/main/java/lambdasinaction/chap11/Discount.java index e0c0b072..5624abd1 100644 --- a/src/main/java/lambdasinaction/chap10/Discount.java +++ b/src/main/java/lambdasinaction/chap11/Discount.java @@ -1,7 +1,7 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; -import static lambdasinaction.chap10.Util.delay; -import static lambdasinaction.chap10.Util.format; +import static lambdasinaction.chap11.Util.delay; +import static lambdasinaction.chap11.Util.format; public class Discount { diff --git a/src/main/java/lambdasinaction/chap10/ExchangeService.java b/src/main/java/lambdasinaction/chap11/ExchangeService.java similarity index 86% rename from src/main/java/lambdasinaction/chap10/ExchangeService.java rename to src/main/java/lambdasinaction/chap11/ExchangeService.java index 9ae1ccdb..3f98a7e3 100644 --- a/src/main/java/lambdasinaction/chap10/ExchangeService.java +++ b/src/main/java/lambdasinaction/chap11/ExchangeService.java @@ -1,6 +1,6 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; -import static lambdasinaction.chap10.Util.delay; +import static lambdasinaction.chap11.Util.delay; public class ExchangeService { diff --git a/src/main/java/lambdasinaction/chap10/Quote.java b/src/main/java/lambdasinaction/chap11/Quote.java similarity index 96% rename from src/main/java/lambdasinaction/chap10/Quote.java rename to src/main/java/lambdasinaction/chap11/Quote.java index 2bba954b..72dd81bf 100644 --- a/src/main/java/lambdasinaction/chap10/Quote.java +++ b/src/main/java/lambdasinaction/chap11/Quote.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; public class Quote { diff --git a/src/main/java/lambdasinaction/chap10/Shop.java b/src/main/java/lambdasinaction/chap11/Shop.java similarity index 84% rename from src/main/java/lambdasinaction/chap10/Shop.java rename to src/main/java/lambdasinaction/chap11/Shop.java index 4aa88ec7..bf0446fe 100644 --- a/src/main/java/lambdasinaction/chap10/Shop.java +++ b/src/main/java/lambdasinaction/chap11/Shop.java @@ -1,7 +1,7 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; -import static lambdasinaction.chap10.Util.delay; -import static lambdasinaction.chap10.Util.format; +import static lambdasinaction.chap11.Util.delay; +import static lambdasinaction.chap11.Util.format; import java.util.Random; diff --git a/src/main/java/lambdasinaction/chap10/Util.java b/src/main/java/lambdasinaction/chap11/Util.java similarity index 97% rename from src/main/java/lambdasinaction/chap10/Util.java rename to src/main/java/lambdasinaction/chap11/Util.java index f0a0f5f4..a72c4d33 100644 --- a/src/main/java/lambdasinaction/chap10/Util.java +++ b/src/main/java/lambdasinaction/chap11/Util.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap10; +package lambdasinaction.chap11; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; diff --git a/src/main/java/lambdasinaction/chap10/v1/BestPriceFinder.java b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java similarity index 98% rename from src/main/java/lambdasinaction/chap10/v1/BestPriceFinder.java rename to src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java index 42022883..1bbb6030 100644 --- a/src/main/java/lambdasinaction/chap10/v1/BestPriceFinder.java +++ b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap10.v1; +package lambdasinaction.chap11.v1; import java.util.ArrayList; import java.util.Arrays; @@ -14,8 +14,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import lambdasinaction.chap10.ExchangeService; -import lambdasinaction.chap10.ExchangeService.Money; +import lambdasinaction.chap11.ExchangeService; +import lambdasinaction.chap11.ExchangeService.Money; public class BestPriceFinder { diff --git a/src/main/java/lambdasinaction/chap10/v1/BestPriceFinderMain.java b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java similarity index 96% rename from src/main/java/lambdasinaction/chap10/v1/BestPriceFinderMain.java rename to src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java index c1c0f80a..5a74161a 100644 --- a/src/main/java/lambdasinaction/chap10/v1/BestPriceFinderMain.java +++ b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap10.v1; +package lambdasinaction.chap11.v1; import java.util.List; import java.util.function.Supplier; diff --git a/src/main/java/lambdasinaction/chap10/v1/Shop.java b/src/main/java/lambdasinaction/chap11/v1/Shop.java similarity index 92% rename from src/main/java/lambdasinaction/chap10/v1/Shop.java rename to src/main/java/lambdasinaction/chap11/v1/Shop.java index 9a4350d3..cd3da975 100644 --- a/src/main/java/lambdasinaction/chap10/v1/Shop.java +++ b/src/main/java/lambdasinaction/chap11/v1/Shop.java @@ -1,6 +1,6 @@ -package lambdasinaction.chap10.v1; +package lambdasinaction.chap11.v1; -import static lambdasinaction.chap10.Util.delay; +import static lambdasinaction.chap11.Util.delay; import java.util.Random; import java.util.concurrent.CompletableFuture; diff --git a/src/main/java/lambdasinaction/chap10/v1/ShopMain.java b/src/main/java/lambdasinaction/chap11/v1/ShopMain.java similarity index 96% rename from src/main/java/lambdasinaction/chap10/v1/ShopMain.java rename to src/main/java/lambdasinaction/chap11/v1/ShopMain.java index b972713f..ea1a19c1 100644 --- a/src/main/java/lambdasinaction/chap10/v1/ShopMain.java +++ b/src/main/java/lambdasinaction/chap11/v1/ShopMain.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap10.v1; +package lambdasinaction.chap11.v1; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; diff --git a/src/main/java/lambdasinaction/chap11/DateTimeExamples.java b/src/main/java/lambdasinaction/chap12/DateTimeExamples.java similarity index 99% rename from src/main/java/lambdasinaction/chap11/DateTimeExamples.java rename to src/main/java/lambdasinaction/chap12/DateTimeExamples.java index ff11ee61..46895cc5 100644 --- a/src/main/java/lambdasinaction/chap11/DateTimeExamples.java +++ b/src/main/java/lambdasinaction/chap12/DateTimeExamples.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap11; +package lambdasinaction.chap12; import static java.time.temporal.TemporalAdjusters.lastDayOfMonth; import static java.time.temporal.TemporalAdjusters.nextOrSame; diff --git a/src/main/java/lambdasinaction/chap12/Recursion.java b/src/main/java/lambdasinaction/chap13/Recursion.java similarity index 96% rename from src/main/java/lambdasinaction/chap12/Recursion.java rename to src/main/java/lambdasinaction/chap13/Recursion.java index 223600e7..77f66d57 100644 --- a/src/main/java/lambdasinaction/chap12/Recursion.java +++ b/src/main/java/lambdasinaction/chap13/Recursion.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap12; +package lambdasinaction.chap13; import java.util.stream.LongStream; diff --git a/src/main/java/lambdasinaction/chap12/SubsetsMain.java b/src/main/java/lambdasinaction/chap13/SubsetsMain.java similarity index 97% rename from src/main/java/lambdasinaction/chap12/SubsetsMain.java rename to src/main/java/lambdasinaction/chap13/SubsetsMain.java index 61c52fb5..02b51998 100644 --- a/src/main/java/lambdasinaction/chap12/SubsetsMain.java +++ b/src/main/java/lambdasinaction/chap13/SubsetsMain.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap12; +package lambdasinaction.chap13; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/lambdasinaction/chap13/Combinators.java b/src/main/java/lambdasinaction/chap14/Combinators.java similarity index 93% rename from src/main/java/lambdasinaction/chap13/Combinators.java rename to src/main/java/lambdasinaction/chap14/Combinators.java index 4fb99db0..7ae5dfd2 100644 --- a/src/main/java/lambdasinaction/chap13/Combinators.java +++ b/src/main/java/lambdasinaction/chap14/Combinators.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap13; +package lambdasinaction.chap14; import java.util.function.Function; diff --git a/src/main/java/lambdasinaction/chap13/Currying.java b/src/main/java/lambdasinaction/chap14/Currying.java similarity index 96% rename from src/main/java/lambdasinaction/chap13/Currying.java rename to src/main/java/lambdasinaction/chap14/Currying.java index d1fc3551..f17ac928 100644 --- a/src/main/java/lambdasinaction/chap13/Currying.java +++ b/src/main/java/lambdasinaction/chap14/Currying.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap13; +package lambdasinaction.chap14; import java.util.function.DoubleUnaryOperator; diff --git a/src/main/java/lambdasinaction/chap13/LazyLists.java b/src/main/java/lambdasinaction/chap14/LazyLists.java similarity index 99% rename from src/main/java/lambdasinaction/chap13/LazyLists.java rename to src/main/java/lambdasinaction/chap14/LazyLists.java index 43d73173..658e0940 100644 --- a/src/main/java/lambdasinaction/chap13/LazyLists.java +++ b/src/main/java/lambdasinaction/chap14/LazyLists.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap13; +package lambdasinaction.chap14; import java.util.function.Supplier; import java.util.function.Predicate; diff --git a/src/main/java/lambdasinaction/chap13/PatternMatching.java b/src/main/java/lambdasinaction/chap14/PatternMatching.java similarity index 99% rename from src/main/java/lambdasinaction/chap13/PatternMatching.java rename to src/main/java/lambdasinaction/chap14/PatternMatching.java index cf9af017..400593d4 100644 --- a/src/main/java/lambdasinaction/chap13/PatternMatching.java +++ b/src/main/java/lambdasinaction/chap14/PatternMatching.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap13; +package lambdasinaction.chap14; import java.util.function.Function; import java.util.function.Supplier; diff --git a/src/main/java/lambdasinaction/chap13/PersistentTrainJourney.java b/src/main/java/lambdasinaction/chap14/PersistentTrainJourney.java similarity index 98% rename from src/main/java/lambdasinaction/chap13/PersistentTrainJourney.java rename to src/main/java/lambdasinaction/chap14/PersistentTrainJourney.java index 8569f57f..7e958a14 100644 --- a/src/main/java/lambdasinaction/chap13/PersistentTrainJourney.java +++ b/src/main/java/lambdasinaction/chap14/PersistentTrainJourney.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap13; +package lambdasinaction.chap14; import java.util.function.Consumer; diff --git a/src/main/java/lambdasinaction/chap13/PersistentTree.java b/src/main/java/lambdasinaction/chap14/PersistentTree.java similarity index 98% rename from src/main/java/lambdasinaction/chap13/PersistentTree.java rename to src/main/java/lambdasinaction/chap14/PersistentTree.java index e6b88b70..562d4f69 100644 --- a/src/main/java/lambdasinaction/chap13/PersistentTree.java +++ b/src/main/java/lambdasinaction/chap14/PersistentTree.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap13; +package lambdasinaction.chap14; public class PersistentTree { diff --git a/src/main/java/lambdasinaction/chap4/Reducing.java b/src/main/java/lambdasinaction/chap4/Reducing.java deleted file mode 100644 index 6bfc514d..00000000 --- a/src/main/java/lambdasinaction/chap4/Reducing.java +++ /dev/null @@ -1,29 +0,0 @@ -package lambdasinaction.chap4; -import java.util.stream.*; -import java.util.*; - -import static lambdasinaction.chap4.Dish.menu; - -public class Reducing{ - - public static void main(String...args){ - - List numbers = Arrays.asList(3,4,5,1,2); - int sum = numbers.stream().reduce(0, (a, b) -> a + b); - System.out.println(sum); - - int sum2 = numbers.stream().reduce(0, Integer::sum); - System.out.println(sum2); - - int max = numbers.stream().reduce(0, (a, b) -> Integer.max(a, b)); - System.out.println(max); - - Optional min = numbers.stream().reduce(Integer::min); - min.ifPresent(System.out::println); - - int calories = menu.stream() - .map(Dish::getCalories) - .reduce(0, Integer::sum); - System.out.println("Number of calories:" + calories); - } -} diff --git a/src/main/java/lambdasinaction/chap4/StreamBasic.java b/src/main/java/lambdasinaction/chap4/StreamBasic.java index 9beea005..19a8c176 100644 --- a/src/main/java/lambdasinaction/chap4/StreamBasic.java +++ b/src/main/java/lambdasinaction/chap4/StreamBasic.java @@ -24,7 +24,7 @@ public static void main(String...args){ public static List getLowCaloricDishesNamesInJava7(List dishes){ List lowCaloricDishes = new ArrayList<>(); for(Dish d: dishes){ - if(d.getCalories() > 400){ + if(d.getCalories() < 400){ lowCaloricDishes.add(d); } } @@ -42,7 +42,7 @@ public int compare(Dish d1, Dish d2){ public static List getLowCaloricDishesNamesInJava8(List dishes){ return dishes.stream() - .filter(d -> d.getCalories() > 400) + .filter(d -> d.getCalories() < 400) .sorted(comparing(Dish::getCalories)) .map(Dish::getName) .collect(toList()); diff --git a/src/main/java/lambdasinaction/chap4/BuildingStreams.java b/src/main/java/lambdasinaction/chap5/BuildingStreams.java similarity index 95% rename from src/main/java/lambdasinaction/chap4/BuildingStreams.java rename to src/main/java/lambdasinaction/chap5/BuildingStreams.java index ecb2dcb3..15280a39 100644 --- a/src/main/java/lambdasinaction/chap4/BuildingStreams.java +++ b/src/main/java/lambdasinaction/chap5/BuildingStreams.java @@ -1,9 +1,8 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; import java.util.*; import java.util.function.IntSupplier; import java.util.stream.*; -import static java.util.stream.Collectors.toList; import java.nio.charset.Charset; import java.nio.file.*; @@ -67,7 +66,7 @@ public int getAsInt(){ }; IntStream.generate(fib).limit(10).forEach(System.out::println); - long uniqueWords = Files.lines(Paths.get("lambdasinaction/chap4/data.txt"), Charset.defaultCharset()) + long uniqueWords = Files.lines(Paths.get("lambdasinaction/chap5/data.txt"), Charset.defaultCharset()) .flatMap(line -> Arrays.stream(line.split(" "))) .distinct() .count(); diff --git a/src/main/java/lambdasinaction/chap5/Dish.java b/src/main/java/lambdasinaction/chap5/Dish.java deleted file mode 100644 index fab9f533..00000000 --- a/src/main/java/lambdasinaction/chap5/Dish.java +++ /dev/null @@ -1,52 +0,0 @@ -package lambdasinaction.chap5; - -import java.util.*; - -public class Dish { - - private final String name; - private final boolean vegetarian; - private final int calories; - private final Type type; - - public Dish(String name, boolean vegetarian, int calories, Type type) { - this.name = name; - this.vegetarian = vegetarian; - this.calories = calories; - this.type = type; - } - - public String getName() { - return name; - } - - public boolean isVegetarian() { - return vegetarian; - } - - public int getCalories() { - return calories; - } - - public Type getType() { - return type; - } - - public enum Type { MEAT, FISH, OTHER } - - @Override - public String toString() { - return name; - } - - 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)); -} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap4/Filtering.java b/src/main/java/lambdasinaction/chap5/Filtering.java similarity index 94% rename from src/main/java/lambdasinaction/chap4/Filtering.java rename to src/main/java/lambdasinaction/chap5/Filtering.java index adfc0d9c..066c8242 100644 --- a/src/main/java/lambdasinaction/chap4/Filtering.java +++ b/src/main/java/lambdasinaction/chap5/Filtering.java @@ -1,4 +1,6 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; +import lambdasinaction.chap4.*; + import java.util.stream.*; import java.util.*; import static java.util.stream.Collectors.toList; diff --git a/src/main/java/lambdasinaction/chap4/Finding.java b/src/main/java/lambdasinaction/chap5/Finding.java similarity index 94% rename from src/main/java/lambdasinaction/chap4/Finding.java rename to src/main/java/lambdasinaction/chap5/Finding.java index 9eade942..acccc543 100644 --- a/src/main/java/lambdasinaction/chap4/Finding.java +++ b/src/main/java/lambdasinaction/chap5/Finding.java @@ -1,4 +1,6 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; +import lambdasinaction.chap4.*; + import java.util.stream.*; import java.util.*; diff --git a/src/main/java/lambdasinaction/chap4/Laziness.java b/src/main/java/lambdasinaction/chap5/Laziness.java similarity index 96% rename from src/main/java/lambdasinaction/chap4/Laziness.java rename to src/main/java/lambdasinaction/chap5/Laziness.java index 60446895..a3df328a 100644 --- a/src/main/java/lambdasinaction/chap4/Laziness.java +++ b/src/main/java/lambdasinaction/chap5/Laziness.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/lambdasinaction/chap4/Mapping.java b/src/main/java/lambdasinaction/chap5/Mapping.java similarity index 95% rename from src/main/java/lambdasinaction/chap4/Mapping.java rename to src/main/java/lambdasinaction/chap5/Mapping.java index 9adf3c99..7bf4caba 100644 --- a/src/main/java/lambdasinaction/chap4/Mapping.java +++ b/src/main/java/lambdasinaction/chap5/Mapping.java @@ -1,4 +1,6 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; + +import lambdasinaction.chap4.*; import java.util.*; import static java.util.stream.Collectors.toList; diff --git a/src/main/java/lambdasinaction/chap4/NumericStreams.java b/src/main/java/lambdasinaction/chap5/NumericStreams.java similarity index 96% rename from src/main/java/lambdasinaction/chap4/NumericStreams.java rename to src/main/java/lambdasinaction/chap5/NumericStreams.java index 7822bf98..e5f8cca8 100644 --- a/src/main/java/lambdasinaction/chap4/NumericStreams.java +++ b/src/main/java/lambdasinaction/chap5/NumericStreams.java @@ -1,4 +1,6 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; +import lambdasinaction.chap4.*; + import java.util.stream.*; import java.util.*; diff --git a/src/main/java/lambdasinaction/chap4/PuttingIntoPractice.java b/src/main/java/lambdasinaction/chap5/PuttingIntoPractice.java similarity index 98% rename from src/main/java/lambdasinaction/chap4/PuttingIntoPractice.java rename to src/main/java/lambdasinaction/chap5/PuttingIntoPractice.java index ae47f9a5..d0b13ae5 100644 --- a/src/main/java/lambdasinaction/chap4/PuttingIntoPractice.java +++ b/src/main/java/lambdasinaction/chap5/PuttingIntoPractice.java @@ -1,7 +1,9 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; + +import lambdasinaction.chap5.*; import java.util.*; -import java.util.stream.*; + import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toList; diff --git a/src/main/java/lambdasinaction/chap5/Reducing.java b/src/main/java/lambdasinaction/chap5/Reducing.java index ae5d519e..93aed73e 100644 --- a/src/main/java/lambdasinaction/chap5/Reducing.java +++ b/src/main/java/lambdasinaction/chap5/Reducing.java @@ -1,34 +1,31 @@ package lambdasinaction.chap5; +import lambdasinaction.chap4.*; -import java.util.*; -import java.util.function.*; import java.util.stream.*; +import java.util.*; -import static java.util.stream.Collectors.*; -import static lambdasinaction.chap5.Dish.menu; +import static lambdasinaction.chap4.Dish.menu; -public class Reducing { +public class Reducing{ - public static void main(String ... args) { - System.out.println("Total calories in menu: " + calculateTotalCalories()); - System.out.println("Total calories in menu: " + calculateTotalCaloriesWithMethodReference()); - System.out.println("Total calories in menu: " + calculateTotalCaloriesWithoutCollectors()); - System.out.println("Total calories in menu: " + calculateTotalCaloriesUsingSum()); - } + public static void main(String...args){ - private static int calculateTotalCalories() { - return menu.stream().collect(reducing(0, Dish::getCalories, (Integer i, Integer j) -> i + j)); - } + List numbers = Arrays.asList(3,4,5,1,2); + int sum = numbers.stream().reduce(0, (a, b) -> a + b); + System.out.println(sum); - private static int calculateTotalCaloriesWithMethodReference() { - return menu.stream().collect(reducing(0, Dish::getCalories, Integer::sum)); - } + int sum2 = numbers.stream().reduce(0, Integer::sum); + System.out.println(sum2); - private static int calculateTotalCaloriesWithoutCollectors() { - return menu.stream().map(Dish::getCalories).reduce(Integer::sum).get(); - } + int max = numbers.stream().reduce(0, (a, b) -> Integer.max(a, b)); + System.out.println(max); + + Optional min = numbers.stream().reduce(Integer::min); + min.ifPresent(System.out::println); - private static int calculateTotalCaloriesUsingSum() { - return menu.stream().mapToInt(Dish::getCalories).sum(); + int calories = menu.stream() + .map(Dish::getCalories) + .reduce(0, Integer::sum); + System.out.println("Number of calories:" + calories); } -} \ No newline at end of file +} diff --git a/src/main/java/lambdasinaction/chap4/Trader.java b/src/main/java/lambdasinaction/chap5/Trader.java similarity index 92% rename from src/main/java/lambdasinaction/chap4/Trader.java rename to src/main/java/lambdasinaction/chap5/Trader.java index b8bb83c8..7487a8c6 100644 --- a/src/main/java/lambdasinaction/chap4/Trader.java +++ b/src/main/java/lambdasinaction/chap5/Trader.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; public class Trader{ private String name; diff --git a/src/main/java/lambdasinaction/chap4/Transaction.java b/src/main/java/lambdasinaction/chap5/Transaction.java similarity index 94% rename from src/main/java/lambdasinaction/chap4/Transaction.java rename to src/main/java/lambdasinaction/chap5/Transaction.java index 04da232b..754e3839 100644 --- a/src/main/java/lambdasinaction/chap4/Transaction.java +++ b/src/main/java/lambdasinaction/chap5/Transaction.java @@ -1,4 +1,5 @@ -package lambdasinaction.chap4; +package lambdasinaction.chap5; + public class Transaction{ private Trader trader; diff --git a/src/main/java/lambdasinaction/chap5/CollectorHarness.java b/src/main/java/lambdasinaction/chap6/CollectorHarness.java similarity index 89% rename from src/main/java/lambdasinaction/chap5/CollectorHarness.java rename to src/main/java/lambdasinaction/chap6/CollectorHarness.java index 3b46dab0..8370be16 100644 --- a/src/main/java/lambdasinaction/chap5/CollectorHarness.java +++ b/src/main/java/lambdasinaction/chap6/CollectorHarness.java @@ -1,9 +1,7 @@ -package lambdasinaction.chap5; +package lambdasinaction.chap6; import java.util.function.*; -import static lambdasinaction.chap5.PartitionPrimeNumbers.*; - public class CollectorHarness { public static void main(String[] args) { diff --git a/src/main/java/lambdasinaction/chap6/Dish.java b/src/main/java/lambdasinaction/chap6/Dish.java new file mode 100644 index 00000000..adba6e93 --- /dev/null +++ b/src/main/java/lambdasinaction/chap6/Dish.java @@ -0,0 +1,68 @@ +package lambdasinaction.chap6; + +import java.util.*; + +import static java.util.Arrays.asList; + +public class Dish { + + private final String name; + private final boolean vegetarian; + private final int calories; + private final Type type; + + public Dish(String name, boolean vegetarian, int calories, Type type) { + this.name = name; + this.vegetarian = vegetarian; + this.calories = calories; + this.type = type; + } + + public String getName() { + return name; + } + + public boolean isVegetarian() { + return vegetarian; + } + + public int getCalories() { + return calories; + } + + public Type getType() { + return type; + } + + public enum Type { MEAT, FISH, OTHER } + + @Override + public String toString() { + return name; + } + + public static final List menu = + 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/chap5/Grouping.java b/src/main/java/lambdasinaction/chap6/Grouping.java similarity index 75% rename from src/main/java/lambdasinaction/chap5/Grouping.java rename to src/main/java/lambdasinaction/chap6/Grouping.java index 9065d02f..9105cc80 100644 --- a/src/main/java/lambdasinaction/chap5/Grouping.java +++ b/src/main/java/lambdasinaction/chap6/Grouping.java @@ -1,11 +1,10 @@ -package lambdasinaction.chap5; +package lambdasinaction.chap6; import java.util.*; -import java.util.function.*; -import java.util.stream.*; import static java.util.stream.Collectors.*; -import static lambdasinaction.chap5.Dish.menu; +import static lambdasinaction.chap6.Dish.dishTags; +import static lambdasinaction.chap6.Dish.menu; public class Grouping { @@ -13,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()); @@ -26,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/chap5/GroupingTransactions.java b/src/main/java/lambdasinaction/chap6/GroupingTransactions.java similarity index 99% rename from src/main/java/lambdasinaction/chap5/GroupingTransactions.java rename to src/main/java/lambdasinaction/chap6/GroupingTransactions.java index db075913..ce358acb 100644 --- a/src/main/java/lambdasinaction/chap5/GroupingTransactions.java +++ b/src/main/java/lambdasinaction/chap6/GroupingTransactions.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap5; +package lambdasinaction.chap6; import java.util.*; diff --git a/src/main/java/lambdasinaction/chap5/PartitionPrimeNumbers.java b/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java similarity index 93% rename from src/main/java/lambdasinaction/chap5/PartitionPrimeNumbers.java rename to src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java index 26b07c70..69d7c4ca 100644 --- a/src/main/java/lambdasinaction/chap5/PartitionPrimeNumbers.java +++ b/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java @@ -1,11 +1,10 @@ -package lambdasinaction.chap5; +package lambdasinaction.chap6; import java.util.*; import java.util.function.*; import java.util.stream.*; import static java.util.stream.Collectors.*; -import static lambdasinaction.chap5.Dish.menu; import static java.util.stream.Collector.Characteristics.*; public class PartitionPrimeNumbers { @@ -33,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) { @@ -47,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/chap5/Partitioning.java b/src/main/java/lambdasinaction/chap6/Partitioning.java similarity index 89% rename from src/main/java/lambdasinaction/chap5/Partitioning.java rename to src/main/java/lambdasinaction/chap6/Partitioning.java index 4b491896..2ec8dc79 100644 --- a/src/main/java/lambdasinaction/chap5/Partitioning.java +++ b/src/main/java/lambdasinaction/chap6/Partitioning.java @@ -1,12 +1,10 @@ -package lambdasinaction.chap5; +package lambdasinaction.chap6; import java.util.*; -import java.util.function.*; -import java.util.stream.*; import static java.util.Comparator.comparingInt; import static java.util.stream.Collectors.*; -import static lambdasinaction.chap5.Dish.menu; +import static lambdasinaction.chap6.Dish.menu; public class Partitioning { diff --git a/src/main/java/lambdasinaction/chap6/Reducing.java b/src/main/java/lambdasinaction/chap6/Reducing.java new file mode 100644 index 00000000..fb7cf971 --- /dev/null +++ b/src/main/java/lambdasinaction/chap6/Reducing.java @@ -0,0 +1,30 @@ +package lambdasinaction.chap6; + +import static java.util.stream.Collectors.*; +import static lambdasinaction.chap6.Dish.menu; + +public class Reducing { + + public static void main(String ... args) { + System.out.println("Total calories in menu: " + calculateTotalCalories()); + System.out.println("Total calories in menu: " + calculateTotalCaloriesWithMethodReference()); + System.out.println("Total calories in menu: " + calculateTotalCaloriesWithoutCollectors()); + System.out.println("Total calories in menu: " + calculateTotalCaloriesUsingSum()); + } + + private static int calculateTotalCalories() { + return menu.stream().collect(reducing(0, Dish::getCalories, (Integer i, Integer j) -> i + j)); + } + + private static int calculateTotalCaloriesWithMethodReference() { + return menu.stream().collect(reducing(0, Dish::getCalories, Integer::sum)); + } + + private static int calculateTotalCaloriesWithoutCollectors() { + return menu.stream().map(Dish::getCalories).reduce(Integer::sum).get(); + } + + private static int calculateTotalCaloriesUsingSum() { + return menu.stream().mapToInt(Dish::getCalories).sum(); + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap5/Summarizing.java b/src/main/java/lambdasinaction/chap6/Summarizing.java similarity index 95% rename from src/main/java/lambdasinaction/chap5/Summarizing.java rename to src/main/java/lambdasinaction/chap6/Summarizing.java index 5e99b6cc..06f9af6d 100644 --- a/src/main/java/lambdasinaction/chap5/Summarizing.java +++ b/src/main/java/lambdasinaction/chap6/Summarizing.java @@ -1,11 +1,10 @@ -package lambdasinaction.chap5; +package lambdasinaction.chap6; import java.util.*; import java.util.function.*; -import java.util.stream.*; import static java.util.stream.Collectors.*; -import static lambdasinaction.chap5.Dish.menu; +import static lambdasinaction.chap6.Dish.menu; public class Summarizing { diff --git a/src/main/java/lambdasinaction/chap5/ToListCollector.java b/src/main/java/lambdasinaction/chap6/ToListCollector.java similarity index 96% rename from src/main/java/lambdasinaction/chap5/ToListCollector.java rename to src/main/java/lambdasinaction/chap6/ToListCollector.java index 19edcd6c..0621d96a 100644 --- a/src/main/java/lambdasinaction/chap5/ToListCollector.java +++ b/src/main/java/lambdasinaction/chap6/ToListCollector.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap5; +package lambdasinaction.chap6; import java.util.*; import java.util.function.*; diff --git a/src/main/java/lambdasinaction/chap6/ForkJoinSumCalculator.java b/src/main/java/lambdasinaction/chap7/ForkJoinSumCalculator.java similarity index 91% rename from src/main/java/lambdasinaction/chap6/ForkJoinSumCalculator.java rename to src/main/java/lambdasinaction/chap7/ForkJoinSumCalculator.java index 90a6e781..8f74a90a 100644 --- a/src/main/java/lambdasinaction/chap6/ForkJoinSumCalculator.java +++ b/src/main/java/lambdasinaction/chap7/ForkJoinSumCalculator.java @@ -1,11 +1,10 @@ -package lambdasinaction.chap6; +package lambdasinaction.chap7; import java.util.concurrent.RecursiveTask; -import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.stream.LongStream; -import static lambdasinaction.chap6.ParallelStreamsHarness.FORK_JOIN_POOL; +import static lambdasinaction.chap7.ParallelStreamsHarness.FORK_JOIN_POOL; public class ForkJoinSumCalculator extends RecursiveTask { 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(); + } +} diff --git a/src/main/java/lambdasinaction/chap6/ParallelStreams.java b/src/main/java/lambdasinaction/chap7/ParallelStreams.java similarity index 97% rename from src/main/java/lambdasinaction/chap6/ParallelStreams.java rename to src/main/java/lambdasinaction/chap7/ParallelStreams.java index 152e8919..e8b2a520 100644 --- a/src/main/java/lambdasinaction/chap6/ParallelStreams.java +++ b/src/main/java/lambdasinaction/chap7/ParallelStreams.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap6; +package lambdasinaction.chap7; import java.util.stream.*; diff --git a/src/main/java/lambdasinaction/chap6/ParallelStreamsHarness.java b/src/main/java/lambdasinaction/chap7/ParallelStreamsHarness.java similarity index 98% rename from src/main/java/lambdasinaction/chap6/ParallelStreamsHarness.java rename to src/main/java/lambdasinaction/chap7/ParallelStreamsHarness.java index 6a6c4fb6..7d53c86f 100644 --- a/src/main/java/lambdasinaction/chap6/ParallelStreamsHarness.java +++ b/src/main/java/lambdasinaction/chap7/ParallelStreamsHarness.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap6; +package lambdasinaction.chap7; import java.util.concurrent.*; import java.util.function.*; diff --git a/src/main/java/lambdasinaction/chap6/WordCount.java b/src/main/java/lambdasinaction/chap7/WordCount.java similarity index 99% rename from src/main/java/lambdasinaction/chap6/WordCount.java rename to src/main/java/lambdasinaction/chap7/WordCount.java index 762e0355..13ccce52 100644 --- a/src/main/java/lambdasinaction/chap6/WordCount.java +++ b/src/main/java/lambdasinaction/chap7/WordCount.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap6; +package lambdasinaction.chap7; import java.util.*; import java.util.function.*; diff --git a/src/main/java/lambdasinaction/chap7/ChainOfResponsibilityMain.java b/src/main/java/lambdasinaction/chap8/ChainOfResponsibilityMain.java similarity index 98% rename from src/main/java/lambdasinaction/chap7/ChainOfResponsibilityMain.java rename to src/main/java/lambdasinaction/chap8/ChainOfResponsibilityMain.java index 84ff8208..91d52e0a 100644 --- a/src/main/java/lambdasinaction/chap7/ChainOfResponsibilityMain.java +++ b/src/main/java/lambdasinaction/chap8/ChainOfResponsibilityMain.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap7; +package lambdasinaction.chap8; import java.util.function.Function; import java.util.function.UnaryOperator; diff --git a/src/main/java/lambdasinaction/chap7/Debugging.java b/src/main/java/lambdasinaction/chap8/Debugging.java similarity index 94% rename from src/main/java/lambdasinaction/chap7/Debugging.java rename to src/main/java/lambdasinaction/chap8/Debugging.java index 7677a2a8..40c4dd23 100644 --- a/src/main/java/lambdasinaction/chap7/Debugging.java +++ b/src/main/java/lambdasinaction/chap8/Debugging.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap7; +package lambdasinaction.chap8; import java.util.*; diff --git a/src/main/java/lambdasinaction/chap7/FactoryMain.java b/src/main/java/lambdasinaction/chap8/FactoryMain.java similarity index 96% rename from src/main/java/lambdasinaction/chap7/FactoryMain.java rename to src/main/java/lambdasinaction/chap8/FactoryMain.java index 83d69abc..e30d219e 100644 --- a/src/main/java/lambdasinaction/chap7/FactoryMain.java +++ b/src/main/java/lambdasinaction/chap8/FactoryMain.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap7; +package lambdasinaction.chap8; import java.util.HashMap; import java.util.Map; @@ -40,7 +40,7 @@ static private class Stock implements Product {} static private class Bond implements Product {} final static private Map> map = new HashMap<>(); - { + static { map.put("loan", Loan::new); map.put("stock", Stock::new); map.put("bond", Bond::new); diff --git a/src/main/java/lambdasinaction/chap7/ObserverMain.java b/src/main/java/lambdasinaction/chap8/ObserverMain.java similarity index 96% rename from src/main/java/lambdasinaction/chap7/ObserverMain.java rename to src/main/java/lambdasinaction/chap8/ObserverMain.java index 37291977..dcd8cb50 100644 --- a/src/main/java/lambdasinaction/chap7/ObserverMain.java +++ b/src/main/java/lambdasinaction/chap8/ObserverMain.java @@ -1,9 +1,7 @@ -package lambdasinaction.chap7; +package lambdasinaction.chap8; import java.util.ArrayList; import java.util.List; -import java.util.Observable; -import java.util.Observer; public class ObserverMain { diff --git a/src/main/java/lambdasinaction/chap7/OnlineBanking.java b/src/main/java/lambdasinaction/chap8/OnlineBanking.java similarity index 93% rename from src/main/java/lambdasinaction/chap7/OnlineBanking.java rename to src/main/java/lambdasinaction/chap8/OnlineBanking.java index 7e8b6930..27cbf917 100644 --- a/src/main/java/lambdasinaction/chap7/OnlineBanking.java +++ b/src/main/java/lambdasinaction/chap8/OnlineBanking.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap7; +package lambdasinaction.chap8; abstract class OnlineBanking { diff --git a/src/main/java/lambdasinaction/chap7/OnlineBankingLambda.java b/src/main/java/lambdasinaction/chap8/OnlineBankingLambda.java similarity index 95% rename from src/main/java/lambdasinaction/chap7/OnlineBankingLambda.java rename to src/main/java/lambdasinaction/chap8/OnlineBankingLambda.java index 235bf249..3bd9e049 100644 --- a/src/main/java/lambdasinaction/chap7/OnlineBankingLambda.java +++ b/src/main/java/lambdasinaction/chap8/OnlineBankingLambda.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap7; +package lambdasinaction.chap8; import java.util.function.Consumer; diff --git a/src/main/java/lambdasinaction/chap7/Peek.java b/src/main/java/lambdasinaction/chap8/Peek.java similarity index 94% rename from src/main/java/lambdasinaction/chap7/Peek.java rename to src/main/java/lambdasinaction/chap8/Peek.java index 1c0192ee..e25d68a4 100644 --- a/src/main/java/lambdasinaction/chap7/Peek.java +++ b/src/main/java/lambdasinaction/chap8/Peek.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap7; +package lambdasinaction.chap8; import java.util.List; import java.util.stream.Stream; diff --git a/src/main/java/lambdasinaction/chap7/StrategyMain.java b/src/main/java/lambdasinaction/chap8/StrategyMain.java similarity index 97% rename from src/main/java/lambdasinaction/chap7/StrategyMain.java rename to src/main/java/lambdasinaction/chap8/StrategyMain.java index d670b734..cc899aa8 100644 --- a/src/main/java/lambdasinaction/chap7/StrategyMain.java +++ b/src/main/java/lambdasinaction/chap8/StrategyMain.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap7; +package lambdasinaction.chap8; public class StrategyMain { diff --git a/src/main/java/lambdasinaction/chap8/Ambiguous.java b/src/main/java/lambdasinaction/chap9/Ambiguous.java similarity index 93% rename from src/main/java/lambdasinaction/chap8/Ambiguous.java rename to src/main/java/lambdasinaction/chap9/Ambiguous.java index 1c856e61..d007bedc 100644 --- a/src/main/java/lambdasinaction/chap8/Ambiguous.java +++ b/src/main/java/lambdasinaction/chap9/Ambiguous.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; public class Ambiguous{ diff --git a/src/main/java/lambdasinaction/chap8/Diamond.java b/src/main/java/lambdasinaction/chap9/Diamond.java similarity index 91% rename from src/main/java/lambdasinaction/chap8/Diamond.java rename to src/main/java/lambdasinaction/chap9/Diamond.java index a02a8621..f0226e1d 100644 --- a/src/main/java/lambdasinaction/chap8/Diamond.java +++ b/src/main/java/lambdasinaction/chap9/Diamond.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; public class Diamond{ diff --git a/src/main/java/lambdasinaction/chap8/Drawable.java b/src/main/java/lambdasinaction/chap9/Drawable.java similarity index 77% rename from src/main/java/lambdasinaction/chap8/Drawable.java rename to src/main/java/lambdasinaction/chap9/Drawable.java index 981b5575..731a8772 100644 --- a/src/main/java/lambdasinaction/chap8/Drawable.java +++ b/src/main/java/lambdasinaction/chap9/Drawable.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; /** * Created by raoul-gabrielurma on 15/01/2014. diff --git a/src/main/java/lambdasinaction/chap8/Ellipse.java b/src/main/java/lambdasinaction/chap9/Ellipse.java similarity index 93% rename from src/main/java/lambdasinaction/chap8/Ellipse.java rename to src/main/java/lambdasinaction/chap9/Ellipse.java index 1912558f..8f2d1ae0 100644 --- a/src/main/java/lambdasinaction/chap8/Ellipse.java +++ b/src/main/java/lambdasinaction/chap9/Ellipse.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; /** * Created by raoul-gabrielurma on 15/01/2014. diff --git a/src/main/java/lambdasinaction/chap8/Game.java b/src/main/java/lambdasinaction/chap9/Game.java similarity index 90% rename from src/main/java/lambdasinaction/chap8/Game.java rename to src/main/java/lambdasinaction/chap9/Game.java index 917626e7..0836f46c 100644 --- a/src/main/java/lambdasinaction/chap8/Game.java +++ b/src/main/java/lambdasinaction/chap9/Game.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; import java.util.Arrays; diff --git a/src/main/java/lambdasinaction/chap8/Intro.java b/src/main/java/lambdasinaction/chap9/Intro.java similarity index 92% rename from src/main/java/lambdasinaction/chap8/Intro.java rename to src/main/java/lambdasinaction/chap9/Intro.java index 09b010d7..d540a705 100644 --- a/src/main/java/lambdasinaction/chap8/Intro.java +++ b/src/main/java/lambdasinaction/chap9/Intro.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; import java.util.Arrays; import java.util.Comparator; diff --git a/src/main/java/lambdasinaction/chap8/Letter.java b/src/main/java/lambdasinaction/chap9/Letter.java similarity index 95% rename from src/main/java/lambdasinaction/chap8/Letter.java rename to src/main/java/lambdasinaction/chap9/Letter.java index cea01ccb..2ff65193 100644 --- a/src/main/java/lambdasinaction/chap8/Letter.java +++ b/src/main/java/lambdasinaction/chap9/Letter.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; import java.util.function.Function; diff --git a/src/main/java/lambdasinaction/chap8/MostSpecific.java b/src/main/java/lambdasinaction/chap9/MostSpecific.java similarity index 95% rename from src/main/java/lambdasinaction/chap8/MostSpecific.java rename to src/main/java/lambdasinaction/chap9/MostSpecific.java index c9198235..2a845e72 100644 --- a/src/main/java/lambdasinaction/chap8/MostSpecific.java +++ b/src/main/java/lambdasinaction/chap9/MostSpecific.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; public class MostSpecific{ diff --git a/src/main/java/lambdasinaction/chap9/OptionalMain.java b/src/main/java/lambdasinaction/chap9/OptionalMain.java deleted file mode 100644 index 1db2ab03..00000000 --- a/src/main/java/lambdasinaction/chap9/OptionalMain.java +++ /dev/null @@ -1,13 +0,0 @@ -package lambdasinaction.chap9; - -import java.util.*; - -public class OptionalMain { - - public String getCarInsuranceName(Optional person) { - return person.flatMap(Person::getCar) - .flatMap(Car::getInsurance) - .map(Insurance::getName) - .orElse("Unknown"); - } -} diff --git a/src/main/java/lambdasinaction/chap8/README b/src/main/java/lambdasinaction/chap9/README similarity index 100% rename from src/main/java/lambdasinaction/chap8/README rename to src/main/java/lambdasinaction/chap9/README diff --git a/src/main/java/lambdasinaction/chap8/Resizable.java b/src/main/java/lambdasinaction/chap9/Resizable.java similarity index 92% rename from src/main/java/lambdasinaction/chap8/Resizable.java rename to src/main/java/lambdasinaction/chap9/Resizable.java index 450ba4d5..c197b2bb 100644 --- a/src/main/java/lambdasinaction/chap8/Resizable.java +++ b/src/main/java/lambdasinaction/chap9/Resizable.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; public interface Resizable extends Drawable{ public int getWidth(); diff --git a/src/main/java/lambdasinaction/chap8/Square.java b/src/main/java/lambdasinaction/chap9/Square.java similarity index 93% rename from src/main/java/lambdasinaction/chap8/Square.java rename to src/main/java/lambdasinaction/chap9/Square.java index b77c439e..11c2397f 100644 --- a/src/main/java/lambdasinaction/chap8/Square.java +++ b/src/main/java/lambdasinaction/chap9/Square.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; /** * Created by raoul-gabrielurma on 15/01/2014. diff --git a/src/main/java/lambdasinaction/chap8/Triangle.java b/src/main/java/lambdasinaction/chap9/Triangle.java similarity index 93% rename from src/main/java/lambdasinaction/chap8/Triangle.java rename to src/main/java/lambdasinaction/chap9/Triangle.java index 03cbab22..ab98fa72 100644 --- a/src/main/java/lambdasinaction/chap8/Triangle.java +++ b/src/main/java/lambdasinaction/chap9/Triangle.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; /** * Created by raoul-gabrielurma on 15/01/2014. diff --git a/src/main/java/lambdasinaction/chap8/Utils.java b/src/main/java/lambdasinaction/chap9/Utils.java similarity index 89% rename from src/main/java/lambdasinaction/chap8/Utils.java rename to src/main/java/lambdasinaction/chap9/Utils.java index 2967e703..9e2af4bd 100644 --- a/src/main/java/lambdasinaction/chap8/Utils.java +++ b/src/main/java/lambdasinaction/chap9/Utils.java @@ -1,4 +1,4 @@ -package lambdasinaction.chap8; +package lambdasinaction.chap9; import java.util.List; diff --git a/src/main/java/lambdasinaction/dsl/Grouping.java b/src/main/java/lambdasinaction/dsl/Grouping.java new file mode 100644 index 00000000..b1472cf0 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/Grouping.java @@ -0,0 +1,79 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl; + +import lambdasinaction.chap6.Dish; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collector; + +import static java.util.stream.Collectors.groupingBy; +import static lambdasinaction.chap6.Dish.menu; +import static lambdasinaction.dsl.Grouping.GroupingBuilder.groupOn; + +public class Grouping { + + enum CaloricLevel { DIET, NORMAL, FAT }; + + public static void main(String ... args) { + System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel2()); + System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel3()); + } + + private static CaloricLevel getCaloricLevel( Dish dish ) { + if (dish.getCalories() <= 400) return CaloricLevel.DIET; + else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; + else return CaloricLevel.FAT; + } + + private static Map>> groupDishedByTypeAndCaloricLevel2() { + return menu.stream().collect( + twoLevelGroupingBy(Dish::getType, dish -> getCaloricLevel( dish ) ) + ); + } + + public static Collector>>> twoLevelGroupingBy(Function f1, Function f2) { + return groupingBy(f1, groupingBy(f2)); + } + + private static Map>> groupDishedByTypeAndCaloricLevel3() { + Collector>>> c = groupOn( ( Dish dish ) -> getCaloricLevel( dish ) ).after( Dish::getType ).get(); + return menu.stream().collect( c ); + } + + public static class GroupingBuilder { + private final Collector> collector; + + public GroupingBuilder( Collector> collector ) { + this.collector = collector; + } + + public Collector> get() { + return collector; + } + + public GroupingBuilder, J> after(Function classifier) { + return new GroupingBuilder<>( groupingBy( classifier, collector ) ); + } + + public static GroupingBuilder, K> groupOn(Function classifier) { + return new GroupingBuilder<>( groupingBy( classifier ) ); + } + } +} diff --git a/src/main/java/lambdasinaction/dsl/LambdaOrderBuilder.java b/src/main/java/lambdasinaction/dsl/LambdaOrderBuilder.java new file mode 100644 index 00000000..6746c3b1 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/LambdaOrderBuilder.java @@ -0,0 +1,83 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl; + +import lambdasinaction.dsl.model.Order; +import lambdasinaction.dsl.model.Stock; +import lambdasinaction.dsl.model.Trade; + +import java.util.function.Consumer; + +public class LambdaOrderBuilder { + + private Order order = new Order(); + + public static Order order(Consumer consumer) { + LambdaOrderBuilder builder = new LambdaOrderBuilder(); + consumer.accept( builder ); + return builder.order; + } + + public void forCustomer(String customer) { + order.setCustomer( customer ); + } + + public void buy(Consumer consumer) { + trade( consumer, Trade.Type.BUY ); + } + + public void sell(Consumer consumer) { + trade( consumer, Trade.Type.SELL ); + } + + private void trade( Consumer consumer, Trade.Type type ) { + TradeBuilder builder = new TradeBuilder(); + builder.trade.setType( type ); + consumer.accept( builder ); + order.addTrade( builder.trade ); + } + + public static class TradeBuilder { + private Trade trade = new Trade(); + + public void quantity(int quantity) { + trade.setQuantity( quantity ); + } + + public void price(double price) { + trade.setPrice( price ); + } + + public void stock(Consumer consumer) { + StockBuilder builder = new StockBuilder(); + consumer.accept( builder ); + trade.setStock( builder.stock ); + } + } + + public static class StockBuilder { + private Stock stock = new Stock(); + + public void symbol(String symbol) { + stock.setSymbol( symbol ); + } + + public void market(String market) { + stock.setMarket( market ); + } + } +} diff --git a/src/main/java/lambdasinaction/dsl/Main.java b/src/main/java/lambdasinaction/dsl/Main.java new file mode 100644 index 00000000..b50683e5 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/Main.java @@ -0,0 +1,98 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl; + +import lambdasinaction.dsl.model.Order; +import lambdasinaction.dsl.model.Stock; +import lambdasinaction.dsl.model.Trade; + +import static lambdasinaction.dsl.MethodChainingOrderBuilder.forCustomer; +import static lambdasinaction.dsl.NestedFunctionOrderBuilder.*; + +public class Main { + + public void plain() { + Order order = new Order(); + order.setCustomer( "BigBank" ); + + Trade trade1 = new Trade(); + trade1.setType( Trade.Type.BUY ); + + Stock stock1 = new Stock(); + stock1.setSymbol( "IBM" ); + stock1.setMarket( "NYSE" ); + + trade1.setStock( stock1 ); + trade1.setPrice( 125.00 ); + trade1.setQuantity( 80 ); + order.addTrade( trade1 ); + + Trade trade2 = new Trade(); + trade2.setType( Trade.Type.BUY ); + + Stock stock2 = new Stock(); + stock2.setSymbol( "GOOGLE" ); + stock2.setMarket( "NASDAQ" ); + + trade2.setStock( stock2 ); + trade2.setPrice( 375.00 ); + trade2.setQuantity( 50 ); + order.addTrade( trade2 ); + } + + public void methodChaining() { + Order order = forCustomer( "BigBank" ) + .buy( 80 ).stock( "IBM" ).on( "NYSE" ).at( 125.00 ) + .sell( 50 ).stock( "GOOGLE" ).on( "NASDAQ" ).at( 375.00 ) + .end(); + + } + + public void nestedFunction() { + Order order = order("BigBank", + buy(80, + stock( "IBM", on( "NYSE" ) ), + at(125.00)), + sell(50, + stock("GOOGLE", on("NASDAQ")), + at(375.00)) + ); + } + + public void lambda() { + Order order = LambdaOrderBuilder.order( o -> { + o.forCustomer( "BigBank" ); + o.buy( t -> { + t.quantity( 80 ); + t.price( 125.00 ); + t.stock( s -> { + s.symbol( "IBM" ); + s.market( "NYSE" ); + } ); + }); + o.sell( t -> { + t.quantity( 50 ); + t.price( 375.00 ); + t.stock( s -> { + s.symbol( "GOOGLE" ); + s.market( "NASDAQ" ); + } ); + }); + } ); + } + +} diff --git a/src/main/java/lambdasinaction/dsl/MethodChainingOrderBuilder.java b/src/main/java/lambdasinaction/dsl/MethodChainingOrderBuilder.java new file mode 100644 index 00000000..7d771ec5 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/MethodChainingOrderBuilder.java @@ -0,0 +1,99 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl; + +import lambdasinaction.dsl.model.Order; +import lambdasinaction.dsl.model.Stock; +import lambdasinaction.dsl.model.Trade; + +public class MethodChainingOrderBuilder { + + public final Order order = new Order(); + + private MethodChainingOrderBuilder(String customer) { + order.setCustomer( customer ); + } + + public static MethodChainingOrderBuilder forCustomer( String customer ) { + return new MethodChainingOrderBuilder(customer); + } + + public Order end() { + return order; + } + + public TradeBuilder buy(int quantity) { + return new TradeBuilder( this, Trade.Type.BUY, quantity ); + } + + public TradeBuilder sell(int quantity) { + return new TradeBuilder( this, Trade.Type.SELL, quantity ); + } + + private MethodChainingOrderBuilder addTrade(Trade trade) { + order.addTrade( trade ); + return this; + } + + public static class TradeBuilder { + private final MethodChainingOrderBuilder builder; + public final Trade trade = new Trade(); + + private TradeBuilder(MethodChainingOrderBuilder builder, Trade.Type type, int quantity) { + this.builder = builder; + trade.setType( type ); + trade.setQuantity( quantity ); + } + + public StockBuilder stock(String symbol) { + return new StockBuilder( builder, trade, symbol ); + } + } + + public static class TradeBuilderWithStock { + private final MethodChainingOrderBuilder builder; + private final Trade trade; + + public TradeBuilderWithStock( MethodChainingOrderBuilder builder, Trade trade ) { + this.builder = builder; + this.trade = trade; + } + + public MethodChainingOrderBuilder at(double price) { + trade.setPrice( price ); + return builder.addTrade( trade ); + } + } + + public static class StockBuilder { + private final MethodChainingOrderBuilder builder; + private final Trade trade; + private final Stock stock = new Stock(); + + private StockBuilder(MethodChainingOrderBuilder builder, Trade trade, String symbol) { + this.builder = builder; + this.trade = trade; + stock.setSymbol( symbol ); + } + + public TradeBuilderWithStock on(String market) { + stock.setMarket( market ); + trade.setStock( stock ); + return new TradeBuilderWithStock( builder, trade ); + } + } +} diff --git a/src/main/java/lambdasinaction/dsl/Mixed.java b/src/main/java/lambdasinaction/dsl/Mixed.java new file mode 100644 index 00000000..132dd998 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/Mixed.java @@ -0,0 +1,39 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl; + +import lambdasinaction.dsl.model.Order; + +import static lambdasinaction.dsl.MixedBuilder.buy; +import static lambdasinaction.dsl.MixedBuilder.sell; +import static lambdasinaction.dsl.MixedBuilder.forCustomer; + +public class Mixed { + public void mixed() { + Order order = + forCustomer( "BigBank", + buy( t -> t.quantity( 80 ) + .stock( "IBM" ) + .on( "NYSE" ) + .at( 125.00 )), + sell( t -> t.quantity( 50 ) + .stock( "GOOGLE" ) + .on( "NASDAQ" ) + .at( 125.00 )) ); + + } +} diff --git a/src/main/java/lambdasinaction/dsl/MixedBuilder.java b/src/main/java/lambdasinaction/dsl/MixedBuilder.java new file mode 100644 index 00000000..98d7ea97 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/MixedBuilder.java @@ -0,0 +1,85 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl; + +import lambdasinaction.dsl.model.Order; +import lambdasinaction.dsl.model.Stock; +import lambdasinaction.dsl.model.Trade; + +import java.util.function.Consumer; +import java.util.stream.Stream; + +public class MixedBuilder { + + public static Order forCustomer(String customer, TradeBuilder... builders) { + Order order = new Order(); + order.setCustomer( customer ); + Stream.of(builders).forEach( b -> order.addTrade( b.trade ) ); + return order; + } + + public static TradeBuilder buy(Consumer consumer) { + return buildTrade( consumer, Trade.Type.BUY ); + } + + public static TradeBuilder sell(Consumer consumer) { + return buildTrade( consumer, Trade.Type.SELL ); + } + + private static TradeBuilder buildTrade( Consumer consumer, Trade.Type buy ) { + TradeBuilder builder = new TradeBuilder(); + builder.trade.setType( buy ); + consumer.accept( builder ); + return builder; + } + + public static class TradeBuilder { + private Trade trade = new Trade(); + + public TradeBuilder quantity(int quantity) { + trade.setQuantity( quantity ); + return this; + } + + public TradeBuilder at(double price) { + trade.setPrice( price ); + return this; + } + + public StockBuilder stock(String symbol) { + return new StockBuilder(this, trade, symbol); + } + } + + public static class StockBuilder { + private final TradeBuilder builder; + private final Trade trade; + private final Stock stock = new Stock(); + + private StockBuilder(TradeBuilder builder, Trade trade, String symbol) { + this.builder = builder; + this.trade = trade; + stock.setSymbol( symbol ); + } + + public TradeBuilder on(String market) { + stock.setMarket( market ); + trade.setStock( stock ); + return builder; + } + } +} diff --git a/src/main/java/lambdasinaction/dsl/NestedFunctionOrderBuilder.java b/src/main/java/lambdasinaction/dsl/NestedFunctionOrderBuilder.java new file mode 100644 index 00000000..b9daaac9 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/NestedFunctionOrderBuilder.java @@ -0,0 +1,64 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl; + +import lambdasinaction.dsl.model.Order; +import lambdasinaction.dsl.model.Stock; +import lambdasinaction.dsl.model.Trade; + +import java.util.stream.Stream; + +public class NestedFunctionOrderBuilder { + + public static Order order(String customer, Trade... trades) { + Order order = new Order(); + order.setCustomer( customer ); + Stream.of(trades).forEach( order::addTrade ); + return order; + } + + public static Trade buy(int quantity, Stock stock, double price) { + return buildTrade( stock, price, Trade.Type.BUY ); + } + + public static Trade sell(int quantity, Stock stock, double price) { + return buildTrade( stock, price, Trade.Type.SELL ); + } + + private static Trade buildTrade( Stock stock, double price, Trade.Type buy ) { + Trade trade = new Trade(); + trade.setType( buy ); + trade.setStock( stock ); + trade.setPrice( price ); + return trade; + } + + public static double at(double price) { + return price; + } + + public static Stock stock(String symbol, String market) { + Stock stock = new Stock(); + stock.setSymbol( symbol ); + stock.setMarket( market ); + return stock; + } + + public static String on(String market) { + return market; + } +} diff --git a/src/main/java/lambdasinaction/dsl/TaxCalculator.java b/src/main/java/lambdasinaction/dsl/TaxCalculator.java new file mode 100644 index 00000000..9ef38cef --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/TaxCalculator.java @@ -0,0 +1,81 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl; + +import lambdasinaction.dsl.model.Order; +import lambdasinaction.dsl.model.Tax; + +import java.util.function.Function; + +public class TaxCalculator { + + public static double calculate( Order order, boolean useRegional, boolean useGeneral, boolean useSurcharge ) { + double value = order.getValue(); + if (useRegional) value = Tax.regional(value); + if (useGeneral) value = Tax.general(value); + if (useSurcharge) value = Tax.surcharge(value); + return value; + } + + private boolean useRegional; + private boolean useGeneral; + private boolean useSurcharge; + + public TaxCalculator withTaxRegional() { + useRegional = true; + return this; + } + + public TaxCalculator withTaxGeneral() { + useGeneral= true; + return this; + } + + public TaxCalculator withTaxSurcharge() { + useSurcharge = true; + return this; + } + + public double calculate(Order order) { + return calculate( order, useRegional, useGeneral, useSurcharge ); + } + + public Function taxFuncion = Function.identity(); + + public TaxCalculator with(Function f) { + taxFuncion.andThen( f ); + return this; + } + + public double calculateF(Order order) { + return taxFuncion.apply( order.getValue() ); + } + + public static void main(String[] args) { + Order order = new Order(); + + double value = TaxCalculator.calculate( order, true, false, true ); + + value = new TaxCalculator().withTaxRegional() + .withTaxSurcharge() + .calculate( order ); + + value = new TaxCalculator().with(Tax::regional) + .with(Tax::surcharge) + .calculate( order ); + } +} diff --git a/src/main/java/lambdasinaction/dsl/model/Order.java b/src/main/java/lambdasinaction/dsl/model/Order.java new file mode 100644 index 00000000..21c06747 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/model/Order.java @@ -0,0 +1,43 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl.model; + +import java.util.ArrayList; +import java.util.List; + +public class Order { + + private String customer; + + private List trades = new ArrayList<>(); + + public void addTrade( Trade trade ) { + trades.add( trade ); + } + + public String getCustomer() { + return customer; + } + + public void setCustomer( String customer ) { + this.customer = customer; + } + + public double getValue() { + return trades.stream().mapToDouble( Trade::getValue ).sum(); + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/dsl/model/Stock.java b/src/main/java/lambdasinaction/dsl/model/Stock.java new file mode 100644 index 00000000..1e0302e2 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/model/Stock.java @@ -0,0 +1,40 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl.model; + +public class Stock { + + private String symbol; + + private String market; + + public String getSymbol() { + return symbol; + } + + public void setSymbol( String symbol ) { + this.symbol = symbol; + } + + public String getMarket() { + return market; + } + + public void setMarket( String market ) { + this.market = market; + } +} diff --git a/src/main/java/lambdasinaction/dsl/model/Tax.java b/src/main/java/lambdasinaction/dsl/model/Tax.java new file mode 100644 index 00000000..d2d6bf22 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/model/Tax.java @@ -0,0 +1,31 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl.model; + +public class Tax { + public static double regional(double value) { + return value * 1.1; + } + + public static double general(double value) { + return value * 1.3; + } + + public static double surcharge(double value) { + return value * 1.05; + } +} diff --git a/src/main/java/lambdasinaction/dsl/model/Trade.java b/src/main/java/lambdasinaction/dsl/model/Trade.java new file mode 100644 index 00000000..c8f35813 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/model/Trade.java @@ -0,0 +1,66 @@ +/* + * Copyright 2005 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lambdasinaction.dsl.model; + +public class Trade { + + public enum Type { BUY, SELL } + + private Type type; + + private Stock stock; + + private int quantity; + + private double price; + + public Type getType() { + return type; + } + + public void setType( Type type ) { + this.type = type; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity( int quantity ) { + this.quantity = quantity; + } + + public double getPrice() { + return price; + } + + public void setPrice( double price ) { + this.price = price; + } + + public Stock getStock() { + return stock; + } + + public void setStock( Stock stock ) { + this.stock = stock; + } + + public double getValue() { + return quantity * price; + } +} diff --git a/src/main/resources/lambdasinaction/chap4/data.txt b/src/main/resources/lambdasinaction/chap5/data.txt similarity index 100% rename from src/main/resources/lambdasinaction/chap4/data.txt rename to src/main/resources/lambdasinaction/chap5/data.txt