├── .gitignore ├── src ├── main │ ├── java │ │ └── com │ │ │ └── insightfullogic │ │ │ └── java8 │ │ │ ├── examples │ │ │ ├── chapter9 │ │ │ │ ├── Credentials.java │ │ │ │ ├── AlbumLookup.java │ │ │ │ ├── AlbumLookupException.java │ │ │ │ ├── RxExamples.java │ │ │ │ └── FutureAlbumLookup.java │ │ │ ├── chapter5 │ │ │ │ ├── mutable_custom │ │ │ │ │ ├── Customer.java │ │ │ │ │ ├── CollectorExpansions.java │ │ │ │ │ ├── AlbumSalesReport.java │ │ │ │ │ ├── AlbumSale.java │ │ │ │ │ └── AlbumSalesCollector.java │ │ │ │ ├── MethodReferences.java │ │ │ │ ├── StringCombiner.java │ │ │ │ ├── StringCollector.java │ │ │ │ └── Niceties.java │ │ │ ├── chapter4 │ │ │ │ ├── ChildImpl.java │ │ │ │ ├── Rockable.java │ │ │ │ ├── OverridingChild.java │ │ │ │ ├── Carriage.java │ │ │ │ ├── Jukebox.java │ │ │ │ ├── Child.java │ │ │ │ ├── OverridingParent.java │ │ │ │ ├── MusicalCarriage.java │ │ │ │ ├── Parent.java │ │ │ │ ├── ParentImpl.java │ │ │ │ ├── Order.java │ │ │ │ ├── Primitives.java │ │ │ │ ├── OrderStreams.java │ │ │ │ ├── OrderDomain.java │ │ │ │ ├── OrderImperative.java │ │ │ │ └── Logger.java │ │ │ ├── chapter8 │ │ │ │ ├── template_method │ │ │ │ │ ├── ApplicationDenied.java │ │ │ │ │ ├── lambdas │ │ │ │ │ │ ├── Criteria.java │ │ │ │ │ │ ├── CompanyLoanApplication.java │ │ │ │ │ │ ├── Company.java │ │ │ │ │ │ └── LoanApplication.java │ │ │ │ │ ├── traditional │ │ │ │ │ │ ├── EmployeeLoanApplication.java │ │ │ │ │ │ ├── CompanyLoanApplication.java │ │ │ │ │ │ ├── PersonalLoanApplication.java │ │ │ │ │ │ └── LoanApplication.java │ │ │ │ │ └── Company.java │ │ │ │ ├── command │ │ │ │ │ ├── Action.java │ │ │ │ │ ├── Editor.java │ │ │ │ │ ├── Close.java │ │ │ │ │ ├── Open.java │ │ │ │ │ ├── Save.java │ │ │ │ │ └── Macro.java │ │ │ │ ├── HeadingLookupException.java │ │ │ │ ├── observer │ │ │ │ │ ├── LandingObserver.java │ │ │ │ │ ├── Nasa.java │ │ │ │ │ ├── Aliens.java │ │ │ │ │ └── Moon.java │ │ │ │ ├── strategy │ │ │ │ │ ├── CompressionStrategy.java │ │ │ │ │ ├── ZipCompressionStrategy.java │ │ │ │ │ ├── GzipCompressionStrategy.java │ │ │ │ │ └── Compressor.java │ │ │ │ ├── OpenClosedPrinciple.java │ │ │ │ ├── DependencyInversionPrinciple.java │ │ │ │ └── SingleResponsibilityPrinciple.java │ │ │ ├── chapter2 │ │ │ │ ├── ArrayExample.java │ │ │ │ └── CaptureCompileError.java │ │ │ ├── chapter6 │ │ │ │ ├── MovingAverage.java │ │ │ │ ├── ArrayExamples.java │ │ │ │ ├── ArraySum.java │ │ │ │ ├── DiceRolls.java │ │ │ │ ├── WordCounting.java │ │ │ │ └── ManualDiceRolls.java │ │ │ ├── chapter3 │ │ │ │ ├── Functional.java │ │ │ │ ├── GeneratingStreams.java │ │ │ │ ├── StreamExercises.java │ │ │ │ ├── Decisions.java │ │ │ │ └── Iteration.java │ │ │ └── chapter1 │ │ │ │ ├── Performance.java │ │ │ │ ├── MusicChapter.java │ │ │ │ ├── Track.java │ │ │ │ ├── Chapter1.java │ │ │ │ ├── SampleData.java │ │ │ │ ├── Artist.java │ │ │ │ └── Album.java │ │ │ ├── answers │ │ │ ├── chapter9 │ │ │ │ ├── package-info.java │ │ │ │ ├── ArtistAnalyzer.java │ │ │ │ ├── BlockingArtistAnalyzer.java │ │ │ │ ├── CallbackArtistAnalyser.java │ │ │ │ └── CompletableFutureArtistAnalyser.java │ │ │ ├── chapter5 │ │ │ │ ├── package-info.java │ │ │ │ ├── WordCount.java │ │ │ │ ├── Fibonacci.java │ │ │ │ ├── LongestName.java │ │ │ │ └── GroupingBy.java │ │ │ ├── chapter6 │ │ │ │ ├── package-info.java │ │ │ │ ├── SerialToParallel.java │ │ │ │ ├── BuggyReduce.java │ │ │ │ ├── OptimisationExample.java │ │ │ │ └── OptimisationExampleFixed.java │ │ │ ├── chapter4 │ │ │ │ ├── package-info.java │ │ │ │ ├── Performance.java │ │ │ │ ├── PerformanceFixed.java │ │ │ │ └── ArtistsFixed.java │ │ │ ├── chapter2 │ │ │ │ ├── Question2.java │ │ │ │ └── package-info.java │ │ │ └── chapter3 │ │ │ │ ├── package-info.java │ │ │ │ ├── Question2.java │ │ │ │ ├── StringExercises.java │ │ │ │ ├── Question1.java │ │ │ │ ├── MapUsingReduce.java │ │ │ │ └── FilterUsingReduce.java │ │ │ └── exercises │ │ │ ├── chapter9 │ │ │ ├── package-info.java │ │ │ ├── ArtistAnalyzer.java │ │ │ ├── BlockingArtistAnalyzer.java │ │ │ ├── CallbackArtistAnalyser.java │ │ │ └── CompletableFutureArtistAnalyser.java │ │ │ ├── Exercises.java │ │ │ ├── chapter5 │ │ │ ├── package-info.java │ │ │ ├── Fibonacci.java │ │ │ ├── WordCount.java │ │ │ ├── LongestName.java │ │ │ └── GroupingBy.java │ │ │ ├── chapter6 │ │ │ ├── package-info.java │ │ │ ├── BuggyReduce.java │ │ │ ├── SerialToParallel.java │ │ │ └── OptimisationExample.java │ │ │ ├── chapter4 │ │ │ ├── package-info.java │ │ │ ├── Performance.java │ │ │ ├── PerformanceFixed.java │ │ │ └── Artists.java │ │ │ ├── ExerciseNotCompletedException.java │ │ │ ├── chapter2 │ │ │ ├── Question2.java │ │ │ └── package-info.java │ │ │ └── chapter3 │ │ │ ├── Question2.java │ │ │ ├── package-info.java │ │ │ ├── MapUsingReduce.java │ │ │ ├── FilterUsingReduce.java │ │ │ ├── StringExercises.java │ │ │ └── Question1.java │ └── resources │ │ └── com │ │ └── insightfullogic │ │ └── java8 │ │ └── examples │ │ └── chapter02 │ │ └── Function.png └── test │ ├── java │ └── com │ │ └── insightfullogic │ │ └── java8 │ │ ├── examples │ │ ├── chapter8 │ │ │ ├── lambdabehave │ │ │ │ ├── reporting │ │ │ │ │ ├── Result.java │ │ │ │ │ ├── ReportFormatter.java │ │ │ │ │ ├── SuiteReport.java │ │ │ │ │ ├── SpecificationReport.java │ │ │ │ │ ├── ConsoleFormatter.java │ │ │ │ │ └── Report.java │ │ │ │ ├── Suite.java │ │ │ │ ├── Specification.java │ │ │ │ ├── Lets.java │ │ │ │ ├── expectations │ │ │ │ │ ├── BoundExpectation.java │ │ │ │ │ ├── Expect.java │ │ │ │ │ └── CollectionExpectation.java │ │ │ │ ├── Description.java │ │ │ │ ├── example │ │ │ │ │ └── StackSpec.java │ │ │ │ └── Runner.java │ │ │ ├── template_method │ │ │ │ └── TraditionalTest.java │ │ │ ├── command │ │ │ │ ├── MockEditor.java │ │ │ │ └── MacrosTest.java │ │ │ ├── DependencyInversionPrincipleTest.java │ │ │ └── SingleResponsibilityPrincipleTest.java │ │ ├── chapter4 │ │ │ ├── MusicalCarriageTest.java │ │ │ ├── PrimitivesTest.java │ │ │ ├── OptionalExampleTest.java │ │ │ ├── TestDefaultSubClassing.java │ │ │ └── TestOrder.java │ │ ├── chapter3 │ │ │ ├── IterationTest.java │ │ │ ├── StreamExercisesTest.java │ │ │ └── RefactorTest.java │ │ ├── chapter9 │ │ │ ├── RxExamplesTest.java │ │ │ └── AlbumLookupTest.java │ │ ├── chapter6 │ │ │ ├── MovingAverageTest.java │ │ │ └── ArrayExamplesTest.java │ │ ├── chapter1 │ │ │ └── TestPerformance.java │ │ ├── chapter7 │ │ │ ├── OrderDomainExampleTest.java │ │ │ └── TestingTest.java │ │ ├── chapter5 │ │ │ ├── StringCombinerTest.java │ │ │ ├── StringExamplesTest.java │ │ │ └── EncounterOrderTest.java │ │ └── chapter2 │ │ │ └── LambdaExercises.java │ │ ├── exercises │ │ ├── chapter6 │ │ │ ├── SerialToParallelTest.java │ │ │ └── BuggyReduceTest.java │ │ ├── chapter3 │ │ │ ├── Question2Test.java │ │ │ ├── MapUsingReduceTest.java │ │ │ ├── StringExercisesTest.java │ │ │ ├── FilterUsingReduceTest.java │ │ │ └── Question1Test.java │ │ ├── chapter2 │ │ │ └── Question2Test.java │ │ ├── chapter9 │ │ │ ├── BlockingArtistAnalyzerTest.java │ │ │ ├── FakeLookupService.java │ │ │ └── ArtistAnalyzerTest.java │ │ ├── chapter5 │ │ │ ├── WordCountTest.java │ │ │ ├── LongestNameTest.java │ │ │ ├── FibonacciTest.java │ │ │ └── GroupingByTest.java │ │ └── chapter4 │ │ │ ├── ArtistsTest.java │ │ │ └── PerformanceTest.java │ │ └── answers │ │ ├── chapter6 │ │ ├── SerialToParallelTest.java │ │ └── BuggyReduceTest.java │ │ ├── chapter3 │ │ ├── Question2Test.java │ │ ├── MapUsingReduceTest.java │ │ ├── FilterUsingReduceTest.java │ │ ├── StringExercisesTest.java │ │ └── Question1Test.java │ │ ├── chapter2 │ │ └── Question2Test.java │ │ ├── chapter5 │ │ ├── WordCountTest.java │ │ ├── LongestNameTest.java │ │ ├── FibonacciTest.java │ │ └── GroupingByTest.java │ │ ├── chapter9 │ │ ├── BlockingArtistAnalyzerTest.java │ │ ├── FakeLookupService.java │ │ └── ArtistAnalyzerTest.java │ │ └── chapter4 │ │ ├── ArtistsTest.java │ │ └── PerformanceTest.java │ └── resources │ └── com │ └── insightfullogic │ └── java8 │ └── examples │ └── chapter8 │ └── test_file ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Idea 2 | .idea 3 | *.iml 4 | 5 | # Maven 6 | target/ 7 | 8 | # Vim 9 | *.swp 10 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter9/Credentials.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter9; 2 | 3 | public class Credentials { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/mutable_custom/Customer.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5.mutable_custom; 2 | 3 | public class Customer { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/ChildImpl.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | public class ChildImpl extends ParentImpl implements Child { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/Rockable.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | public interface Rockable { 4 | 5 | public String rock(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/com/insightfullogic/java8/examples/chapter02/Function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardWarburton/java-8-lambdas-exercises/HEAD/src/main/resources/com/insightfullogic/java8/examples/chapter02/Function.png -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/ApplicationDenied.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method; 2 | 3 | public class ApplicationDenied extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/reporting/Result.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.reporting; 2 | 3 | public enum Result { 4 | SUCCESS, 5 | ERROR, 6 | FAILURE 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter9/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter9; 2 | 3 | /** 4 | * The API gets refactored to CallbackArtistAnalyzer and 5 | * the code to CompletableFutureArtistAnalyser. 6 | */ -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/OverridingChild.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | // BEGIN body 4 | public class OverridingChild extends OverridingParent implements Child { 5 | 6 | } 7 | // END body 8 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter9/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter9; 2 | 3 | /** 4 | * The API gets refactored to CallbackArtistAnalyzer and 5 | * the code to CompletableFutureArtistAnalyser. 6 | */ -------------------------------------------------------------------------------- /src/test/resources/com/insightfullogic/java8/examples/chapter8/test_file: -------------------------------------------------------------------------------- 1 | Improve Content: 2 | 3 | Cleanup: 4 | Adadsadsa;lkdsal; 5 | 6 | Add Content: 7 | dasdasdadsa 8 | 9 | dadasdsadsdas 10 | Add to Streams Chapter: 11 | 12 | dasdasdas 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/command/Action.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.command; 2 | 3 | // BEGIN Action 4 | public interface Action { 5 | 6 | public void perform(); 7 | 8 | } 9 | // END Action 10 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/reporting/ReportFormatter.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.reporting; 2 | 3 | public interface ReportFormatter { 4 | 5 | public void format(Report report); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter9/AlbumLookup.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | 5 | public interface AlbumLookup { 6 | Album lookupByName(String albumName); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/Exercises.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises; 2 | 3 | public class Exercises { 4 | 5 | public static T replaceThisWithSolution() { 6 | throw new ExerciseNotCompletedException(); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/Suite.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave; 2 | 3 | // BEGIN Suite 4 | public interface Suite { 5 | 6 | public void specifySuite(Description description); 7 | 8 | } 9 | // END Suite 10 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter2/ArrayExample.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter2; 2 | 3 | public class ArrayExample { 4 | 5 | // BEGIN ARRAY_INFERENCE 6 | final String[] array = { "hello", "world" }; 7 | // END ARRAY_INFERENCE 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter6/MovingAverage.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter6; 2 | 3 | public class MovingAverage { 4 | 5 | /*public static void sma() { 6 | IntStream.range(0, 1000) 7 | .reduce(); 8 | }*/ 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter5/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | /** 4 | * Question 2: 5 | * a. see LongestName 6 | * b. See WordCount 7 | * c. See GroupingBy 8 | * 9 | * Question 3: 10 | * See Fibonacci 11 | * 12 | */ 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/Carriage.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | // BEGIN body 4 | public interface Carriage { 5 | 6 | public default String rock() { 7 | return "... from side to side"; 8 | } 9 | 10 | } 11 | // END body 12 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/Jukebox.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | // BEGIN body 4 | public interface Jukebox { 5 | 6 | public default String rock() { 7 | return "... all over the world!"; 8 | } 9 | 10 | } 11 | // END body 12 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/HeadingLookupException.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8; 2 | 3 | import java.io.IOException; 4 | 5 | public class HeadingLookupException extends RuntimeException { 6 | public HeadingLookupException(IOException e) { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter5/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | /** 4 | * Question 2: 5 | * a. see LongestName 6 | * b. See WordCount 7 | * c. See GroupingBy 8 | * 9 | * Question 3: 10 | * See Fibonacci 11 | * 12 | */ 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/observer/LandingObserver.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.observer; 2 | 3 | // BEGIN LandingObserver 4 | public interface LandingObserver { 5 | 6 | public void observeLanding(String name); 7 | 8 | } 9 | // END LandingObserver 10 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter6/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter6; 2 | 3 | /** 4 | * Question 1: 5 | * see SerialToParallel 6 | * 7 | * Question 2: 8 | * See BuggyReduce 9 | * 10 | * Question 3: 11 | * See OptimisationExampleFixed 12 | * 13 | */ 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter6/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter6; 2 | 3 | /** 4 | * Question 1: 5 | * see SerialToParallel 6 | * 7 | * Question 2: 8 | * See BuggyReduce 9 | * 10 | * Question 3: 11 | * See OptimisationExampleFixed 12 | * 13 | */ 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/Child.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | // BEGIN body 4 | public interface Child extends Parent { 5 | 6 | @Override 7 | public default void welcome() { 8 | message("Child: Hi!"); 9 | } 10 | 11 | } 12 | // END body 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/command/Editor.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.command; 2 | 3 | // BEGIN Editor 4 | public interface Editor { 5 | 6 | public void save(); 7 | 8 | public void open(); 9 | 10 | public void close(); 11 | 12 | } 13 | // END Editor 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/OverridingParent.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | // BEGIN body 4 | public class OverridingParent extends ParentImpl { 5 | 6 | @Override 7 | public void welcome() { 8 | message("Class Parent: Hi!"); 9 | } 10 | 11 | } 12 | // END body 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter4/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter4; 2 | 3 | /** 4 | * Question 1: 5 | * see PerformanceFixed 6 | * 7 | * Question 2: 8 | * No - they are defined on java.lang.Object, and 'class always wins.' 9 | * 10 | * Question 3: 11 | * See ArtistsFixed 12 | * 13 | */ -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter4/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter4; 2 | 3 | /** 4 | * Question 1: 5 | * see PerformanceFixed 6 | * 7 | * Question 2: 8 | * No - they are defined on java.lang.Object, and 'class always wins.' 9 | * 10 | * Question 3: 11 | * See ArtistsFixed 12 | * 13 | */ -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/ExerciseNotCompletedException.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises; 2 | 3 | public class ExerciseNotCompletedException extends RuntimeException { 4 | 5 | public ExerciseNotCompletedException() { 6 | super("Please remove this line of code and implement the exercise"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/MusicalCarriage.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | // BEGIN body 4 | public class MusicalCarriage 5 | implements Carriage, Jukebox { 6 | 7 | @Override 8 | public String rock() { 9 | return Carriage.super.rock(); 10 | } 11 | 12 | } 13 | // END body 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/Parent.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | // BEGIN body 4 | public interface Parent { 5 | 6 | public void message(String body); 7 | 8 | public default void welcome() { 9 | message("Parent: Hi!"); 10 | } 11 | 12 | public String getLastMessage(); 13 | 14 | } 15 | // END body 16 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter9/AlbumLookupException.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter9; 2 | 3 | public class AlbumLookupException extends RuntimeException { 4 | 5 | public AlbumLookupException(Throwable cause) { 6 | super(cause); 7 | } 8 | 9 | public AlbumLookupException(String message) { 10 | super(message); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/Specification.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave; 2 | 3 | import com.insightfullogic.java8.examples.chapter8.lambdabehave.expectations.Expect; 4 | 5 | // BEGIN Specification 6 | public interface Specification { 7 | 8 | public void specifyBehaviour(Expect expect); 9 | 10 | } 11 | // END Specification 12 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/lambdas/Criteria.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method.lambdas; 2 | 3 | import com.insightfullogic.java8.examples.chapter8.template_method.ApplicationDenied; 4 | 5 | // BEGIN Criteria 6 | public interface Criteria { 7 | 8 | public void check() throws ApplicationDenied; 9 | 10 | } 11 | // END Criteria 12 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/observer/Nasa.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.observer; 2 | 3 | // BEGIN Nasa 4 | public class Nasa implements LandingObserver { 5 | @Override 6 | public void observeLanding(String name) { 7 | if (name.contains("Apollo")) { 8 | System.out.println("We made it!"); 9 | } 10 | } 11 | } 12 | // END Nasa 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter6/BuggyReduce.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter6; 2 | 3 | import java.util.List; 4 | 5 | public class BuggyReduce { 6 | 7 | public static int multiplyThrough(List linkedListOfNumbers) { 8 | return linkedListOfNumbers.stream() 9 | .reduce(5, (acc, x) -> x * acc); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/Lets.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave; 2 | 3 | public final class Lets { 4 | 5 | // BEGIN describe 6 | public static void describe(String name, Suite behavior) { 7 | Description description = new Description(name); 8 | behavior.specifySuite(description); 9 | } 10 | // END describe 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/command/Close.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.command; 2 | 3 | public class Close implements Action { 4 | 5 | private final Editor editor; 6 | 7 | public Close(Editor editor) { 8 | this.editor = editor; 9 | } 10 | 11 | @Override 12 | public void perform() { 13 | editor.close(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter4/MusicalCarriageTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | 4 | import junit.framework.Assert; 5 | import org.junit.Test; 6 | 7 | public class MusicalCarriageTest { 8 | 9 | @Test 10 | public void rocksLikeACarriage() { 11 | Assert.assertEquals("... from side to side", new MusicalCarriage().rock()); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter4/PrimitivesTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.SampleData; 4 | import org.junit.Test; 5 | 6 | public class PrimitivesTest { 7 | 8 | @Test 9 | public void albumStatistics() { 10 | Primitives.printTrackLengthStatistics(SampleData.aLoveSupreme); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter2/Question2.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter2; 2 | 3 | import java.text.DateFormat; 4 | import java.text.SimpleDateFormat; 5 | 6 | import static java.lang.ThreadLocal.withInitial; 7 | 8 | public class Question2 { 9 | 10 | public final static ThreadLocal formatter = withInitial(() -> new SimpleDateFormat("dd-MMM-yyyy")); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/strategy/CompressionStrategy.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.strategy; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | // BEGIN CompressionStrategy 7 | public interface CompressionStrategy { 8 | 9 | public OutputStream compress(OutputStream data) throws IOException; 10 | 11 | } 12 | // END CompressionStrategy 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/ParentImpl.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | public class ParentImpl implements Parent { 4 | 5 | private String body; 6 | 7 | @Override 8 | public void message(String body) { 9 | this.body = body; 10 | } 11 | 12 | @Override 13 | public String getLastMessage() { 14 | return body; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter4/Performance.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.stream.Stream; 6 | 7 | /** A Performance by some musicians - e.g., an Album or Gig. */ 8 | public interface Performance { 9 | 10 | public String getName(); 11 | 12 | public Stream getMusicians(); 13 | 14 | } -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter9/ArtistAnalyzer.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter9; 2 | 3 | import java.util.function.Consumer; 4 | 5 | // BEGIN class 6 | public interface ArtistAnalyzer { 7 | 8 | public void isLargerGroup(String artistName, 9 | String otherArtistName, 10 | Consumer handler); 11 | 12 | } 13 | // END class 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter4/Performance.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.stream.Stream; 6 | 7 | /** A Performance by some musicians - e.g., an Album or Gig. */ 8 | public interface Performance { 9 | 10 | public String getName(); 11 | 12 | public Stream getMusicians(); 13 | 14 | } -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/command/Open.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.command; 2 | 3 | // BEGIN Open 4 | public class Open implements Action { 5 | 6 | private final Editor editor; 7 | 8 | public Open(Editor editor) { 9 | this.editor = editor; 10 | } 11 | 12 | @Override 13 | public void perform() { 14 | editor.open(); 15 | } 16 | } 17 | // END Open 18 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/command/Save.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.command; 2 | 3 | // BEGIN Save 4 | public class Save implements Action { 5 | 6 | private final Editor editor; 7 | 8 | public Save(Editor editor) { 9 | this.editor = editor; 10 | } 11 | 12 | @Override 13 | public void perform() { 14 | editor.save(); 15 | } 16 | } 17 | // END Save 18 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter9/ArtistAnalyzer.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter9; 2 | 3 | import java.util.function.Consumer; 4 | 5 | // BEGIN class 6 | public interface ArtistAnalyzer { 7 | 8 | public void isLargerGroup(String artistName, 9 | String otherArtistName, 10 | Consumer handler); 11 | 12 | } 13 | // END class 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter5/Fibonacci.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class Fibonacci { 9 | 10 | public Fibonacci() { 11 | } 12 | 13 | public long fibonacci(int x) { 14 | return Exercises.replaceThisWithSolution(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter2/Question2.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter2; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | 5 | import javax.swing.text.DateFormatter; 6 | 7 | import static java.lang.ThreadLocal.withInitial; 8 | 9 | public class Question2 { 10 | 11 | public static ThreadLocal formatter 12 | = Exercises.replaceThisWithSolution(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/observer/Aliens.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.observer; 2 | 3 | // BEGIN Aliens 4 | public class Aliens implements LandingObserver { 5 | 6 | @Override 7 | public void observeLanding(String name) { 8 | if (name.contains("Apollo")) { 9 | System.out.println("They're distracted, lets invade earth!"); 10 | } 11 | } 12 | 13 | } 14 | // END Aliens 15 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/traditional/EmployeeLoanApplication.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method.traditional; 2 | 3 | // BEGIN EmployeeLoanApplication 4 | public class EmployeeLoanApplication extends PersonalLoanApplication { 5 | 6 | @Override 7 | protected void checkIncomeHistory() { 8 | // They work for us! 9 | } 10 | 11 | } 12 | // END EmployeeLoanApplication 13 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter2/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter2; 2 | 3 | /** 4 | * Question 1: 5 | * a. See Function.png 6 | * b. Unary Operators, for example 'not' 7 | * c. x -> x + 1; 8 | * 9 | * Question 2: 10 | * a. N/A 11 | * 12 | * Question 3: 13 | * a. Yes 14 | * b. Yes 15 | * c. No - the lambda expression could be inferred as IntPred or Predicate so the overload is ambiguous. 16 | */ -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/Company.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method; 2 | 3 | public interface Company { 4 | 5 | // BEGIN checkSignatures 6 | public void checkIdentity() throws ApplicationDenied; 7 | 8 | public void checkProfitAndLoss() throws ApplicationDenied; 9 | 10 | public void checkHistoricalDebt() throws ApplicationDenied; 11 | // END checkSignatures 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter2/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter2; 2 | 3 | /** 4 | * Question 1: 5 | * a. See Function.png 6 | * b. Unary Operators, for example 'not' 7 | * c. x -> x + 1; 8 | * 9 | * Question 2: 10 | * a. N/A 11 | * 12 | * Question 3: 13 | * a. Yes 14 | * b. Yes 15 | * c. No - the lambda expression could be inferred as IntPred or Predicate so the overload is ambiguous. 16 | */ -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter3/Question2.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.exercises.Exercises; 5 | 6 | import java.util.List; 7 | 8 | public class Question2 { 9 | // Q3 10 | public static int countBandMembersInternal(List artists) { 11 | return Exercises.replaceThisWithSolution(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter5/WordCount.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | import java.util.Map; 4 | import java.util.stream.Stream; 5 | 6 | import static java.util.stream.Collectors.counting; 7 | import static java.util.stream.Collectors.groupingBy; 8 | 9 | public class WordCount { 10 | 11 | public static Map countWords(Stream names) { 12 | return names.collect(groupingBy(name -> name, counting())); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/traditional/CompanyLoanApplication.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method.traditional; 2 | 3 | public class CompanyLoanApplication extends LoanApplication { 4 | 5 | @Override 6 | protected void checkIdentity() { 7 | 8 | } 9 | 10 | @Override 11 | protected void checkIncomeHistory() { 12 | 13 | } 14 | 15 | @Override 16 | protected void checkCreditHistory() { 17 | 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter6/SerialToParallelTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter6; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.stream.IntStream; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | public class SerialToParallelTest { 10 | 11 | @Test 12 | public void testSerialToParallel() { 13 | IntStream range = IntStream.range(0, 100); 14 | assertEquals(328350, SerialToParallel.sumOfSquares(range)); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/traditional/PersonalLoanApplication.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method.traditional; 2 | 3 | public class PersonalLoanApplication extends LoanApplication { 4 | 5 | @Override 6 | protected void checkIdentity() { 7 | 8 | } 9 | 10 | @Override 11 | protected void checkIncomeHistory() { 12 | 13 | } 14 | 15 | @Override 16 | protected void checkCreditHistory() { 17 | 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/lambdas/CompanyLoanApplication.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method.lambdas; 2 | 3 | // BEGIN CompanyLoanApplication 4 | public class CompanyLoanApplication extends LoanApplication { 5 | 6 | public CompanyLoanApplication(Company company) { 7 | super(company::checkIdentity, 8 | company::checkHistoricalDebt, 9 | company::checkProfitAndLoss); 10 | } 11 | 12 | } 13 | // END CompanyLoanApplication 14 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter6/BuggyReduceTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter6; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class BuggyReduceTest { 11 | 12 | @Test 13 | public void sample() { 14 | List numbers = Arrays.asList(1, 2, 3); 15 | int result = BuggyReduce.multiplyThrough(numbers); 16 | assertEquals(30, result); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter6/SerialToParallel.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter6; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | 5 | import java.util.stream.IntStream; 6 | 7 | public class SerialToParallel { 8 | 9 | public static int sumOfSquares(IntStream range) { 10 | return Exercises.replaceThisWithSolution(); 11 | } 12 | 13 | public static int sequentialSumOfSquares(IntStream range) { 14 | return Exercises.replaceThisWithSolution(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter5/Fibonacci.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class Fibonacci { 7 | 8 | private final Map cache; 9 | 10 | public Fibonacci() { 11 | cache = new HashMap<>(); 12 | cache.put(0, 0L); 13 | cache.put(1, 1L); 14 | } 15 | 16 | public long fibonacci(int x) { 17 | return cache.computeIfAbsent(x, n -> fibonacci(n-1) + fibonacci(n-2)); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter6/SerialToParallel.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter6; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | public class SerialToParallel { 6 | 7 | public static int sumOfSquares(IntStream range) { 8 | return range.parallel() 9 | .map(x -> x * x) 10 | .sum(); 11 | } 12 | 13 | public static int sequentialSumOfSquares(IntStream range) { 14 | return range.map(x -> x * x) 15 | .sum(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/mutable_custom/CollectorExpansions.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5.mutable_custom; 2 | 3 | import java.util.stream.Collector; 4 | import java.util.stream.Collectors; 5 | 6 | public class CollectorExpansions { 7 | 8 | public static final Collector 9 | reportingAlbumSales() { 10 | return Collectors.reducing(new AlbumSalesReport(), album -> new AlbumSalesReport(album), (left, right) -> left.merge(right)); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/lambdas/Company.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method.lambdas; 2 | 3 | import com.insightfullogic.java8.examples.chapter8.template_method.ApplicationDenied; 4 | 5 | public class Company { 6 | 7 | public void checkIdentity() throws ApplicationDenied { 8 | 9 | } 10 | 11 | public void checkProfitAndLoss() throws ApplicationDenied { 12 | 13 | } 14 | 15 | public void checkHistoricalDebt() throws ApplicationDenied { 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/expectations/BoundExpectation.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.expectations; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | public class BoundExpectation { 6 | 7 | private final Object objectUnderTest; 8 | 9 | public BoundExpectation(Object value) { 10 | this.objectUnderTest = value; 11 | } 12 | 13 | public void isEqualTo(Object expected) { 14 | assertEquals(expected, objectUnderTest); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/Order.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | 4 | import com.insightfullogic.java8.examples.chapter1.Album; 5 | 6 | import java.util.List; 7 | 8 | public abstract class Order { 9 | 10 | protected final List albums; 11 | 12 | public Order(List albums) { 13 | this.albums = albums; 14 | } 15 | 16 | public abstract long countRunningTime(); 17 | 18 | public abstract long countMusicians(); 19 | 20 | public abstract long countTracks(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/mutable_custom/AlbumSalesReport.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5.mutable_custom; 2 | 3 | public class AlbumSalesReport { 4 | 5 | public AlbumSalesReport() { 6 | 7 | } 8 | 9 | public AlbumSalesReport(AlbumSale album) { 10 | this(); 11 | acknowledgeSale(album); 12 | } 13 | 14 | public void acknowledgeSale(AlbumSale album) { 15 | 16 | } 17 | 18 | public AlbumSalesReport merge(AlbumSalesReport right) { 19 | return null; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/strategy/ZipCompressionStrategy.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.strategy; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.util.zip.ZipOutputStream; 6 | 7 | // BEGIN ZipCompressionStrategy 8 | public class ZipCompressionStrategy implements CompressionStrategy { 9 | 10 | @Override 11 | public OutputStream compress(OutputStream data) throws IOException { 12 | return new ZipOutputStream(data); 13 | } 14 | 15 | } 16 | // END ZipCompressionStrategy 17 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter3/Functional.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter3; 2 | 3 | import javax.swing.*; 4 | import java.awt.event.ActionEvent; 5 | 6 | public class Functional { 7 | 8 | private JButton button = new JButton(); 9 | 10 | // BEGIN field_assignment 11 | private ActionEvent lastEvent; 12 | 13 | private void registerHandler() { 14 | button.addActionListener((ActionEvent event) -> { 15 | this.lastEvent = event; 16 | }); 17 | } 18 | // END field_assignment 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/strategy/GzipCompressionStrategy.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.strategy; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.util.zip.GZIPOutputStream; 6 | 7 | // BEGIN GzipCompressionStrategy 8 | public class GzipCompressionStrategy implements CompressionStrategy { 9 | 10 | @Override 11 | public OutputStream compress(OutputStream data) throws IOException { 12 | return new GZIPOutputStream(data); 13 | } 14 | 15 | } 16 | // END GzipCompressionStrategy 17 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter3/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | /** 4 | * Question 1: 5 | * See the Question1 class 6 | * 7 | * Question 2: 8 | * see the Question2 class 9 | * 10 | * Question 3: 11 | * a. Eager 12 | * b. Lazy 13 | * 14 | * Question 4: 15 | * a. Yes - takes a function as an argument 16 | * b. No 17 | * 18 | * Question 5: 19 | * a. Side Effect Free 20 | * b. Mutates count 21 | * 22 | * Question 6: 23 | * StringExercises 24 | * 25 | * Question 7: 26 | * StringExercises 27 | */ -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/command/Macro.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.command; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | // BEGIN Macro 7 | public class Macro { 8 | 9 | private final List actions; 10 | 11 | public Macro() { 12 | actions = new ArrayList<>(); 13 | } 14 | 15 | public void record(Action action) { 16 | actions.add(action); 17 | } 18 | 19 | public void run() { 20 | actions.forEach(Action::perform); 21 | } 22 | 23 | } 24 | // END Macro 25 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter3/MapUsingReduce.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.function.Function; 8 | import java.util.stream.Stream; 9 | 10 | /** 11 | * Advanced Exercises Question 1 12 | */ 13 | public class MapUsingReduce { 14 | 15 | public static List map(Stream stream, Function mapper) { 16 | return Exercises.replaceThisWithSolution(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter6/SerialToParallelTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter6; 2 | 3 | import com.insightfullogic.java8.answers.chapter6.SerialToParallel; 4 | import org.junit.Test; 5 | 6 | import java.util.stream.IntStream; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class SerialToParallelTest { 11 | 12 | @Test 13 | public void testSerialToParallel() { 14 | IntStream range = IntStream.range(0, 100); 15 | assertEquals(328350, SerialToParallel.sumOfSquares(range)); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/expectations/Expect.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.expectations; 2 | 3 | import java.util.Collection; 4 | 5 | // BEGIN Expect 6 | public final class Expect { 7 | 8 | public BoundExpectation that(Object value) { 9 | return new BoundExpectation(value); 10 | } 11 | 12 | // Rest of class omitted 13 | // END Expect 14 | 15 | public CollectionExpectation that(Collection collection) { 16 | return new CollectionExpectation(collection); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter1/Performance.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter1; 2 | 3 | import java.util.stream.Stream; 4 | 5 | import static java.util.stream.Stream.concat; 6 | 7 | public interface Performance { 8 | 9 | public String getName(); 10 | 11 | public Stream getMusicians(); 12 | 13 | // TODO: test 14 | public default Stream getAllMusicians() { 15 | return getMusicians().flatMap(artist -> { 16 | return concat(Stream.of(artist), artist.getMembers()); 17 | }); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter3/FilterUsingReduce.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.function.Predicate; 8 | import java.util.stream.Stream; 9 | 10 | /** 11 | * Advanced Exercises Question 2 12 | */ 13 | public class FilterUsingReduce { 14 | 15 | public static List filter(Stream stream, Predicate predicate) { 16 | return Exercises.replaceThisWithSolution(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter5/WordCount.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | 5 | import java.util.Map; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | import static java.util.stream.Collectors.counting; 10 | import static java.util.stream.Collectors.groupingBy; 11 | 12 | public class WordCount { 13 | 14 | public static Map countWords(Stream names) { 15 | return Exercises.replaceThisWithSolution(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter6/BuggyReduceTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter6; 2 | 3 | import com.insightfullogic.java8.answers.chapter6.BuggyReduce; 4 | import org.junit.Test; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class BuggyReduceTest { 12 | 13 | @Test 14 | public void sample() { 15 | List numbers = Arrays.asList(1, 2, 3); 16 | int result = BuggyReduce.multiplyThrough(numbers); 17 | assertEquals(30, result); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter3/Question2Test.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.SampleData; 4 | import org.junit.Test; 5 | 6 | import java.util.Arrays; 7 | 8 | import static com.insightfullogic.java8.answers.chapter3.Question2.countBandMembersInternal; 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class Question2Test { 12 | 13 | @Test 14 | public void internal() { 15 | assertEquals(4, countBandMembersInternal(Arrays.asList(SampleData.johnColtrane, SampleData.theBeatles))); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter3/Question2Test.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.SampleData; 4 | import org.junit.Test; 5 | 6 | import java.util.Arrays; 7 | 8 | import static com.insightfullogic.java8.exercises.chapter3.Question2.countBandMembersInternal; 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class Question2Test { 12 | 13 | @Test 14 | public void internal() { 15 | assertEquals(4, countBandMembersInternal(Arrays.asList(SampleData.johnColtrane, SampleData.theBeatles))); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter3/GeneratingStreams.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter3; 2 | 3 | import java.util.stream.Stream; 4 | 5 | public class GeneratingStreams { 6 | 7 | public static void main(String[] args) { 8 | iterate(); 9 | } 10 | 11 | static void generate() { 12 | Stream.generate(() -> "hello world") 13 | .limit(3) 14 | .forEach(System.out::println); 15 | } 16 | 17 | static void iterate() { 18 | Stream.iterate(0, x -> x + 1) 19 | 20 | .limit(5) 21 | .forEach(System.out::println); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter3/StringExercises.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | 5 | import java.util.Comparator; 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | public class StringExercises { 10 | 11 | // Question 6 12 | public static int countLowercaseLetters(String string) { 13 | return Exercises.replaceThisWithSolution(); 14 | } 15 | 16 | // Question 7 17 | public static Optional mostLowercaseString(List strings) { 18 | return Exercises.replaceThisWithSolution(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter2/Question2Test.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter2; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Calendar; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | public class Question2Test { 10 | 11 | @Test 12 | public void exampleInB() { 13 | Calendar cal = Calendar.getInstance(); 14 | cal.set(Calendar.YEAR, 1970); 15 | cal.set(Calendar.MONTH, Calendar.JANUARY); 16 | cal.set(Calendar.DAY_OF_MONTH, 1); 17 | String formatted = Question2.formatter.get().format(cal.getTime()); 18 | assertEquals("01-Jan-1970", formatted); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter3/IterationTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.SampleData; 4 | import org.junit.Test; 5 | 6 | public class IterationTest { 7 | 8 | @Test 9 | public void lazyPrintOuts() { 10 | Iteration iteration = new Iteration(); 11 | iteration.filterArtistsFromLondonPrinted(SampleData.membersOfTheBeatles); 12 | } 13 | 14 | @Test 15 | public void evaluatedPrintOuts() { 16 | Iteration iteration = new Iteration(); 17 | iteration.internalCountArtistsFromLondonPrinted(SampleData.membersOfTheBeatles); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter4/PerformanceFixed.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.stream.Stream; 6 | 7 | import static java.util.stream.Stream.concat; 8 | 9 | /** A Performance by some musicians - eg an Album or Gig. */ 10 | public interface PerformanceFixed { 11 | 12 | public String getName(); 13 | 14 | public Stream getMusicians(); 15 | 16 | public default Stream getAllMusicians() { 17 | return getMusicians() 18 | .flatMap(artist -> concat(Stream.of(artist), artist.getMembers())); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter4/PerformanceFixed.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.exercises.Exercises; 5 | 6 | import java.util.stream.Stream; 7 | 8 | import static java.util.stream.Stream.concat; 9 | 10 | /** A Performance by some musicians - eg an Album or Gig. */ 11 | public interface PerformanceFixed { 12 | 13 | public String getName(); 14 | 15 | public Stream getMusicians(); 16 | 17 | public default Stream getAllMusicians() { 18 | return Exercises.replaceThisWithSolution(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/expectations/CollectionExpectation.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.expectations; 2 | 3 | import java.util.Collection; 4 | 5 | import static junit.framework.Assert.assertTrue; 6 | 7 | public class CollectionExpectation extends BoundExpectation { 8 | 9 | private final Collection objectUnderTest; 10 | 11 | public CollectionExpectation(Collection objectUnderTest) { 12 | super(objectUnderTest); 13 | this.objectUnderTest = objectUnderTest; 14 | } 15 | 16 | public void isEmpty() { 17 | assertTrue(objectUnderTest.isEmpty()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter6/BuggyReduce.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter6; 2 | 3 | import java.util.List; 4 | 5 | public class BuggyReduce { 6 | 7 | /* 8 | Buggy Version: 9 | // BEGIN buggyMultiplyThrough 10 | public static int multiplyThrough(List linkedListOfNumbers) { 11 | return linkedListOfNumbers.stream() 12 | .reduce(5, (acc, x) -> x * acc); 13 | } 14 | // END buggyMultiplyThrough 15 | */ 16 | 17 | public static int multiplyThrough(List numbers) { 18 | return 5 * numbers.parallelStream() 19 | .reduce(1, (acc, x) -> x * acc); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter2/Question2Test.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter2; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Calendar; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | public class Question2Test { 10 | 11 | @Test 12 | public void exampleInB() { 13 | Calendar cal = Calendar.getInstance(); 14 | cal.set(Calendar.YEAR, 1970); 15 | cal.set(Calendar.MONTH, Calendar.JANUARY); 16 | cal.set(Calendar.DAY_OF_MONTH, 1); 17 | String formatted = Question2.formatter.get().getFormat().format(cal.getTime()); 18 | assertEquals("01-Jan-1970", formatted); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter3/package-info.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | /** 4 | * Question 1: 5 | * See the Question1 class 6 | * 7 | * Question 2: 8 | * see the Question2 class 9 | * 10 | * Question 3: 11 | * This question is to test how much we know about evaluation. So as we understood, Streams are lazy and others are Eager. 12 | * a. Eager 13 | * b. Lazy 14 | * 15 | * Question 4: 16 | * a. Yes - takes a function as an argument 17 | * b. No 18 | * 19 | * Question 5: 20 | * a. Side Effect Free 21 | * b. Mutates count 22 | * 23 | * Question 6: 24 | * StringExercises 25 | * 26 | * Question 7: 27 | * StringExercises 28 | */ 29 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter2/CaptureCompileError.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter2; 2 | 3 | import javax.swing.*; 4 | 5 | public class CaptureCompileError { 6 | 7 | private JButton button; 8 | 9 | public void error() { 10 | String name = getUserName(); 11 | name = formatUserName(name); 12 | // Uncommenting this line should cause a compile error: 13 | // button.addActionListener(event -> System.out.println("hi " + name)); 14 | } 15 | 16 | private String formatUserName(String name) { 17 | return name.toLowerCase(); 18 | } 19 | 20 | private String getUserName() { 21 | return "RICHARD"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter3/Question2.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.List; 6 | 7 | public class Question2 { 8 | // Q3 9 | public static int countBandMembersInternal(List artists) { 10 | // NB: readers haven't learnt about primitives yet, so can't use the sum() method 11 | return artists.stream() 12 | .map(artist -> artist.getMembers().count()) 13 | .reduce(0L, Long::sum) 14 | .intValue(); 15 | 16 | //return (int) artists.stream().flatMap(artist -> artist.getMembers()).count(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter1/MusicChapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package com.insightfullogic.java8.examples.chapter1; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * 13 | * @author Richard Warburton 14 | */ 15 | public abstract class MusicChapter { 16 | 17 | protected final List artists; 18 | protected final List albums; 19 | 20 | public MusicChapter() { 21 | artists = new ArrayList<>(); 22 | albums = new ArrayList<>(); 23 | loadData(""); 24 | } 25 | 26 | private void loadData(String file) { 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter5/LongestName.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.exercises.Exercises; 5 | 6 | import java.util.Comparator; 7 | import java.util.List; 8 | import java.util.Objects; 9 | import java.util.stream.Collectors; 10 | 11 | import static java.util.Comparator.comparing; 12 | 13 | public class LongestName { 14 | 15 | public static Artist byReduce(List artists) { 16 | return Exercises.replaceThisWithSolution(); 17 | } 18 | 19 | public static Artist byCollecting(List artists) { 20 | return Exercises.replaceThisWithSolution(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter3/StringExercises.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import java.util.Comparator; 4 | import java.util.List; 5 | import java.util.Optional; 6 | 7 | public class StringExercises { 8 | 9 | // Question 6 10 | public static int countLowercaseLetters(String string) { 11 | return (int) string.chars() 12 | .filter(Character::isLowerCase) 13 | .count(); 14 | } 15 | 16 | // Question 7 17 | public static Optional mostLowercaseString(List strings) { 18 | return strings.stream() 19 | .max(Comparator.comparingInt(StringExercises::countLowercaseLetters)); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter9/BlockingArtistAnalyzerTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter9; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertFalse; 6 | import static org.junit.Assert.assertTrue; 7 | 8 | public class BlockingArtistAnalyzerTest { 9 | 10 | private final BlockingArtistAnalyzer analyser = new BlockingArtistAnalyzer(new FakeLookupService()::lookupArtistName); 11 | 12 | @Test 13 | public void largerGroupsAreLarger() { 14 | assertTrue(analyser.isLargerGroup("The Beatles", "John Coltrane")); 15 | } 16 | 17 | @Test 18 | public void smallerGroupsArentLarger() { 19 | assertFalse(analyser.isLargerGroup("John Coltrane", "The Beatles")); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter9/RxExamplesTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import org.junit.Test; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | public class RxExamplesTest { 10 | 11 | @Test 12 | public void filtersAlbums() throws InterruptedException { 13 | RxExamples examples = new RxExamples(SampleData.getThreeArtists()); 14 | Artist artist = examples.search("John", "UK", 5) 15 | .toBlockingObservable() 16 | .single(); 17 | 18 | assertEquals(SampleData.johnLennon, artist); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/mutable_custom/AlbumSale.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5.mutable_custom; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | 5 | public final class AlbumSale { 6 | 7 | private final Album album; 8 | private final Customer customer; 9 | private final long price; 10 | 11 | public AlbumSale(Album album, Customer customer, long price) { 12 | this.album = album; 13 | this.customer = customer; 14 | this.price = price; 15 | } 16 | 17 | public Album getAlbum() { 18 | return album; 19 | } 20 | 21 | public Customer getCustomer() { 22 | return customer; 23 | } 24 | 25 | public long getPrice() { 26 | return price; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter5/WordCountTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Map; 6 | import java.util.stream.Stream; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class WordCountTest { 11 | 12 | @Test 13 | public void passesBookExample() { 14 | Stream names = Stream.of("John", "Paul", "George", "John", "Paul", "John"); 15 | Map counts = WordCount.countWords(names); 16 | 17 | assertEquals(3, counts.size()); 18 | assertEquals(Long.valueOf(3), counts.get("John")); 19 | assertEquals(Long.valueOf(2), counts.get("Paul")); 20 | assertEquals(Long.valueOf(1), counts.get("George")); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter6/MovingAverageTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter6; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | 7 | import static org.junit.Assert.assertArrayEquals; 8 | 9 | public class MovingAverageTest { 10 | 11 | /*@Test(expected = IllegalArgumentException.class) 12 | public void emptyArray() { 13 | ArrayExamples.simpleMovingAverage(new double[]{}, 3); 14 | }*/ 15 | 16 | @Test 17 | public void smallArray() { 18 | double[] input = {0, 1, 2, 3, 4, 3.5}; 19 | double[] result = ArrayExamples.simpleMovingAverage(input, 3); 20 | System.out.println(Arrays.toString(result)); 21 | double[] expected = {1, 2, 3, 3.5}; 22 | assertArrayEquals(expected, result, 0.0); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/template_method/TraditionalTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method; 2 | 3 | import com.insightfullogic.java8.examples.chapter8.template_method.traditional.CompanyLoanApplication; 4 | import com.insightfullogic.java8.examples.chapter8.template_method.traditional.EmployeeLoanApplication; 5 | import com.insightfullogic.java8.examples.chapter8.template_method.traditional.PersonalLoanApplication; 6 | import org.junit.Test; 7 | 8 | public class TraditionalTest { 9 | 10 | @Test 11 | public void fitsTogether() throws ApplicationDenied { 12 | new CompanyLoanApplication().checkLoanApplication(); 13 | new PersonalLoanApplication().checkLoanApplication(); 14 | new EmployeeLoanApplication().checkLoanApplication(); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter5/LongestNameTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import org.junit.Test; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | public class LongestNameTest { 10 | 11 | @Test 12 | public void findsLongestNameByReduce() { 13 | Artist artist = LongestName.byReduce(SampleData.getThreeArtists()); 14 | assertEquals(SampleData.johnColtrane, artist); 15 | } 16 | 17 | @Test 18 | public void findsLongestNameByCollecting() { 19 | Artist artist = LongestName.byCollecting(SampleData.getThreeArtists()); 20 | assertEquals(SampleData.johnColtrane, artist); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter5/WordCountTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | import com.insightfullogic.java8.answers.chapter5.WordCount; 4 | import org.junit.Test; 5 | 6 | import java.util.Map; 7 | import java.util.stream.Stream; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class WordCountTest { 12 | 13 | @Test 14 | public void passesBookExample() { 15 | Stream names = Stream.of("John", "Paul", "George", "John", "Paul", "John"); 16 | Map counts = WordCount.countWords(names); 17 | 18 | assertEquals(3, counts.size()); 19 | assertEquals(Long.valueOf(3), counts.get("John")); 20 | assertEquals(Long.valueOf(2), counts.get("Paul")); 21 | assertEquals(Long.valueOf(1), counts.get("George")); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/command/MockEditor.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.command; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | public class MockEditor implements Editor { 9 | 10 | private final List actions = new ArrayList<>(); 11 | 12 | @Override 13 | public void save() { 14 | actions.add("save"); 15 | } 16 | 17 | @Override 18 | public void open() { 19 | actions.add("open"); 20 | } 21 | 22 | @Override 23 | public void close() { 24 | actions.add("close"); 25 | } 26 | 27 | public void check() { 28 | assertEquals("open", actions.get(0)); 29 | assertEquals("save", actions.get(1)); 30 | assertEquals("close", actions.get(2)); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/reporting/SuiteReport.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.reporting; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Stream; 6 | 7 | public final class SuiteReport { 8 | 9 | private final String name; 10 | private final List specifications; 11 | 12 | public SuiteReport(String name) { 13 | this.name = name; 14 | specifications = new ArrayList<>(); 15 | } 16 | 17 | public void add(SpecificationReport specification) { 18 | specifications.add(specification); 19 | } 20 | 21 | public Stream specifications() { 22 | return specifications.stream(); 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter4/ArtistsFixed.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | public class ArtistsFixed { 9 | 10 | private List artists; 11 | 12 | public ArtistsFixed(List artists) { 13 | this.artists = artists; 14 | } 15 | 16 | public Optional getArtist(int index) { 17 | if (index < 0 || index >= artists.size()) { 18 | return Optional.empty(); 19 | } 20 | return Optional.of(artists.get(index)); 21 | } 22 | 23 | public String getArtistName(int index) { 24 | Optional artist = getArtist(index); 25 | return artist.map(Artist::getName) 26 | .orElse("unknown"); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter9/BlockingArtistAnalyzerTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter9; 2 | 3 | import com.insightfullogic.java8.answers.chapter9.BlockingArtistAnalyzer; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertFalse; 7 | import static org.junit.Assert.assertTrue; 8 | 9 | public class BlockingArtistAnalyzerTest { 10 | 11 | private final com.insightfullogic.java8.answers.chapter9.BlockingArtistAnalyzer analyser = new BlockingArtistAnalyzer(new FakeLookupService()::lookupArtistName); 12 | 13 | @Test 14 | public void largerGroupsAreLarger() { 15 | assertTrue(analyser.isLargerGroup("The Beatles", "John Coltrane")); 16 | } 17 | 18 | @Test 19 | public void smallerGroupsArentLarger() { 20 | assertFalse(analyser.isLargerGroup("John Coltrane", "The Beatles")); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter3/Question1.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.Artist; 5 | import com.insightfullogic.java8.exercises.Exercises; 6 | 7 | import java.util.List; 8 | import java.util.stream.Stream; 9 | 10 | import static java.util.stream.Collectors.toList; 11 | 12 | public class Question1 { 13 | public static int addUp(Stream numbers) { 14 | return Exercises.replaceThisWithSolution(); 15 | } 16 | 17 | public static List getNamesAndOrigins(List artists) { 18 | return Exercises.replaceThisWithSolution(); 19 | } 20 | 21 | public static List getAlbumsWithAtMostThreeTracks(List input) { 22 | return Exercises.replaceThisWithSolution(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/Primitives.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | 5 | import java.util.IntSummaryStatistics; 6 | 7 | public class Primitives { 8 | 9 | // BEGIN printTrackLengthStatistics 10 | public static void printTrackLengthStatistics(Album album) { 11 | IntSummaryStatistics trackLengthStats 12 | = album.getTracks() 13 | .mapToInt(track -> track.getLength()) 14 | .summaryStatistics(); 15 | 16 | System.out.printf("Max: %d, Min: %d, Ave: %f, Sum: %d", 17 | trackLengthStats.getMax(), 18 | trackLengthStats.getMin(), 19 | trackLengthStats.getAverage(), 20 | trackLengthStats.getSum()); 21 | } 22 | // END printTrackLengthStatistics 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter4/OptionalExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Optional; 6 | 7 | import static org.junit.Assert.*; 8 | 9 | public class OptionalExampleTest { 10 | 11 | @Test 12 | public void examples() { 13 | // BEGIN value_creation 14 | Optional a = Optional.of("a"); 15 | assertEquals("a", a.get()); 16 | // END value_creation 17 | 18 | // BEGIN is_present 19 | Optional emptyOptional = Optional.empty(); 20 | Optional alsoEmpty = Optional.ofNullable(null); 21 | 22 | assertFalse(emptyOptional.isPresent()); 23 | 24 | // a is defined above 25 | assertTrue(a.isPresent()); 26 | // END is_present 27 | 28 | // BEGIN orElse 29 | assertEquals("b", emptyOptional.orElse("b")); 30 | assertEquals("c", emptyOptional.orElseGet(() -> "c")); 31 | // END orElse 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter1/Track.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package com.insightfullogic.java8.examples.chapter1; 7 | 8 | /** 9 | * @author richard 10 | */ 11 | public final class Track { 12 | 13 | private final String name; 14 | private final int length; 15 | 16 | public Track(String name, int length) { 17 | this.name = name; 18 | this.length = length; 19 | } 20 | 21 | /** 22 | * @return the name 23 | */ 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | /** 29 | * @return the length of the track in milliseconds. 30 | */ 31 | public int getLength() { 32 | return length; 33 | } 34 | 35 | public Track copy() { 36 | return new Track(name, length); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/traditional/LoanApplication.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method.traditional; 2 | 3 | import com.insightfullogic.java8.examples.chapter8.template_method.ApplicationDenied; 4 | 5 | // BEGIN LoanApplication 6 | public abstract class LoanApplication { 7 | 8 | public void checkLoanApplication() throws ApplicationDenied { 9 | checkIdentity(); 10 | checkCreditHistory(); 11 | checkIncomeHistory(); 12 | reportFindings(); 13 | } 14 | 15 | protected abstract void checkIdentity() throws ApplicationDenied; 16 | 17 | protected abstract void checkIncomeHistory() throws ApplicationDenied; 18 | 19 | protected abstract void checkCreditHistory() throws ApplicationDenied; 20 | 21 | private void reportFindings() { 22 | // END LoanApplication 23 | 24 | } 25 | 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/OpenClosedPrinciple.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8; 2 | 3 | import java.text.DateFormat; 4 | import java.text.SimpleDateFormat; 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | 7 | public class OpenClosedPrinciple { 8 | 9 | public void asHigherOrderFunctions() { 10 | // BEGIN local_formatter 11 | // One implementation 12 | ThreadLocal localFormatter 13 | = ThreadLocal.withInitial(() -> new SimpleDateFormat()); 14 | 15 | // Usage 16 | DateFormat formatter = localFormatter.get(); 17 | // END local_formatter 18 | 19 | // BEGIN local_thread_id 20 | // Or... 21 | AtomicInteger threadId = new AtomicInteger(); 22 | ThreadLocal localId 23 | = ThreadLocal.withInitial(() -> threadId.getAndIncrement()); 24 | 25 | // Usage 26 | int idForThisThread = localId.get(); 27 | // END local_thread_id 28 | } 29 | 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter5/FibonacciTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.stream.IntStream; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class FibonacciTest { 12 | 13 | @Test 14 | public void fibonacciMatchesOpeningSequence() { 15 | List fibonacciSequence = Arrays.asList(0L, 1L, 1L, 2L, 3L, 5L, 8L, 13L, 21L, 34L); 16 | 17 | IntStream.range(0, fibonacciSequence.size()) 18 | .forEach(x -> { 19 | Fibonacci fibonacci = new Fibonacci(); 20 | long result = fibonacci.fibonacci(x); 21 | long expectedResult = fibonacciSequence.get(x); 22 | assertEquals(expectedResult, result); 23 | }); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter5/LongestNameTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import com.insightfullogic.java8.answers.chapter5.LongestName; 6 | import org.junit.Test; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class LongestNameTest { 11 | 12 | @Test 13 | public void findsLongestNameByReduce() { 14 | Artist artist = com.insightfullogic.java8.answers.chapter5.LongestName.byReduce(SampleData.getThreeArtists()); 15 | assertEquals(SampleData.johnColtrane, artist); 16 | } 17 | 18 | @Test 19 | public void findsLongestNameByCollecting() { 20 | Artist artist = LongestName.byCollecting(SampleData.getThreeArtists()); 21 | assertEquals(SampleData.johnColtrane, artist); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/Description.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave; 2 | 3 | import com.insightfullogic.java8.examples.chapter8.lambdabehave.expectations.Expect; 4 | 5 | public final class Description { 6 | 7 | private final String suite; 8 | 9 | Description(String suite) { 10 | this.suite = suite; 11 | } 12 | 13 | // BEGIN should 14 | public void should(String description, Specification specification) { 15 | try { 16 | Expect expect = new Expect(); 17 | specification.specifyBehaviour(expect); 18 | Runner.current.recordSuccess(suite, description); 19 | } catch (AssertionError cause) { 20 | Runner.current.recordFailure(suite, description, cause); 21 | } catch (Throwable cause) { 22 | Runner.current.recordError(suite, description, cause); 23 | } 24 | } 25 | // END should 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/reporting/SpecificationReport.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.reporting; 2 | 3 | public final class SpecificationReport { 4 | 5 | private final String description; 6 | private final Result result; 7 | private final String message; 8 | 9 | public SpecificationReport(String description, Result result, String message) { 10 | this.description = description; 11 | this.result = result; 12 | this.message = message; 13 | } 14 | 15 | public SpecificationReport(String specification) { 16 | this(specification, Result.SUCCESS, null); 17 | } 18 | 19 | public String getDescription() { 20 | return description; 21 | } 22 | 23 | public Result getResult() { 24 | return result; 25 | } 26 | 27 | public String getMessage() { 28 | return message; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter5/GroupingByTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.stream.Stream; 8 | 9 | import static java.util.Arrays.asList; 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class GroupingByTest { 13 | 14 | @Test 15 | public void stringsByLength() { 16 | GroupingBy stringIntegerGroupingBy = new GroupingBy<>(String::length); 17 | Map> results = Stream.of("a", "b", "cc", "dd") 18 | .collect(stringIntegerGroupingBy); 19 | 20 | System.out.println(results); 21 | 22 | assertEquals(2, results.size()); 23 | assertEquals(asList("a", "b"), results.get(1)); 24 | assertEquals(asList("cc", "dd"), results.get(2)); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter9/BlockingArtistAnalyzer.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.function.Function; 6 | 7 | public class BlockingArtistAnalyzer { 8 | 9 | private final Function artistLookupService; 10 | 11 | public BlockingArtistAnalyzer(Function artistLookupService) { 12 | this.artistLookupService = artistLookupService; 13 | } 14 | 15 | public boolean isLargerGroup(String artistName, String otherArtistName) { 16 | return getNumberOfMembers(artistName) > getNumberOfMembers(otherArtistName); 17 | } 18 | 19 | private long getNumberOfMembers(String artistName) { 20 | return artistLookupService.apply(artistName) 21 | .getMembers() 22 | .count(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter9/CallbackArtistAnalyser.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.exercises.Exercises; 5 | 6 | import java.util.function.Consumer; 7 | import java.util.function.Function; 8 | 9 | public class CallbackArtistAnalyser implements ArtistAnalyzer { 10 | 11 | private final Function artistLookupService; 12 | 13 | public CallbackArtistAnalyser(Function artistLookupService) { 14 | this.artistLookupService = artistLookupService; 15 | } 16 | 17 | public void isLargerGroup(String artistName, String otherArtistName, Consumer handler) { 18 | Exercises.replaceThisWithSolution(); 19 | } 20 | 21 | private long getNumberOfMembers(String artistName) { 22 | return Exercises.replaceThisWithSolution(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter9/BlockingArtistAnalyzer.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.function.Function; 6 | 7 | // BEGIN class 8 | public class BlockingArtistAnalyzer { 9 | 10 | private final Function artistLookupService; 11 | 12 | public BlockingArtistAnalyzer(Function artistLookupService) { 13 | this.artistLookupService = artistLookupService; 14 | } 15 | 16 | public boolean isLargerGroup(String artistName, String otherArtistName) { 17 | return getNumberOfMembers(artistName) > getNumberOfMembers(otherArtistName); 18 | } 19 | 20 | private long getNumberOfMembers(String artistName) { 21 | return artistLookupService.apply(artistName) 22 | .getMembers() 23 | .count(); 24 | } 25 | 26 | } 27 | // END class 28 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter9/FakeLookupService.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | 6 | public class FakeLookupService { 7 | 8 | public Artist lookupArtistName(String name) { 9 | sleepToSimulateLookupLatency(); 10 | 11 | switch (name) { 12 | case "The Beatles": 13 | return SampleData.theBeatles; 14 | 15 | case "John Coltrane": 16 | return SampleData.johnColtrane; 17 | 18 | default: 19 | throw new IllegalArgumentException("Unknown artist: " + name); 20 | } 21 | } 22 | 23 | private void sleepToSimulateLookupLatency() { 24 | try { 25 | Thread.sleep(1000); 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter9/FakeLookupService.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | 6 | public class FakeLookupService { 7 | 8 | public Artist lookupArtistName(String name) { 9 | sleepToSimulateLookupLatency(); 10 | 11 | switch (name) { 12 | case "The Beatles": 13 | return SampleData.theBeatles; 14 | 15 | case "John Coltrane": 16 | return SampleData.johnColtrane; 17 | 18 | default: 19 | throw new IllegalArgumentException("Unknown artist: " + name); 20 | } 21 | } 22 | 23 | private void sleepToSimulateLookupLatency() { 24 | try { 25 | Thread.sleep(1000); 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter1/TestPerformance.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter1; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Collections; 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | import static com.insightfullogic.java8.examples.chapter1.SampleData.theBeatles; 10 | import static java.util.Collections.singletonList; 11 | import static java.util.stream.Collectors.toSet; 12 | import static junit.framework.Assert.assertEquals; 13 | 14 | public class TestPerformance { 15 | 16 | @Test 17 | public void allMembers() { 18 | Album album = new Album("foo", Collections.emptyList(), singletonList(theBeatles)); 19 | Set musicians = album.getAllMusicians().collect(toSet()); 20 | Set expectedMusicians = new HashSet<>(SampleData.membersOfTheBeatles); 21 | expectedMusicians.add(theBeatles); 22 | assertEquals(expectedMusicians, musicians); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter5/FibonacciTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | import com.insightfullogic.java8.answers.chapter5.Fibonacci; 4 | import org.junit.Test; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.stream.IntStream; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class FibonacciTest { 13 | 14 | @Test 15 | public void fibonacciMatchesOpeningSequence() { 16 | List fibonacciSequence = Arrays.asList(0L, 1L, 1L, 2L, 3L, 5L, 8L, 13L, 21L, 34L); 17 | 18 | IntStream.range(0, fibonacciSequence.size()) 19 | .forEach(x -> { 20 | com.insightfullogic.java8.answers.chapter5.Fibonacci fibonacci = new Fibonacci(); 21 | long result = fibonacci.fibonacci(x); 22 | long expectedResult = fibonacciSequence.get(x); 23 | assertEquals(expectedResult, result); 24 | }); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/OrderStreams.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | 4 | import com.insightfullogic.java8.examples.chapter1.Album; 5 | 6 | import java.util.List; 7 | 8 | public class OrderStreams extends Order { 9 | 10 | public OrderStreams(List albums) { 11 | super(albums); 12 | } 13 | 14 | // BEGIN body 15 | public long countRunningTime() { 16 | return albums.stream() 17 | .mapToLong(album -> album.getTracks() 18 | .mapToLong(track -> track.getLength()) 19 | .sum()) 20 | .sum(); 21 | } 22 | 23 | public long countMusicians() { 24 | return albums.stream() 25 | .mapToLong(album -> album.getMusicians().count()) 26 | .sum(); 27 | } 28 | 29 | public long countTracks() { 30 | return albums.stream() 31 | .mapToLong(album -> album.getTracks().count()) 32 | .sum(); 33 | } 34 | // END body 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter9/CompletableFutureArtistAnalyser.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.exercises.Exercises; 5 | 6 | import java.util.concurrent.CompletableFuture; 7 | import java.util.function.Consumer; 8 | import java.util.function.Function; 9 | 10 | public class CompletableFutureArtistAnalyser implements ArtistAnalyzer { 11 | 12 | private final Function artistLookupService; 13 | 14 | public CompletableFutureArtistAnalyser(Function artistLookupService) { 15 | this.artistLookupService = artistLookupService; 16 | } 17 | 18 | public void isLargerGroup(String artistName, String otherArtistName, Consumer handler) { 19 | Exercises.replaceThisWithSolution(); 20 | } 21 | 22 | private long getNumberOfMembers(String artistName) { 23 | return Exercises.replaceThisWithSolution(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter5/GroupingByTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | import com.insightfullogic.java8.answers.chapter5.GroupingBy; 4 | import org.junit.Test; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.stream.Stream; 9 | 10 | import static java.util.Arrays.asList; 11 | import static org.junit.Assert.assertEquals; 12 | 13 | public class GroupingByTest { 14 | 15 | @Test 16 | public void stringsByLength() { 17 | com.insightfullogic.java8.answers.chapter5.GroupingBy stringIntegerGroupingBy = new GroupingBy<>(String::length); 18 | Map> results = Stream.of("a", "b", "cc", "dd") 19 | .collect(stringIntegerGroupingBy); 20 | 21 | System.out.println(results); 22 | 23 | assertEquals(2, results.size()); 24 | assertEquals(asList("a", "b"), results.get(1)); 25 | assertEquals(asList("cc", "dd"), results.get(2)); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter3/Question1.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.Artist; 5 | 6 | import java.util.List; 7 | import java.util.stream.Stream; 8 | 9 | import static java.util.stream.Collectors.toList; 10 | 11 | public class Question1 { 12 | public static int addUp(Stream numbers) { 13 | return numbers.reduce(0, (acc, x) -> acc + x); 14 | } 15 | 16 | public static List getNamesAndOrigins(List artists) { 17 | return artists.stream() 18 | .flatMap(artist -> Stream.of(artist.getName(), artist.getNationality())) 19 | .collect(toList()); 20 | } 21 | 22 | public static List getAlbumsWithAtMostThreeTracks(List input) { 23 | return input.stream() 24 | .filter(album -> album.getTrackList().size() <= 3) 25 | .collect(toList()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/OrderDomain.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | 4 | import com.insightfullogic.java8.examples.chapter1.Album; 5 | 6 | import java.util.List; 7 | import java.util.function.ToLongFunction; 8 | 9 | public class OrderDomain extends Order { 10 | 11 | public OrderDomain(List albums) { 12 | super(albums); 13 | } 14 | 15 | // BEGIN body 16 | public long countFeature(ToLongFunction function) { 17 | return albums.stream() 18 | .mapToLong(function) 19 | .sum(); 20 | } 21 | 22 | public long countTracks() { 23 | return countFeature(album -> album.getTracks().count()); 24 | } 25 | 26 | public long countRunningTime() { 27 | return countFeature(album -> album.getTracks() 28 | .mapToLong(track -> track.getLength()) 29 | .sum()); 30 | } 31 | 32 | public long countMusicians() { 33 | return countFeature(album -> album.getMusicians().count()); 34 | } 35 | // END body 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter9/CallbackArtistAnalyser.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.function.Consumer; 6 | import java.util.function.Function; 7 | 8 | public class CallbackArtistAnalyser implements ArtistAnalyzer { 9 | 10 | private final Function artistLookupService; 11 | 12 | public CallbackArtistAnalyser(Function artistLookupService) { 13 | this.artistLookupService = artistLookupService; 14 | } 15 | 16 | public void isLargerGroup(String artistName, String otherArtistName, Consumer handler) { 17 | boolean isLarger = getNumberOfMembers(artistName) > getNumberOfMembers(otherArtistName); 18 | handler.accept(isLarger); 19 | } 20 | 21 | private long getNumberOfMembers(String artistName) { 22 | return artistLookupService.apply(artistName) 23 | .getMembers() 24 | .count(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter4/Artists.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.List; 6 | 7 | public class Artists { 8 | 9 | private List artists; 10 | 11 | public Artists(List artists) { 12 | this.artists = artists; 13 | } 14 | 15 | public Artist getArtist(int index) { 16 | if (index < 0 || index >= artists.size()) { 17 | indexException(index); 18 | } 19 | return artists.get(index); 20 | } 21 | 22 | private void indexException(int index) { 23 | throw new IllegalArgumentException(index + 24 | " doesn't correspond to an Artist"); 25 | } 26 | 27 | public String getArtistName(int index) { 28 | try { 29 | Artist artist = getArtist(index); 30 | return artist.getName(); 31 | } catch (IllegalArgumentException e) { 32 | return "unknown"; 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter5/LongestName.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.Comparator; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | 9 | import static java.util.Comparator.comparing; 10 | 11 | public class LongestName { 12 | 13 | private static Comparator byNameLength = comparing(artist -> artist.getName().length()); 14 | 15 | public static Artist byReduce(List artists) { 16 | return artists.stream() 17 | .reduce((acc, artist) -> { 18 | return (byNameLength.compare(acc, artist) >= 0) ? acc : artist; 19 | }) 20 | .orElseThrow(RuntimeException::new); 21 | } 22 | 23 | public static Artist byCollecting(List artists) { 24 | return artists.stream() 25 | .collect(Collectors.maxBy(byNameLength)) 26 | .orElseThrow(RuntimeException::new); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/template_method/lambdas/LoanApplication.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.template_method.lambdas; 2 | 3 | import com.insightfullogic.java8.examples.chapter8.template_method.ApplicationDenied; 4 | 5 | // BEGIN LoanApplication 6 | public class LoanApplication { 7 | 8 | private final Criteria identity; 9 | private final Criteria creditHistory; 10 | private final Criteria incomeHistory; 11 | 12 | public LoanApplication(Criteria identity, 13 | Criteria creditHistory, 14 | Criteria incomeHistory) { 15 | 16 | this.identity = identity; 17 | this.creditHistory = creditHistory; 18 | this.incomeHistory = incomeHistory; 19 | } 20 | 21 | public void checkLoanApplication() throws ApplicationDenied { 22 | identity.check(); 23 | creditHistory.check(); 24 | incomeHistory.check(); 25 | reportFindings(); 26 | } 27 | 28 | private void reportFindings() { 29 | // END LoanApplication 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/example/StackSpec.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.example; 2 | 3 | import java.util.Stack; 4 | 5 | import static com.insightfullogic.java8.examples.chapter8.lambdabehave.Lets.describe; 6 | 7 | // BEGIN StackSpec 8 | public class StackSpec {{ 9 | 10 | describe("a stack", it -> { 11 | 12 | it.should("be empty when created", expect -> { 13 | expect.that(new Stack()).isEmpty(); 14 | }); 15 | 16 | it.should("push new elements onto the top of the stack", expect -> { 17 | Stack stack = new Stack<>(); 18 | stack.push(1); 19 | 20 | expect.that(stack.get(0)).isEqualTo(1); 21 | }); 22 | 23 | it.should("pop the last element pushed onto the stack", expect -> { 24 | Stack stack = new Stack<>(); 25 | stack.push(2); 26 | stack.push(1); 27 | 28 | expect.that(stack.pop()).isEqualTo(2); 29 | }); 30 | 31 | }); 32 | 33 | }} 34 | // END StackSpec 35 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/reporting/ConsoleFormatter.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.reporting; 2 | 3 | import java.io.PrintStream; 4 | 5 | public class ConsoleFormatter implements ReportFormatter { 6 | 7 | @Override 8 | public void format(Report report) { 9 | report.suites().forEach(suite -> { 10 | System.out.print(suite.getName()); 11 | System.out.println(); 12 | suite.specifications().forEach(this::printSpecification); 13 | }); 14 | } 15 | 16 | private void printSpecification(SpecificationReport specification) { 17 | boolean isSuccess = specification.getResult() == Result.SUCCESS; 18 | PrintStream out = isSuccess ? System.out : System.err; 19 | 20 | out.print("\tshould "); 21 | out.print(specification.getDescription()); 22 | if (!isSuccess) { 23 | out.print("["); 24 | out.print(specification.getMessage()); 25 | out.print("]"); 26 | } 27 | out.println(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter1/Chapter1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package com.insightfullogic.java8.examples.chapter1; 7 | 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | /** 12 | * 13 | * @author richard 14 | */ 15 | public class Chapter1 extends MusicChapter { 16 | 17 | public List getNamesOfArtists_Lambda() { 18 | return artists.stream() 19 | .map(artist -> artist.getName()) 20 | .collect(Collectors.toList()); 21 | } 22 | 23 | public List getNamesOfArtists_MethodReference() { 24 | return artists.stream() 25 | .map(Artist::getName) 26 | .collect(Collectors.toList()); 27 | } 28 | 29 | public List artistsLivingInLondon() { 30 | return artists.stream() 31 | .filter(artist -> "London".equals(artist.getNationality())) 32 | .collect(Collectors.toList()); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/OrderImperative.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | 4 | import com.insightfullogic.java8.examples.chapter1.Album; 5 | import com.insightfullogic.java8.examples.chapter1.Track; 6 | 7 | import java.util.List; 8 | 9 | public class OrderImperative extends Order { 10 | 11 | public OrderImperative(List albums) { 12 | super(albums); 13 | } 14 | 15 | // BEGIN body 16 | public long countRunningTime() { 17 | long count = 0; 18 | for (Album album : albums) { 19 | for (Track track : album.getTrackList()) { 20 | count += track.getLength(); 21 | } 22 | } 23 | return count; 24 | } 25 | 26 | public long countMusicians() { 27 | long count = 0; 28 | for (Album album : albums) { 29 | count += album.getMusicianList().size(); 30 | } 31 | return count; 32 | } 33 | 34 | public long countTracks() { 35 | long count = 0; 36 | for (Album album : albums) { 37 | count += album.getTrackList().size(); 38 | } 39 | return count; 40 | } 41 | // END body 42 | 43 | } 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014 Richard Warburton 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter7/OrderDomainExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter7; 2 | 3 | import com.insightfullogic.java8.examples.chapter4.OrderDomain; 4 | import com.insightfullogic.java8.examples.chapter1.Album; 5 | import org.junit.Test; 6 | 7 | import static java.util.Arrays.asList; 8 | import static java.util.Collections.emptyList; 9 | import static org.junit.Assert.assertEquals; 10 | 11 | /** 12 | * Sample code for chapter7 OrderDomain from the 13 | * previous chapter. 14 | */ 15 | public class OrderDomainExampleTest { 16 | 17 | // BEGIN can_count_albums 18 | @Test 19 | public void canCountFeatures() { 20 | OrderDomain order = new OrderDomain(asList( 21 | newAlbum("Exile on Main St."), 22 | newAlbum("Beggars Banquet"), 23 | newAlbum("Aftermath"), 24 | newAlbum("Let it Bleed"))); 25 | 26 | assertEquals(8, order.countFeature(album -> 2)); 27 | } 28 | // END can_count_albums 29 | 30 | private Album newAlbum(String name) { 31 | return new Album(name, emptyList(), emptyList()); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/reporting/Report.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave.reporting; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Stream; 6 | 7 | public final class Report { 8 | 9 | private final List suites; 10 | 11 | private SuiteReport currentSuite; 12 | 13 | public Report() { 14 | suites = new ArrayList<>(); 15 | } 16 | 17 | private void newSuite(String name) { 18 | currentSuite = new SuiteReport(name); 19 | suites.add(currentSuite); 20 | } 21 | 22 | public void newSpecification(String suiteName, SpecificationReport report) { 23 | if (noSuite() || seenNewSuite(suiteName)) { 24 | newSuite(suiteName); 25 | } 26 | currentSuite.add(report); 27 | } 28 | 29 | private boolean seenNewSuite(String suite) { 30 | return !currentSuite.getName().equals(suite); 31 | } 32 | 33 | private boolean noSuite() { 34 | return currentSuite == null; 35 | } 36 | 37 | public Stream suites() { 38 | return suites.stream(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter3/StreamExercisesTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.SampleData; 4 | 5 | import org.junit.Test; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.stream.Stream; 10 | 11 | import static com.insightfullogic.java8.examples.chapter3.StreamExercises.*; 12 | import static org.junit.Assert.assertEquals; 13 | 14 | public class StreamExercisesTest { 15 | 16 | @Test 17 | public void external() { 18 | assertEquals(4, countBandMembersExternal(Arrays.asList(SampleData.johnColtrane, SampleData.theBeatles))); 19 | } 20 | 21 | 22 | 23 | @Test 24 | public void mapExample() { 25 | Stream stream = Stream.of(1, 2, 3); 26 | List values = StreamExercises.map(stream, x -> x + 1); 27 | assertEquals(Arrays.asList(2, 3, 4), values); 28 | } 29 | 30 | @Test 31 | public void mapExampleParallel() { 32 | Stream parallelStream = Stream.of(1, 2, 3).parallel(); 33 | List values = StreamExercises.map(parallelStream, x -> x + 1); 34 | assertEquals(Arrays.asList(2, 3, 4), values); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter4/ArtistsTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import static junit.framework.Assert.assertEquals; 9 | import static junit.framework.Assert.assertNotNull; 10 | 11 | public class ArtistsTest { 12 | 13 | private final Artists optionalExamples = new Artists(SampleData.getThreeArtists()); 14 | 15 | @Test 16 | public void indexWithinRange() { 17 | Artist artist = optionalExamples.getArtist(0); 18 | assertNotNull(artist); 19 | } 20 | 21 | @Test(expected = IllegalArgumentException.class) 22 | public void indexOutsideRange() { 23 | optionalExamples.getArtist(4); 24 | } 25 | 26 | @Test 27 | public void nameIndexInsideRange() { 28 | String artist = optionalExamples.getArtistName(0); 29 | Assert.assertEquals("John Coltrane", artist); 30 | } 31 | 32 | @Test 33 | public void nameIndexOutsideRange() { 34 | String artist = optionalExamples.getArtistName(4); 35 | assertEquals("unknown", artist); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter3/MapUsingReduce.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.function.Function; 6 | import java.util.stream.Stream; 7 | 8 | /** 9 | * Advanced Exercises Question 1 10 | */ 11 | public class MapUsingReduce { 12 | 13 | public static List map(Stream stream, Function mapper) { 14 | return stream.reduce(new ArrayList(), (acc, x) -> { 15 | // We are copying data from acc to new list instance. It is very inefficient, 16 | // but contract of Stream.reduce method requires that accumulator function does 17 | // not mutate its arguments. 18 | // Stream.collect method could be used to implement more efficient mutable reduction, 19 | // but this exercise asks to use reduce method. 20 | List newAcc = new ArrayList<>(acc); 21 | newAcc.add(mapper.apply(x)); 22 | return newAcc; 23 | }, (List left, List right) -> { 24 | // We are copying left to new list to avoid mutating it. 25 | List newLeft = new ArrayList<>(left); 26 | newLeft.addAll(right); 27 | return newLeft; 28 | }); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter4/Logger.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | import java.util.function.Supplier; 4 | 5 | public class Logger { 6 | 7 | private boolean debug = true; 8 | 9 | public boolean isDebugEnabled() { 10 | return debug; 11 | } 12 | 13 | public void debug(String message) { 14 | if (isDebugEnabled()) { 15 | System.out.println(message); 16 | } 17 | } 18 | 19 | public void example() { 20 | // BEGIN debug_optimised 21 | Logger logger = new Logger(); 22 | if (logger.isDebugEnabled()) { 23 | logger.debug("Look at this: " + expensiveOperation()); 24 | } 25 | // END debug_optimised 26 | } 27 | 28 | private String expensiveOperation() { 29 | return ""; 30 | } 31 | 32 | // BEGIN debug_lambda 33 | public void debug(Supplier message) { 34 | if (isDebugEnabled()) { 35 | debug(message.get()); 36 | } 37 | } 38 | // END debug_lambda 39 | 40 | public void exampleWithLambda() { 41 | // BEGIN debug_optimised_lambda 42 | Logger logger = new Logger(); 43 | logger.debug(() -> "Look at this: " + expensiveOperation()); 44 | // END debug_optimised_lambda 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter3/MapUsingReduceTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import static java.util.Arrays.asList; 4 | import static org.junit.Assert.assertEquals; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.function.Function; 9 | 10 | import org.junit.Test; 11 | 12 | public class MapUsingReduceTest { 13 | 14 | @Test 15 | public void emptyList() { 16 | assertMapped(Function.identity(), Collections.emptyList(), Collections.emptyList()); 17 | } 18 | 19 | @Test 20 | public void identityMapsToItself() { 21 | assertMapped((Integer x) -> x, asList(1, 2, 3), asList(1, 2, 3)); 22 | } 23 | 24 | @Test 25 | public void incrementingNumbers() { 26 | assertMapped((Integer x) -> x + 2, asList(1, 2, 3), asList(3, 4, 5)); 27 | } 28 | 29 | private void assertMapped(Function mapper, List input, List expectedOutput) { 30 | List output = MapUsingReduce.map(input.stream(), mapper); 31 | assertEquals(expectedOutput, output); 32 | 33 | List parallelOutput = MapUsingReduce.map(input.parallelStream(), mapper); 34 | assertEquals(expectedOutput, parallelOutput); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter3/MapUsingReduceTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import static java.util.Arrays.asList; 4 | import static org.junit.Assert.assertEquals; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.function.Function; 9 | 10 | import org.junit.Test; 11 | 12 | public class MapUsingReduceTest { 13 | 14 | @Test 15 | public void emptyList() { 16 | assertMapped(Function.identity(), Collections.emptyList(), Collections.emptyList()); 17 | } 18 | 19 | @Test 20 | public void identityMapsToItself() { 21 | assertMapped((Integer x) -> x, asList(1, 2, 3), asList(1, 2, 3)); 22 | } 23 | 24 | @Test 25 | public void incrementingNumbers() { 26 | assertMapped((Integer x) -> x + 2, asList(1, 2, 3), asList(3, 4, 5)); 27 | } 28 | 29 | private void assertMapped(Function mapper, List input, List expectedOutput) { 30 | List output = MapUsingReduce.map(input.stream(), mapper); 31 | assertEquals(expectedOutput, output); 32 | 33 | List parallelOutput = MapUsingReduce.map(input.parallelStream(), mapper); 34 | assertEquals(expectedOutput, parallelOutput); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter6/ArrayExamplesTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter6; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.junit.runners.Parameterized; 6 | 7 | import java.util.Arrays; 8 | import java.util.Collection; 9 | 10 | import static org.junit.Assert.assertArrayEquals; 11 | 12 | @RunWith(value = Parameterized.class) 13 | public class ArrayExamplesTest { 14 | 15 | @Parameterized.Parameters 16 | public static Collection data() { 17 | Object[][] data = new Object[][] { 18 | { 0, new double[]{} }, 19 | { 2, new double[]{0, 1} }, 20 | { 4, new double[]{0, 1, 2, 3} } 21 | }; 22 | return Arrays.asList(data); 23 | } 24 | 25 | private final int size; 26 | private final double[] output; 27 | 28 | public ArrayExamplesTest(int size, double[] output) { 29 | this.size = size; 30 | this.output = output; 31 | } 32 | 33 | @Test 34 | public void parallel() { 35 | assertArrayEquals(output, ArrayExamples.parallelInitialize(size), 0.0); 36 | } 37 | 38 | @Test 39 | public void imperative() { 40 | assertArrayEquals(output, ArrayExamples.imperativeInitilize(size), 0.0); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/MethodReferences.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.Artist; 5 | 6 | import java.io.IOException; 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.regex.Pattern; 12 | import java.util.stream.Stream; 13 | 14 | import static com.insightfullogic.java8.examples.chapter5.CollectorExamples.countWords; 15 | import static java.nio.charset.Charset.defaultCharset; 16 | import static java.util.stream.Collectors.groupingBy; 17 | 18 | public class MethodReferences { 19 | 20 | public Map> albumsByArtist(Stream albums) { 21 | return albums.collect(groupingBy(Album::getMainMusician)); 22 | } 23 | 24 | private static final Pattern SPACES = Pattern.compile("\\w+"); 25 | 26 | public static Map countWordsIn(Path path) throws IOException { 27 | Stream words = Files.readAllLines(path, defaultCharset()) 28 | .stream() 29 | .flatMap(SPACES::splitAsStream); 30 | 31 | return countWords(words); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter3/StringExercisesTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.Collections; 7 | import java.util.Optional; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | import static org.junit.Assert.assertFalse; 11 | 12 | public class StringExercisesTest { 13 | 14 | @Test 15 | public void noLowercaseLettersInAnEmptyString() { 16 | assertEquals(0, StringExercises.countLowercaseLetters("")); 17 | } 18 | 19 | @Test 20 | public void countsLowercaseLetterExample() { 21 | assertEquals(3, StringExercises.countLowercaseLetters("aBcDeF")); 22 | } 23 | 24 | @Test 25 | public void suppoertsNoLowercaseLetters() { 26 | assertEquals(0, StringExercises.countLowercaseLetters("ABCDEF")); 27 | } 28 | 29 | @Test 30 | public void noStringReturnedForEmptyList() { 31 | assertFalse(StringExercises.mostLowercaseString(Collections.emptyList()).isPresent()); 32 | } 33 | 34 | @Test 35 | public void findsMostLowercaseString() { 36 | Optional result = StringExercises.mostLowercaseString(Arrays.asList("a", "abc", "ABCde")); 37 | assertEquals(result, Optional.of("abc")); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter4/TestDefaultSubClassing.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class TestDefaultSubClassing { 8 | 9 | // BEGIN parent_default_used 10 | @Test 11 | public void parentDefaultUsed() { 12 | Parent parent = new ParentImpl(); 13 | parent.welcome(); 14 | assertEquals("Parent: Hi!", parent.getLastMessage()); 15 | } 16 | // END parent_default_used 17 | 18 | // BEGIN child_override_default 19 | @Test 20 | public void childOverrideDefault() { 21 | Child child = new ChildImpl(); 22 | child.welcome(); 23 | assertEquals("Child: Hi!", child.getLastMessage()); 24 | } 25 | // END child_override_default 26 | 27 | // BEGIN concrete_beats_default 28 | @Test 29 | public void concreteBeatsDefault() { 30 | Parent parent = new OverridingParent(); 31 | parent.welcome(); 32 | assertEquals("Class Parent: Hi!", parent.getLastMessage()); 33 | } 34 | // END concrete_beats_default 35 | 36 | // BEGIN concrete_beats_closer_default 37 | @Test 38 | public void concreteBeatsCloserDefault() { 39 | Child child = new OverridingChild(); 40 | child.welcome(); 41 | assertEquals("Class Parent: Hi!", child.getLastMessage()); 42 | } 43 | // END concrete_beats_closer_default 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/command/MacrosTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.command; 2 | 3 | import org.junit.Test; 4 | 5 | public class MacrosTest { 6 | 7 | @Test 8 | public void classBasedCommand() { 9 | MockEditor editor = new MockEditor(); 10 | 11 | // BEGIN classBasedCommand 12 | Macro macro = new Macro(); 13 | macro.record(new Open(editor)); 14 | macro.record(new Save(editor)); 15 | macro.record(new Close(editor)); 16 | macro.run(); 17 | // END classBasedCommand 18 | 19 | editor.check(); 20 | } 21 | 22 | @Test 23 | public void lambdaBasedCommand() { 24 | MockEditor editor = new MockEditor(); 25 | 26 | // BEGIN lambdaBasedCommand 27 | Macro macro = new Macro(); 28 | macro.record(() -> editor.open()); 29 | macro.record(() -> editor.save()); 30 | macro.record(() -> editor.close()); 31 | macro.run(); 32 | // END lambdaBasedCommand 33 | 34 | editor.check(); 35 | } 36 | 37 | @Test 38 | public void referenceBasedCommand() { 39 | MockEditor editor = new MockEditor(); 40 | 41 | // BEGIN referenceBasedCommand 42 | Macro macro = new Macro(); 43 | macro.record(editor::open); 44 | macro.record(editor::save); 45 | macro.record(editor::close); 46 | macro.run(); 47 | // END referenceBasedCommand 48 | 49 | editor.check(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter4/PerformanceTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import org.junit.Test; 6 | 7 | import java.util.List; 8 | import java.util.stream.Stream; 9 | 10 | import static java.util.stream.Collectors.toList; 11 | import static org.hamcrest.Matchers.hasItem; 12 | import static org.hamcrest.Matchers.hasItems; 13 | import static org.junit.Assert.assertThat; 14 | 15 | public class PerformanceTest { 16 | 17 | @Test 18 | public void findsAllTheBeatles() { 19 | PerformanceFixed stub = new PerformanceFixed() { 20 | @Override 21 | public String getName() { 22 | throw new UnsupportedOperationException(); 23 | } 24 | 25 | @Override 26 | public Stream getMusicians() { 27 | return Stream.of(SampleData.theBeatles); 28 | } 29 | }; 30 | 31 | List allMusicians = stub.getAllMusicians().collect(toList()); 32 | assertThat(allMusicians, hasItem(SampleData.theBeatles)); 33 | // There really must be a better way than this 34 | assertThat(allMusicians, hasItems(SampleData.membersOfTheBeatles.toArray(new Artist[0]))); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | java-8-lambdas-exercises 2 | ======================== 3 | 4 | This git repository contains support material for the [Java 8 Lambdas](https://www.oreilly.com/library/view/java-8-lambdas/9781449370831/) book. 5 | 6 | Project Structure 7 | ----------------- 8 | 9 | The overall code layout is: 10 | 11 | * Code is in `src/main/java` 12 | * Tests are in `src/test/java` 13 | 14 | Within these directories things are organised by package: 15 | 16 | * Exercises which involve code in `com.insightfullogic.java8.exercises` 17 | * Answers are in `com.insightfullogic.java8.answers` Coding questions are all in the form of failing tests, and the package-info.java 18 | contains the correct answer to questions which don't involve writing code, such as yes/no questions. For example here are the chapter 2 answers: 19 | https://github.com/RichardWarburton/java-8-lambdas-exercises/blob/master/src/main/java/com/insightfullogic/java8/answers/chapter2/package-info.java 20 | * Code Examples/Listings are in `com.insightfullogic.java8.examples` 21 | 22 | The sub-packages then correspond to the chapter number, so the examples for chapter 4 are in 23 | `com.insightfullogic.java8.examples.chapter4`. 24 | 25 | Reporting Issues 26 | ---------------- 27 | 28 | If you find any issues with the exercises or examples then please submit them via the 29 | [O'Reilly Errata Page](http://www.oreilly.com/catalog/errata.csp?isbn=0636920030713). 30 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter4/ArtistsTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import java.util.Optional; 9 | 10 | import static junit.framework.Assert.assertEquals; 11 | import static junit.framework.TestCase.assertTrue; 12 | import static org.junit.Assert.assertFalse; 13 | 14 | public class ArtistsTest { 15 | 16 | private final ArtistsFixed optionalExamples = new ArtistsFixed(SampleData.getThreeArtists()); 17 | 18 | @Test 19 | public void indexWithinRange() { 20 | Optional artist = optionalExamples.getArtist(0); 21 | assertTrue(artist.isPresent()); 22 | } 23 | 24 | @Test 25 | public void indexOutsideRange() { 26 | Optional artist = optionalExamples.getArtist(4); 27 | assertFalse(artist.isPresent()); 28 | } 29 | 30 | @Test 31 | public void nameIndexInsideRange() { 32 | String artist = optionalExamples.getArtistName(0); 33 | Assert.assertEquals("John Coltrane", artist); 34 | } 35 | 36 | @Test 37 | public void nameIndexOutsideRange() { 38 | String artist = optionalExamples.getArtistName(4); 39 | assertEquals("unknown", artist); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter6/ArrayExamples.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter6; 2 | 3 | import java.util.Arrays; 4 | import java.util.stream.IntStream; 5 | 6 | public class ArrayExamples { 7 | 8 | // BEGIN simpleMovingAverage 9 | public static double[] simpleMovingAverage(double[] values, int n) { 10 | double[] sums = Arrays.copyOf(values, values.length); // <1> 11 | Arrays.parallelPrefix(sums, Double::sum); // <2> 12 | int start = n - 1; 13 | return IntStream.range(start, sums.length) // <3> 14 | .mapToDouble(i -> { 15 | double prefix = i == start ? 0 : sums[i - n]; 16 | return (sums[i] - prefix) / n; // <4> 17 | }) 18 | .toArray(); // <5> 19 | } 20 | // END simpleMovingAverage 21 | 22 | // BEGIN parallelInitialize 23 | public static double[] parallelInitialize(int size) { 24 | double[] values = new double[size]; 25 | Arrays.parallelSetAll(values, i -> i); 26 | return values; 27 | } 28 | // END parallelInitialize 29 | 30 | // BEGIN imperativeInitilize 31 | public static double[] imperativeInitilize(int size) { 32 | double[] values = new double[size]; 33 | for(int i = 0; i < values.length;i++) { 34 | values[i] = i; 35 | } 36 | return values; 37 | } 38 | // END imperativeInitilize 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter9/CompletableFutureArtistAnalyser.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.concurrent.CompletableFuture; 6 | import java.util.function.Consumer; 7 | import java.util.function.Function; 8 | 9 | public class CompletableFutureArtistAnalyser implements ArtistAnalyzer { 10 | 11 | private final Function artistLookupService; 12 | 13 | public CompletableFutureArtistAnalyser(Function artistLookupService) { 14 | this.artistLookupService = artistLookupService; 15 | } 16 | 17 | public void isLargerGroup(String artistName, String otherArtistName, Consumer handler) { 18 | CompletableFuture otherArtistMemberCount = CompletableFuture.supplyAsync(() -> getNumberOfMembers(otherArtistName)); 19 | 20 | CompletableFuture artistMemberCount = CompletableFuture.completedFuture(getNumberOfMembers(artistName)); 21 | 22 | artistMemberCount.thenCombine(otherArtistMemberCount, (count, otherCount) -> count > otherCount) 23 | .thenAccept(handler::accept); 24 | } 25 | 26 | private long getNumberOfMembers(String artistName) { 27 | return artistLookupService.apply(artistName) 28 | .getMembers() 29 | .count(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter3/FilterUsingReduceTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import static java.util.Arrays.asList; 4 | import static org.junit.Assert.assertEquals; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.function.Predicate; 9 | 10 | import org.junit.Test; 11 | 12 | public class FilterUsingReduceTest { 13 | 14 | @Test 15 | public void emptyList() { 16 | assertFiltered(x -> false, Collections.emptyList(), Collections.emptyList()); 17 | } 18 | 19 | @Test 20 | public void trueReturnsEverything() { 21 | assertFiltered((Integer x) -> true, asList(1, 2, 3), asList(1, 2, 3)); 22 | } 23 | 24 | @Test 25 | public void falseRemovesEverything() { 26 | assertFiltered((Integer x) -> false, asList(1, 2, 3), asList()); 27 | } 28 | 29 | @Test 30 | public void filterPartOfList() { 31 | assertFiltered((Integer x) -> x > 2, asList(1, 2, 3), asList(3)); 32 | } 33 | 34 | private void assertFiltered(Predicate predicate, List input, List expectedOutput) { 35 | List output = FilterUsingReduce.filter(input.stream(), predicate); 36 | assertEquals(expectedOutput, output); 37 | 38 | List parallelOutput = FilterUsingReduce.filter(input.parallelStream(), predicate); 39 | assertEquals(expectedOutput, parallelOutput); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/DependencyInversionPrincipleTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.junit.runners.Parameterized; 6 | 7 | import java.io.InputStreamReader; 8 | import java.util.Collection; 9 | import java.util.List; 10 | 11 | import static com.insightfullogic.java8.examples.chapter8.DependencyInversionPrinciple.HeadingFinder; 12 | import static java.util.Arrays.asList; 13 | import static org.junit.Assert.assertEquals; 14 | 15 | @RunWith(Parameterized.class) 16 | public class DependencyInversionPrincipleTest { 17 | 18 | 19 | private final HeadingFinder finder; 20 | 21 | @Parameterized.Parameters 22 | public static Collection data() { 23 | Object[][] data = new Object[][]{{new DependencyInversionPrinciple.NoDIP()}, {new DependencyInversionPrinciple.ExtractedDIP()}}; 24 | return asList(data); 25 | } 26 | 27 | public DependencyInversionPrincipleTest(HeadingFinder finder) { 28 | this.finder = finder; 29 | } 30 | 31 | @Test 32 | public void correctHeadings() { 33 | InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("test_file")); 34 | List headings = finder.findHeadings(reader); 35 | assertEquals(asList("Improve Content", "Cleanup", "Add Content", "Add to Streams Chapter"), headings); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter3/FilterUsingReduceTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import static java.util.Arrays.asList; 4 | import static org.junit.Assert.assertEquals; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.function.Predicate; 9 | 10 | import org.junit.Test; 11 | 12 | public class FilterUsingReduceTest { 13 | 14 | @Test 15 | public void emptyList() { 16 | assertFiltered(x -> false, Collections.emptyList(), Collections.emptyList()); 17 | } 18 | 19 | @Test 20 | public void trueReturnsEverything() { 21 | assertFiltered((Integer x) -> true, asList(1, 2, 3), asList(1, 2, 3)); 22 | } 23 | 24 | @Test 25 | public void falseRemovesEverything() { 26 | assertFiltered((Integer x) -> false, asList(1, 2, 3), asList()); 27 | } 28 | 29 | @Test 30 | public void filterPartOfList() { 31 | assertFiltered((Integer x) -> x > 2, asList(1, 2, 3), asList(3)); 32 | } 33 | 34 | private void assertFiltered(Predicate predicate, List input, List expectedOutput) { 35 | List output = FilterUsingReduce.filter(input.stream(), predicate); 36 | assertEquals(expectedOutput, output); 37 | 38 | List parallelOutput = FilterUsingReduce.filter(input.parallelStream(), predicate); 39 | assertEquals(expectedOutput, parallelOutput); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter5/GroupingBy.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter5; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | 5 | import java.util.*; 6 | import java.util.function.BiConsumer; 7 | import java.util.function.BinaryOperator; 8 | import java.util.function.Function; 9 | import java.util.function.Supplier; 10 | import java.util.stream.Collector; 11 | 12 | public class GroupingBy implements Collector>, Map>> { 13 | 14 | private final Function classifier; 15 | 16 | public GroupingBy(Function classifier) { 17 | this.classifier = classifier; 18 | } 19 | 20 | @Override 21 | public Supplier>> supplier() { 22 | return Exercises.replaceThisWithSolution(); 23 | } 24 | 25 | @Override 26 | public BiConsumer>, T> accumulator() { 27 | return Exercises.replaceThisWithSolution(); 28 | } 29 | 30 | @Override 31 | public BinaryOperator>> combiner() { 32 | return Exercises.replaceThisWithSolution(); 33 | } 34 | 35 | @Override 36 | public Function>, Map>> finisher() { 37 | return Exercises.replaceThisWithSolution(); 38 | } 39 | 40 | @Override 41 | public Set characteristics() { 42 | return Exercises.replaceThisWithSolution(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter4/PerformanceTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import com.insightfullogic.java8.answers.chapter4.PerformanceFixed; 6 | import org.junit.Test; 7 | 8 | import java.util.List; 9 | import java.util.stream.Stream; 10 | 11 | import static java.util.stream.Collectors.toList; 12 | import static org.hamcrest.Matchers.hasItem; 13 | import static org.hamcrest.Matchers.hasItems; 14 | import static org.junit.Assert.assertThat; 15 | 16 | public class PerformanceTest { 17 | 18 | @Test 19 | public void findsAllTheBeatles() { 20 | com.insightfullogic.java8.answers.chapter4.PerformanceFixed stub = new PerformanceFixed() { 21 | @Override 22 | public String getName() { 23 | throw new UnsupportedOperationException(); 24 | } 25 | 26 | @Override 27 | public Stream getMusicians() { 28 | return Stream.of(SampleData.theBeatles); 29 | } 30 | }; 31 | 32 | List allMusicians = stub.getAllMusicians().collect(toList()); 33 | assertThat(allMusicians, hasItem(SampleData.theBeatles)); 34 | // There really must be a better way than this 35 | assertThat(allMusicians, hasItems(SampleData.membersOfTheBeatles.toArray(new Artist[0]))); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter3/StreamExercises.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.function.Function; 8 | import java.util.stream.Stream; 9 | 10 | public class StreamExercises { 11 | 12 | // Q3 13 | public static int countBandMembersExternal(List artists) { 14 | // BEGIN COUNT_MEMBERS_EXTERNAL 15 | int totalMembers = 0; 16 | for (Artist artist : artists) { 17 | Stream members = artist.getMembers(); 18 | totalMembers += members.count(); 19 | } 20 | // END COUNT_MEMBERS_EXTERNAL 21 | 22 | return totalMembers; 23 | } 24 | 25 | // map f = foldr ((:) . f) [] 26 | // Advanced Exercise 27 | public static List map(Stream stream, Function mapper) { 28 | return stream.reduce(new ArrayList<>(), (acc, value) -> { 29 | // Make copy of list (modifying acc would violate contract of reduce method) 30 | ArrayList result = new ArrayList<>(); 31 | result.addAll(acc); 32 | result.add(mapper.apply(value)); 33 | return result; 34 | }, (left, right) -> { 35 | ArrayList result = new ArrayList<>(); 36 | result.addAll(left); 37 | result.addAll(right); 38 | return result; 39 | }); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/mutable_custom/AlbumSalesCollector.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5.mutable_custom; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | import java.util.function.BiConsumer; 6 | import java.util.function.BinaryOperator; 7 | import java.util.function.Function; 8 | import java.util.function.Supplier; 9 | import java.util.stream.Collector; 10 | 11 | public class AlbumSalesCollector implements Collector { 12 | 13 | private static final Set characteristics = new HashSet<>(); 14 | static { 15 | characteristics.add(Characteristics.UNORDERED); 16 | characteristics.add(Characteristics.IDENTITY_FINISH); 17 | } 18 | 19 | @Override 20 | public Supplier supplier() { 21 | return AlbumSalesReport::new; 22 | } 23 | 24 | @Override 25 | public BiConsumer accumulator() { 26 | return (report, album) -> report.acknowledgeSale(album); 27 | } 28 | 29 | @Override 30 | public BinaryOperator combiner() { 31 | return (left, right) -> left.merge(right); 32 | } 33 | 34 | @Override 35 | public Function finisher() { 36 | return Function.identity(); 37 | } 38 | 39 | @Override 40 | public Set characteristics() { 41 | return characteristics; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/StringCombiner.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5; 2 | 3 | public class StringCombiner { 4 | 5 | private final String prefix; 6 | private final String suffix; 7 | private final String delim; 8 | private final StringBuilder buIlder; 9 | 10 | public StringCombiner(String delim, String prefix, String suffix) { 11 | this.prefix = prefix; 12 | this.suffix = suffix; 13 | this.delim = delim; 14 | this.buIlder = new StringBuilder(); 15 | } 16 | 17 | // BEGIN add 18 | public StringCombiner add (String word) { 19 | if(!this.areAtStart()) { 20 | this.buIlder.append(delim); 21 | } 22 | this.buIlder.append(word); 23 | 24 | return this; 25 | } 26 | // END add 27 | 28 | // BEGIN merge 29 | public StringCombiner merge (StringCombiner other) { 30 | if(!other.equals(this)) { 31 | if(!other.areAtStart() && !this.areAtStart()){ 32 | other.buIlder.insert(0, this.delim); 33 | } 34 | this.buIlder.append(other.buIlder); 35 | } 36 | return this; 37 | } 38 | // END merge 39 | 40 | // BEGIN toString 41 | @Override 42 | public String toString() { 43 | return prefix + buIlder.toString() + suffix; 44 | } 45 | // END toString 46 | 47 | // BEGIN areAtStart 48 | private boolean areAtStart() { 49 | return buIlder.length() == 0; 50 | } 51 | // END areAtStart 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/observer/Moon.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.observer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | // BEGIN Moon 7 | public class Moon { 8 | 9 | private final List observers = new ArrayList<>(); 10 | 11 | public void land(String name) { 12 | for (LandingObserver observer : observers) { 13 | observer.observeLanding(name); 14 | } 15 | } 16 | 17 | public void startSpying(LandingObserver observer) { 18 | observers.add(observer); 19 | } 20 | // END Moon 21 | 22 | public static void main(String[] args) { 23 | classBasedExample(); 24 | lambdaBasedExample(); 25 | } 26 | 27 | private static void classBasedExample() { 28 | // BEGIN classBasedExample 29 | Moon moon = new Moon(); 30 | moon.startSpying(new Nasa()); 31 | moon.startSpying(new Aliens()); 32 | 33 | moon.land("An asteroid"); 34 | moon.land("Apollo 11"); 35 | // END classBasedExample 36 | } 37 | 38 | private static void lambdaBasedExample() { 39 | // BEGIN lambdaBasedExample 40 | Moon moon = new Moon(); 41 | 42 | moon.startSpying(name -> { 43 | if (name.contains("Apollo")) 44 | System.out.println("We made it!"); 45 | }); 46 | 47 | moon.startSpying(name -> { 48 | if (name.contains("Apollo")) 49 | System.out.println("They're distracted, lets invade earth!"); 50 | }); 51 | 52 | moon.land("An asteroid"); 53 | moon.land("Apollo 11"); 54 | // END lambdaBasedExample 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter3/StringExercisesTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import com.insightfullogic.java8.answers.chapter3.StringExercises; 4 | import org.junit.Test; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collections; 8 | import java.util.Optional; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | import static org.junit.Assert.assertFalse; 12 | 13 | public class StringExercisesTest { 14 | 15 | @Test 16 | public void noLowercaseLettersInAnEmptyString() { 17 | assertEquals(0, com.insightfullogic.java8.answers.chapter3.StringExercises.countLowercaseLetters("")); 18 | } 19 | 20 | @Test 21 | public void countsLowercaseLetterExample() { 22 | assertEquals(3, com.insightfullogic.java8.answers.chapter3.StringExercises.countLowercaseLetters("aBcDeF")); 23 | } 24 | 25 | @Test 26 | public void suppoertsNoLowercaseLetters() { 27 | assertEquals(0, com.insightfullogic.java8.answers.chapter3.StringExercises.countLowercaseLetters("ABCDEF")); 28 | } 29 | 30 | @Test 31 | public void noStringReturnedForEmptyList() { 32 | assertFalse(com.insightfullogic.java8.answers.chapter3.StringExercises.mostLowercaseString(Collections.emptyList()).isPresent()); 33 | } 34 | 35 | @Test 36 | public void findsMostLowercaseString() { 37 | Optional result = StringExercises.mostLowercaseString(Arrays.asList("a", "abc", "ABCde")); 38 | assertEquals(Optional.of("abc"), result); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter5/StringCombinerTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.*; 7 | 8 | public class StringCombinerTest { 9 | private StringCombiner combiner; 10 | 11 | @Before 12 | public void before() { 13 | this.combiner = new StringCombiner(", ", "[", "]"); 14 | 15 | combiner.add("A").add("B").add("C").add("D"); 16 | } 17 | 18 | @Test 19 | public void add() throws Exception { 20 | assertEquals("[A, B, C, D]", combiner.toString()); 21 | } 22 | 23 | @Test 24 | public void mergeWithOther() throws Exception { 25 | StringCombiner other = new StringCombiner(", ", "[", "]"); 26 | 27 | other.add("E").add("F").add("G"); 28 | 29 | this.combiner.merge(other); 30 | 31 | assertEquals("[A, B, C, D, E, F, G]", this.combiner.toString()); 32 | } 33 | 34 | @Test 35 | public void mergeWithEmpty() { 36 | this.combiner.merge(new StringCombiner(", ", "[", "]")); 37 | 38 | assertEquals("[A, B, C, D]", this.combiner.toString()); 39 | } 40 | 41 | @Test 42 | public void mergeSelf() throws Exception { 43 | assertEquals("[A, B, C, D]", this.combiner.merge(this.combiner).toString()); 44 | } 45 | 46 | @Test 47 | public void twiceCallToString() throws Exception { 48 | assertEquals("[A, B, C, D]", this.combiner.toString()); 49 | assertEquals("[A, B, C, D]", this.combiner.toString()); 50 | } 51 | } -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter9/AlbumLookupTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter9; 2 | 3 | 4 | import com.insightfullogic.java8.examples.chapter1.Album; 5 | import com.insightfullogic.java8.examples.chapter1.Artist; 6 | import com.insightfullogic.java8.examples.chapter1.SampleData; 7 | import com.insightfullogic.java8.examples.chapter1.Track; 8 | import org.junit.Test; 9 | 10 | import java.util.List; 11 | import java.util.function.BiFunction; 12 | import java.util.stream.Stream; 13 | 14 | import static org.junit.Assert.assertEquals; 15 | 16 | public class AlbumLookupTest { 17 | 18 | interface AlbumLookupFactory extends BiFunction, List, AlbumLookup> { 19 | 20 | } 21 | 22 | @Test 23 | public void albumLookedUp() { 24 | Album album = SampleData.aLoveSupreme; 25 | List trackList = album.getTrackList(); 26 | List musicianList = album.getMusicianList(); 27 | 28 | AlbumLookupFactory completable = CompletableAlbumLookup::new; 29 | AlbumLookupFactory future = FutureAlbumLookup::new; 30 | 31 | Stream.of(completable, future) 32 | .forEach(factory -> { 33 | AlbumLookup lookup = factory.apply(trackList, musicianList); 34 | System.out.println("Testing: " + lookup.getClass().getSimpleName()); 35 | Album result = lookup.lookupByName(album.getName()); 36 | 37 | assertEquals(trackList, result.getTrackList()); 38 | assertEquals(musicianList, result.getMusicianList()); 39 | }); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/strategy/Compressor.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.strategy; 2 | 3 | import java.io.*; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.util.zip.GZIPOutputStream; 7 | import java.util.zip.ZipOutputStream; 8 | 9 | // BEGIN Compressor 10 | public class Compressor { 11 | 12 | private final CompressionStrategy strategy; 13 | 14 | public Compressor(CompressionStrategy strategy) { 15 | this.strategy = strategy; 16 | } 17 | 18 | public void compress(Path inFile, File outFile) throws IOException { 19 | try (OutputStream outStream = new FileOutputStream(outFile)) { 20 | Files.copy(inFile, strategy.compress(outStream)); 21 | } 22 | } 23 | // END Compressor 24 | 25 | public static void classBasedExample(Path inFile, File outFile) throws IOException { 26 | // BEGIN classBasedExample 27 | Compressor gzipCompressor = new Compressor(new GzipCompressionStrategy()); 28 | gzipCompressor.compress(inFile, outFile); 29 | 30 | Compressor zipCompressor = new Compressor(new ZipCompressionStrategy()); 31 | zipCompressor.compress(inFile, outFile); 32 | // END classBasedExample 33 | } 34 | 35 | public static void lambdaBasedExample(Path inFile, File outFile) throws IOException { 36 | // BEGIN lambdaBasedExample 37 | Compressor gzipCompressor = new Compressor(GZIPOutputStream::new); 38 | gzipCompressor.compress(inFile, outFile); 39 | 40 | Compressor zipCompressor = new Compressor(ZipOutputStream::new); 41 | zipCompressor.compress(inFile, outFile); 42 | // END lambdaBasedExample 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter3/Question1Test.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import com.insightfullogic.java8.answers.chapter3.Question1; 6 | import org.junit.Test; 7 | 8 | import java.util.List; 9 | import java.util.stream.Stream; 10 | 11 | import static com.insightfullogic.java8.examples.chapter1.SampleData.*; 12 | import static java.util.Arrays.asList; 13 | import static org.junit.Assert.assertEquals; 14 | 15 | public class Question1Test { 16 | 17 | @Test 18 | public void addsEmptyList() { 19 | int result = com.insightfullogic.java8.answers.chapter3.Question1.addUp(Stream.empty()); 20 | assertEquals(0, result); 21 | } 22 | 23 | @Test 24 | public void addsListWithValues() { 25 | int result = com.insightfullogic.java8.answers.chapter3.Question1.addUp(Stream.of(1, 3, -2)); 26 | assertEquals(2, result); 27 | } 28 | 29 | @Test 30 | public void extractsNamesAndOriginsOfArtists() { 31 | List namesAndOrigins = com.insightfullogic.java8.answers.chapter3.Question1.getNamesAndOrigins(SampleData.getThreeArtists()); 32 | assertEquals(asList("John Coltrane", "US", "John Lennon", "UK", "The Beatles", "UK"), namesAndOrigins); 33 | } 34 | 35 | @Test 36 | public void findsShortAlbums() { 37 | List input = asList(manyTrackAlbum, sampleShortAlbum, aLoveSupreme); 38 | List result = Question1.getAlbumsWithAtMostThreeTracks(input); 39 | assertEquals(asList(sampleShortAlbum, aLoveSupreme), result); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter9/ArtistAnalyzerTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter9; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.junit.runners.Parameterized; 6 | 7 | import java.util.Arrays; 8 | import java.util.Collection; 9 | import java.util.concurrent.atomic.AtomicBoolean; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | 13 | @RunWith(Parameterized.class) 14 | public class ArtistAnalyzerTest { 15 | 16 | @Parameterized.Parameters 17 | public static Collection data() { 18 | FakeLookupService lookupService = new FakeLookupService(); 19 | Object[][] data = new Object[][] { 20 | { new CallbackArtistAnalyser(lookupService::lookupArtistName) }, 21 | { new CompletableFutureArtistAnalyser(lookupService::lookupArtistName) }, 22 | }; 23 | return Arrays.asList(data); 24 | } 25 | 26 | private final ArtistAnalyzer analyser; 27 | 28 | public ArtistAnalyzerTest(ArtistAnalyzer analyser) { 29 | this.analyser = analyser; 30 | } 31 | 32 | @Test 33 | public void largerGroupsAreLarger() { 34 | assertLargerGroup(true, "The Beatles", "John Coltrane"); 35 | } 36 | 37 | @Test 38 | public void smallerGroupsArentLarger() { 39 | assertLargerGroup(false, "John Coltrane", "The Beatles"); 40 | } 41 | 42 | private void assertLargerGroup(boolean expected, String artistName, String otherArtistName) { 43 | AtomicBoolean isLarger = new AtomicBoolean(!expected); 44 | analyser.isLargerGroup(artistName, otherArtistName, isLarger::set); 45 | assertEquals(expected, isLarger.get()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/exercises/chapter3/Question1Test.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import org.junit.Test; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.stream.Stream; 10 | 11 | import static com.insightfullogic.java8.examples.chapter1.SampleData.aLoveSupreme; 12 | import static com.insightfullogic.java8.examples.chapter1.SampleData.manyTrackAlbum; 13 | import static com.insightfullogic.java8.examples.chapter1.SampleData.sampleShortAlbum; 14 | import static java.util.Arrays.asList; 15 | import static org.junit.Assert.assertEquals; 16 | 17 | public class Question1Test { 18 | 19 | @Test 20 | public void addsEmptyList() { 21 | int result = Question1.addUp(Stream.empty()); 22 | assertEquals(0, result); 23 | } 24 | 25 | @Test 26 | public void addsListWithValues() { 27 | int result = Question1.addUp(Stream.of(1, 3, -2)); 28 | assertEquals(2, result); 29 | } 30 | 31 | @Test 32 | public void extractsNamesAndOriginsOfArtists() { 33 | List namesAndOrigins = Question1.getNamesAndOrigins(SampleData.getThreeArtists()); 34 | assertEquals(asList("John Coltrane", "US", "John Lennon", "UK", "The Beatles", "UK"), namesAndOrigins); 35 | } 36 | 37 | @Test 38 | public void findsShortAlbums() { 39 | List input = asList(manyTrackAlbum, sampleShortAlbum, aLoveSupreme); 40 | List result = Question1.getAlbumsWithAtMostThreeTracks(input); 41 | assertEquals(asList(sampleShortAlbum, aLoveSupreme), result); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter3/RefactorTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import org.junit.Test; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.Set; 10 | import java.util.function.Supplier; 11 | 12 | import static java.util.Arrays.asList; 13 | import static java.util.Collections.unmodifiableList; 14 | import static org.junit.Assert.assertEquals; 15 | import static org.junit.Assert.assertTrue; 16 | 17 | public class RefactorTest { 18 | 19 | @Test 20 | public void allStringJoins() { 21 | List> finders = Arrays.>asList( 22 | Refactor.Step0::new, 23 | Refactor.Step1::new, 24 | Refactor.Step2::new, 25 | Refactor.Step3::new, 26 | Refactor.Step4::new 27 | ); 28 | 29 | List albums = unmodifiableList(asList(SampleData.aLoveSupreme, SampleData.sampleShortAlbum)); 30 | List noTracks = unmodifiableList(asList(SampleData.sampleShortAlbum)); 31 | 32 | finders.forEach(finder -> { 33 | System.out.println("Testing: " + finder.toString()); 34 | 35 | Refactor.LongTrackFinder longTrackFinder = finder.get(); 36 | Set longTracks = longTrackFinder.findLongTracks(albums); 37 | 38 | assertEquals("[Acknowledgement, Resolution]", longTracks.toString()); 39 | 40 | longTracks = longTrackFinder.findLongTracks(noTracks); 41 | 42 | assertTrue(longTracks.isEmpty()); 43 | }); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/SingleResponsibilityPrincipleTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.junit.runners.Parameterized; 6 | 7 | import java.util.Arrays; 8 | import java.util.Collection; 9 | 10 | import static com.insightfullogic.java8.examples.chapter8.SingleResponsibilityPrinciple.*; 11 | import static org.junit.Assert.assertEquals; 12 | import static org.junit.runners.Parameterized.Parameters; 13 | 14 | @RunWith(Parameterized.class) 15 | public class SingleResponsibilityPrincipleTest { 16 | 17 | @Parameters 18 | public static Collection data() { 19 | Object[][] data = new Object[][]{ {new ImperativeRefactoredPrimeCounter()}, 20 | {new ImperativeSingleMethodPrimeCounter()}, 21 | {new FunctionalPrimeCounter()}, 22 | {new ParallelFunctionalPrimeCounter()}}; 23 | return Arrays.asList(data); 24 | } 25 | 26 | private final PrimeCounter primeCounter; 27 | 28 | public SingleResponsibilityPrincipleTest(PrimeCounter primeCounter) { 29 | this.primeCounter = primeCounter; 30 | } 31 | 32 | @Test 33 | public void countsPrimesTo10() { 34 | assertEquals(5, primeCounter.countPrimes(10)); 35 | assertEquals(9, primeCounter.countPrimes(20)); 36 | } 37 | 38 | @Test 39 | public void countsPrimesTo20() { 40 | assertEquals(9, primeCounter.countPrimes(20)); 41 | } 42 | 43 | @Test 44 | public void countsPrimesTo30() { 45 | assertEquals(11, primeCounter.countPrimes(30)); 46 | } 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter7/TestingTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter7; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | import static java.util.Arrays.asList; 9 | import static org.junit.Assert.assertEquals; 10 | import static org.mockito.Mockito.mock; 11 | import static org.mockito.Mockito.when; 12 | 13 | public class TestingTest { 14 | 15 | // BEGIN to_uppercase 16 | @Test 17 | public void multipleWordsToUppercase() { 18 | List input = Arrays.asList("a", "b", "hello"); 19 | List result = Testing.allToUpperCase(input); 20 | assertEquals(asList("A", "B", "HELLO"), result); 21 | } 22 | // END to_uppercase 23 | 24 | // BEGIN twoLetterStringConvertedToUppercaseLambdas 25 | @Test 26 | public void twoLetterStringConvertedToUppercaseLambdas() { 27 | List input = Arrays.asList("ab"); 28 | List result = Testing.elementFirstToUpperCaseLambdas(input); 29 | assertEquals(asList("Ab"), result); 30 | } 31 | // END twoLetterStringConvertedToUppercaseLambdas 32 | 33 | // BEGIN twoLetterStringConvertedToUppercase 34 | @Test 35 | public void twoLetterStringConvertedToUppercase() { 36 | String input = "ab"; 37 | String result = Testing.firstToUppercase(input); 38 | assertEquals("Ab", result); 39 | } 40 | // END twoLetterStringConvertedToUppercase 41 | 42 | private List otherList = Arrays.asList(1, 2, 3); 43 | 44 | @Test 45 | public void mockitoLambdas() { 46 | // BEGIN mockito_lambdas 47 | List list = mock(List.class); 48 | 49 | when(list.size()).thenAnswer(inv -> otherList.size()); 50 | 51 | assertEquals(3, list.size()); 52 | // END mockito_lambdas 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/StringCollector.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5; 2 | 3 | import java.util.Collections; 4 | import java.util.Set; 5 | import java.util.function.BiConsumer; 6 | import java.util.function.BinaryOperator; 7 | import java.util.function.Function; 8 | import java.util.function.Supplier; 9 | import java.util.stream.Collector; 10 | 11 | // BEGIN class_def 12 | public class StringCollector implements Collector { 13 | // END class_def 14 | 15 | private static final Set characteristics = Collections.emptySet(); 16 | 17 | private final String delim; 18 | private final String prefix; 19 | private final String suffix; 20 | 21 | public StringCollector(String delim, String prefix, String suffix) { 22 | this.delim = delim; 23 | this.prefix = prefix; 24 | this.suffix = suffix; 25 | } 26 | 27 | @Override 28 | // BEGIN supplier 29 | public Supplier supplier() { 30 | return () -> new StringCombiner(delim, prefix, suffix); 31 | } 32 | // END supplier 33 | 34 | @Override 35 | // BEGIN accumulator 36 | public BiConsumer accumulator() { 37 | return StringCombiner::add; 38 | } 39 | // END accumulator 40 | 41 | @Override 42 | // BEGIN combiner 43 | public BinaryOperator combiner() { 44 | return StringCombiner::merge; 45 | } 46 | // END combiner 47 | 48 | @Override 49 | // BEGIN finisher 50 | public Function finisher() { 51 | return StringCombiner::toString; 52 | } 53 | // END finisher 54 | 55 | @Override 56 | public Set characteristics() { 57 | return characteristics; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter3/FilterUsingReduce.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter3; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.function.Predicate; 6 | import java.util.stream.Stream; 7 | 8 | /** 9 | * Advanced Exercises Question 2 10 | */ 11 | public class FilterUsingReduce { 12 | 13 | public static List filter(Stream stream, Predicate predicate) { 14 | List initial = new ArrayList<>(); 15 | return stream.reduce(initial, 16 | (List acc, I x) -> { 17 | if (predicate.test(x)) { 18 | // We are copying data from acc to new list instance. It is very inefficient, 19 | // but contract of Stream.reduce method requires that accumulator function does 20 | // not mutate its arguments. 21 | // Stream.collect method could be used to implement more efficient mutable reduction, 22 | // but this exercise asks to use reduce method explicitly. 23 | List newAcc = new ArrayList<>(acc); 24 | newAcc.add(x); 25 | return newAcc; 26 | } else { 27 | return acc; 28 | } 29 | }, 30 | FilterUsingReduce::combineLists); 31 | } 32 | 33 | private static List combineLists(List left, List right) { 34 | // We are copying left to new list to avoid mutating it. 35 | List newLeft = new ArrayList<>(left); 36 | newLeft.addAll(right); 37 | return newLeft; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter8/lambdabehave/Runner.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8.lambdabehave; 2 | 3 | import com.insightfullogic.java8.examples.chapter8.lambdabehave.example.StackSpec; 4 | import com.insightfullogic.java8.examples.chapter8.lambdabehave.reporting.*; 5 | 6 | public enum Runner { 7 | 8 | current; 9 | 10 | private final Report report; 11 | 12 | private Runner() { 13 | report = new Report(); 14 | } 15 | 16 | void recordSuccess(String suite, String specification) { 17 | report.newSpecification(suite, new SpecificationReport(specification)); 18 | } 19 | 20 | void recordFailure(String suite, String specification, AssertionError cause) { 21 | SpecificationReport specificationReport = new SpecificationReport(specification, Result.FAILURE, cause.getMessage()); 22 | report.newSpecification(suite, specificationReport); 23 | } 24 | 25 | void recordError(String suite, String specification, Throwable cause) { 26 | cause.printStackTrace(); 27 | SpecificationReport specificationReport = new SpecificationReport(specification, Result.ERROR, cause.getMessage()); 28 | report.newSpecification(suite, specificationReport); 29 | } 30 | 31 | public static void main(String[] args) { 32 | current.run(StackSpec.class); 33 | current.printReport(); 34 | } 35 | 36 | private void printReport() { 37 | ReportFormatter formatter = new ConsoleFormatter(); 38 | formatter.format(report); 39 | } 40 | 41 | private void run(Class stackSpecClass) { 42 | try { 43 | stackSpecClass.newInstance(); 44 | } catch (InstantiationException e) { 45 | e.printStackTrace(); 46 | } catch (IllegalAccessException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter1/SampleData.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter1; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Stream; 6 | 7 | import static java.util.Arrays.asList; 8 | 9 | public class SampleData { 10 | 11 | public static final Artist johnColtrane = new Artist("John Coltrane", "US"); 12 | 13 | public static final Artist johnLennon = new Artist("John Lennon", "UK"); 14 | public static final Artist paulMcCartney = new Artist("Paul McCartney", "UK"); 15 | public static final Artist georgeHarrison = new Artist("George Harrison", "UK"); 16 | public static final Artist ringoStarr = new Artist("Ringo Starr", "UK"); 17 | 18 | public static final List membersOfTheBeatles = Arrays.asList(johnLennon, paulMcCartney, georgeHarrison, ringoStarr); 19 | 20 | public static final Artist theBeatles = new Artist("The Beatles", membersOfTheBeatles, "UK"); 21 | 22 | public static final Album aLoveSupreme = new Album("A Love Supreme", asList(new Track("Acknowledgement", 467), new Track("Resolution", 442)), asList(johnColtrane)); 23 | 24 | public static final Album sampleShortAlbum = new Album("sample Short Album", asList(new Track("short track", 30)), asList(johnColtrane)); 25 | 26 | public static final Album manyTrackAlbum = new Album("sample Short Album", asList(new Track("short track", 30), new Track("short track 2", 30), new Track("short track 3", 30), new Track("short track 4", 30), new Track("short track 5", 30)), asList(johnColtrane)); 27 | 28 | public static Stream albums = Stream.of(aLoveSupreme); 29 | 30 | public static Stream threeArtists() { 31 | return Stream.of(johnColtrane, johnLennon, theBeatles); 32 | } 33 | 34 | public static List getThreeArtists() { 35 | return Arrays.asList(johnColtrane, johnLennon, theBeatles); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/answers/chapter9/ArtistAnalyzerTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter9; 2 | 3 | import com.insightfullogic.java8.answers.chapter9.ArtistAnalyzer; 4 | import com.insightfullogic.java8.answers.chapter9.CallbackArtistAnalyser; 5 | import com.insightfullogic.java8.answers.chapter9.CompletableFutureArtistAnalyser; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.junit.runners.Parameterized; 9 | 10 | import java.util.Arrays; 11 | import java.util.Collection; 12 | import java.util.concurrent.atomic.AtomicBoolean; 13 | 14 | import static org.junit.Assert.assertEquals; 15 | 16 | @RunWith(Parameterized.class) 17 | public class ArtistAnalyzerTest { 18 | 19 | @Parameterized.Parameters 20 | public static Collection data() { 21 | FakeLookupService lookupService = new FakeLookupService(); 22 | Object[][] data = new Object[][] { 23 | { new CallbackArtistAnalyser(lookupService::lookupArtistName) }, 24 | { new CompletableFutureArtistAnalyser(lookupService::lookupArtistName) }, 25 | }; 26 | return Arrays.asList(data); 27 | } 28 | 29 | private final ArtistAnalyzer analyser; 30 | 31 | public ArtistAnalyzerTest(ArtistAnalyzer analyser) { 32 | this.analyser = analyser; 33 | } 34 | 35 | @Test 36 | public void largerGroupsAreLarger() { 37 | assertLargerGroup(true, "The Beatles", "John Coltrane"); 38 | } 39 | 40 | @Test 41 | public void smallerGroupsArentLarger() { 42 | assertLargerGroup(false, "John Coltrane", "The Beatles"); 43 | } 44 | 45 | private void assertLargerGroup(boolean expected, String artistName, String otherArtistName) { 46 | AtomicBoolean isLarger = new AtomicBoolean(!expected); 47 | analyser.isLargerGroup(artistName, otherArtistName, isLarger::set); 48 | assertEquals(expected, isLarger.get()); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter6/OptimisationExample.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter6; 2 | 3 | import org.openjdk.jmh.Main; 4 | import org.openjdk.jmh.annotations.*; 5 | import org.openjdk.jmh.runner.RunnerException; 6 | 7 | import java.io.IOException; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | import java.util.stream.IntStream; 11 | 12 | /** 13 | * Just run this class's main method and it will time benchmarks using the harness 14 | */ 15 | @State(Scope.Thread) 16 | @BenchmarkMode(Mode.AverageTime) 17 | public class OptimisationExample { 18 | 19 | public static void main(String[] ignore) throws IOException, RunnerException { 20 | final String[] args = { 21 | ".*OptimisationExample.*", 22 | "-wi", 23 | "10", 24 | "-i", 25 | "10", 26 | "-f", 27 | "1" 28 | }; 29 | Main.main(args); 30 | } 31 | 32 | private List linkedListOfNumbers; 33 | 34 | @Setup 35 | public void init() { 36 | linkedListOfNumbers = new LinkedList<>(); 37 | addNumbers(linkedListOfNumbers); 38 | 39 | // TODO: put any additional setup code here 40 | } 41 | 42 | private void addNumbers(List container) { 43 | IntStream.range(0, 1_000_000) 44 | .forEach(container::add); 45 | } 46 | 47 | @GenerateMicroBenchmark 48 | // BEGIN slowSumOfSquares 49 | public int slowSumOfSquares() { 50 | return linkedListOfNumbers.parallelStream() 51 | .map(x -> x * x) 52 | .reduce(0, (acc, x) -> acc + x); 53 | } 54 | // END slowSumOfSquares 55 | 56 | @GenerateMicroBenchmark 57 | public int fastSumOfSquares() { 58 | // TODO: implement faster version of slowSumOfSquares here 59 | return 0; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter5/GroupingBy.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter5; 2 | 3 | import java.util.*; 4 | import java.util.function.BiConsumer; 5 | import java.util.function.BinaryOperator; 6 | import java.util.function.Function; 7 | import java.util.function.Supplier; 8 | import java.util.stream.Collector; 9 | 10 | public class GroupingBy implements Collector>, Map>> { 11 | 12 | private final static Set characteristics = new HashSet<>(); 13 | static { 14 | characteristics.add(Characteristics.IDENTITY_FINISH); 15 | } 16 | 17 | private final Function classifier; 18 | 19 | public GroupingBy(Function classifier) { 20 | this.classifier = classifier; 21 | } 22 | 23 | @Override 24 | public Supplier>> supplier() { 25 | return HashMap::new; 26 | } 27 | 28 | @Override 29 | public BiConsumer>, T> accumulator() { 30 | return (map, element) -> { 31 | K key = classifier.apply(element); 32 | List elements = map.computeIfAbsent(key, k -> new ArrayList<>()); 33 | elements.add(element); 34 | }; 35 | } 36 | 37 | @Override 38 | public BinaryOperator>> combiner() { 39 | return (left, right) -> { 40 | right.forEach((key, value) -> { 41 | left.merge(key, value, (leftValue, rightValue) -> { 42 | leftValue.addAll(rightValue); 43 | return leftValue; 44 | }); 45 | }); 46 | return left; 47 | }; 48 | } 49 | 50 | @Override 51 | public Function>, Map>> finisher() { 52 | return map -> map; 53 | } 54 | 55 | @Override 56 | public Set characteristics() { 57 | return characteristics; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter6/ArraySum.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter6; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import com.insightfullogic.java8.examples.chapter1.Track; 6 | 7 | import org.openjdk.jmh.Main; 8 | import org.openjdk.jmh.annotations.*; 9 | import org.openjdk.jmh.runner.RunnerException; 10 | 11 | import java.io.IOException; 12 | import java.util.List; 13 | import java.util.stream.IntStream; 14 | 15 | import static java.util.stream.Collectors.groupingBy; 16 | import static java.util.stream.Collectors.toList; 17 | 18 | @State(Scope.Benchmark) 19 | @BenchmarkMode(Mode.AverageTime) 20 | public class ArraySum { 21 | 22 | public static void main(String[] ignore) throws IOException, RunnerException { 23 | final String[] args = { 24 | ".*ArraySum.*", 25 | "-wi", 26 | "5", 27 | "-i", 28 | "5" 29 | }; 30 | Main.main(args); 31 | } 32 | 33 | public List albums; 34 | 35 | @Setup 36 | public void initAlbums() { 37 | int n = Integer.getInteger("arraysum.size", 1000); 38 | albums = IntStream.range(0, n) 39 | .mapToObj(i -> SampleData.aLoveSupreme.copy()) 40 | .collect(toList()); 41 | } 42 | 43 | @GenerateMicroBenchmark 44 | // BEGIN serial 45 | public int serialArraySum() { 46 | return albums.stream() 47 | .flatMap(Album::getTracks) 48 | .mapToInt(Track::getLength) 49 | .sum(); 50 | } 51 | // END serial 52 | 53 | @GenerateMicroBenchmark 54 | // BEGIN parallel 55 | public int parallelArraySum() { 56 | return albums.parallelStream() 57 | .flatMap(Album::getTracks) 58 | .mapToInt(Track::getLength) 59 | .sum(); 60 | } 61 | // END parallel 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/exercises/chapter6/OptimisationExample.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.exercises.chapter6; 2 | 3 | import com.insightfullogic.java8.exercises.Exercises; 4 | import org.openjdk.jmh.Main; 5 | import org.openjdk.jmh.annotations.*; 6 | import org.openjdk.jmh.runner.RunnerException; 7 | 8 | import java.io.IOException; 9 | import java.util.ArrayList; 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | import java.util.stream.IntStream; 13 | 14 | /** 15 | * Just run this class's main method and it will time benchmarks using the harness 16 | */ 17 | @State(Scope.Thread) 18 | @BenchmarkMode(Mode.AverageTime) 19 | public class OptimisationExample { 20 | 21 | public static void main(String[] ignore) throws IOException, RunnerException { 22 | final String[] args = { 23 | ".*OptimisationExample.*", 24 | "-wi", 25 | "10", 26 | "-i", 27 | "10", 28 | "-f", 29 | "1" 30 | }; 31 | Main.main(args); 32 | } 33 | 34 | private List linkedListOfNumbers; 35 | 36 | @Setup 37 | public void init() { 38 | linkedListOfNumbers = new LinkedList<>(); 39 | addNumbers(linkedListOfNumbers); 40 | 41 | // TODO: put any additional setup code here 42 | } 43 | 44 | private void addNumbers(List container) { 45 | IntStream.range(0, 1_000_000) 46 | .forEach(container::add); 47 | } 48 | 49 | @GenerateMicroBenchmark 50 | // BEGIN slowSumOfSquares 51 | public int slowSumOfSquares() { 52 | return linkedListOfNumbers.parallelStream() 53 | .map(x -> x * x) 54 | .reduce(0, (acc, x) -> acc + x); 55 | } 56 | // END slowSumOfSquares 57 | 58 | @GenerateMicroBenchmark 59 | public int fastSumOfSquares() { 60 | return Exercises.replaceThisWithSolution(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter5/StringExamplesTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5; 2 | 3 | 4 | import com.insightfullogic.java8.examples.chapter1.Artist; 5 | import com.insightfullogic.java8.examples.chapter1.SampleData; 6 | import org.junit.Test; 7 | 8 | import java.util.Arrays; 9 | import java.util.Collections; 10 | import java.util.List; 11 | import java.util.StringJoiner; 12 | import java.util.function.Function; 13 | 14 | import static org.junit.Assert.assertEquals; 15 | 16 | public class StringExamplesTest { 17 | 18 | @Test 19 | public void beatlesExample() { 20 | StringJoiner joiner = new StringJoiner(", ", "[", "]"); 21 | joiner.add("John"); 22 | joiner.add("Paul"); 23 | joiner.add("Ringo"); 24 | assertEquals("[John, Paul, Ringo]", joiner.toString()); 25 | } 26 | 27 | @Test 28 | public void allStringJoins() { 29 | List, String>> formatters = Arrays., String>>asList( 30 | StringExamples::formatArtists, 31 | StringExamples::formatArtistsForLoop, 32 | StringExamples::formatArtistsRefactor1, 33 | StringExamples::formatArtistsRefactor2, 34 | StringExamples::formatArtistsRefactor3, 35 | StringExamples::formatArtistsRefactor4, 36 | StringExamples::formatArtistsRefactor5 37 | ); 38 | 39 | formatters.forEach(formatter -> { 40 | System.out.println("Testing: " + formatter.toString()); 41 | String result = formatter.apply(SampleData.getThreeArtists()); 42 | assertEquals("[John Coltrane, John Lennon, The Beatles]", result); 43 | 44 | result = formatter.apply(Collections.emptyList()); 45 | assertEquals("[]", result); 46 | }); 47 | } 48 | 49 | @Test 50 | public void explicitForLoop() { 51 | String result = StringExamples.formatArtists(SampleData.getThreeArtists()); 52 | assertEquals("[John Coltrane, John Lennon, The Beatles]", result); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter4/TestOrder.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter4; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.SampleData; 5 | import com.insightfullogic.java8.examples.chapter1.Track; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.junit.runners.Parameterized; 10 | 11 | import java.util.Collection; 12 | import java.util.List; 13 | import java.util.function.Function; 14 | 15 | import static java.util.Arrays.asList; 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.runners.Parameterized.Parameters; 18 | 19 | @RunWith(Parameterized.class) 20 | public class TestOrder { 21 | 22 | private final OrderFactory factory; 23 | 24 | private Order order; 25 | 26 | @Parameters 27 | public static Collection data() { 28 | Object[][] data = new Object[][] { of(OrderImperative::new), of(OrderStreams::new), of(OrderDomain::new) }; 29 | return asList(data); 30 | } 31 | 32 | private static interface OrderFactory extends Function, Order> {} 33 | 34 | private static Object[] of(OrderFactory factory) { 35 | return new Object[] { factory }; 36 | } 37 | 38 | public TestOrder(OrderFactory factory) { 39 | this.factory = factory; 40 | } 41 | 42 | @Before 43 | public void initOrder() { 44 | List tracks = asList(new Track("Acknowledgement", 467), new Track("Resolution", 442)); 45 | Album aLoveSupreme = new Album("A Love Supreme", tracks, asList(SampleData.johnColtrane)); 46 | order = factory.apply(asList(aLoveSupreme)); 47 | } 48 | 49 | @Test 50 | public void countsRunningTime() { 51 | assertEquals(909, order.countRunningTime()); 52 | } 53 | 54 | @Test 55 | public void countsArtists() { 56 | assertEquals(1, order.countMusicians()); 57 | } 58 | 59 | @Test 60 | public void countsTracks() { 61 | assertEquals(2, order.countTracks()); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter3/Decisions.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.Artist; 5 | 6 | import java.util.HashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import static java.util.stream.Collectors.toList; 11 | import static java.util.stream.Collectors.toSet; 12 | 13 | public class Decisions { 14 | 15 | public static class Imperative { 16 | // BEGIN origins_of_bands_meth_imp 17 | public Set originsOfBands(Album album) { 18 | Set nationalities = new HashSet<>(); 19 | for (Artist artist : album.getMusicianList()) { 20 | if (artist.getName().startsWith("The")) { 21 | String nationality = artist.getNationality(); 22 | nationalities.add(nationality); 23 | } 24 | } 25 | return nationalities; 26 | } 27 | // END origins_of_bands_meth_imp 28 | } 29 | 30 | public Set originsOfBands(Album album) { 31 | // BEGIN origins_of_bands 32 | Set origins = album.getMusicians() 33 | .filter(artist -> artist.getName().startsWith("The")) 34 | .map(artist -> artist.getNationality()) 35 | .collect(toSet()); 36 | // END origins_of_bands 37 | return origins; 38 | } 39 | 40 | public Set originsOfBandsMisuse(Album album) { 41 | // BEGIN misuse 42 | List musicians = album.getMusicians() 43 | .collect(toList()); 44 | 45 | List bands = musicians.stream() 46 | .filter(artist -> artist.getName().startsWith("The")) 47 | .collect(toList()); 48 | 49 | Set origins = bands.stream() 50 | .map(artist -> artist.getNationality()) 51 | .collect(toSet()); 52 | // END misuse 53 | return origins; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter1/Artist.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package com.insightfullogic.java8.examples.chapter1; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.List; 11 | import java.util.Objects; 12 | import java.util.stream.Stream; 13 | 14 | import static java.util.stream.Collectors.toList; 15 | 16 | /** 17 | * Domain class for a popular music artist. 18 | * 19 | * @author Richard Warburton 20 | */ 21 | public final class Artist { 22 | 23 | private String name; 24 | private List members; 25 | private String nationality; 26 | 27 | public Artist(String name, String nationality) { 28 | this(name, Collections.emptyList(), nationality); 29 | } 30 | 31 | public Artist(String name, List members, String nationality) { 32 | Objects.requireNonNull(name); 33 | Objects.requireNonNull(members); 34 | Objects.requireNonNull(nationality); 35 | this.name = name; 36 | this.members = new ArrayList<>(members); 37 | this.nationality = nationality; 38 | } 39 | 40 | /** 41 | * @return the name 42 | */ 43 | public String getName() { 44 | return name; 45 | } 46 | 47 | /** 48 | * @return the members 49 | */ 50 | public Stream getMembers() { 51 | return members.stream(); 52 | } 53 | 54 | /** 55 | * @return the nationality 56 | */ 57 | public String getNationality() { 58 | return nationality; 59 | } 60 | 61 | public boolean isSolo() { 62 | return members.isEmpty(); 63 | } 64 | 65 | public boolean isFrom(String nationality) { 66 | return this.nationality.equals(nationality); 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return getName(); 72 | } 73 | 74 | public Artist copy() { 75 | List members = getMembers().map(Artist::copy).collect(toList()); 76 | return new Artist(name, members, nationality); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/DependencyInversionPrinciple.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.Reader; 6 | import java.util.List; 7 | import java.util.function.Function; 8 | import java.util.stream.Stream; 9 | 10 | import static java.util.stream.Collectors.toList; 11 | 12 | public class DependencyInversionPrinciple { 13 | 14 | public static interface HeadingFinder { 15 | public List findHeadings(Reader reader); 16 | } 17 | 18 | public static class NoDIP implements HeadingFinder { 19 | // BEGIN nodip_headings 20 | public List findHeadings(Reader input) { 21 | try (BufferedReader reader = new BufferedReader(input)) { 22 | return reader.lines() 23 | .filter(line -> line.endsWith(":")) 24 | .map(line -> line.substring(0, line.length() - 1)) 25 | .collect(toList()); 26 | } catch (IOException e) { 27 | throw new HeadingLookupException(e); 28 | } 29 | } 30 | // END nodip_headings 31 | } 32 | 33 | public static class ExtractedDIP implements HeadingFinder { 34 | // BEGIN refactored_headings 35 | public List findHeadings(Reader input) { 36 | return withLinesOf(input, 37 | lines -> lines.filter(line -> line.endsWith(":")) 38 | .map(line -> line.substring(0, line.length()-1)) 39 | .collect(toList()), 40 | HeadingLookupException::new); 41 | } 42 | // END refactored_headings 43 | 44 | // BEGIN with_lines_Of 45 | private T withLinesOf(Reader input, 46 | Function, T> handler, 47 | Function error) { 48 | 49 | try (BufferedReader reader = new BufferedReader(input)) { 50 | return handler.apply(reader.lines()); 51 | } catch (IOException e) { 52 | throw error.apply(e); 53 | } 54 | } 55 | // END with_lines_Of 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter6/DiceRolls.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter6; 2 | 3 | import org.openjdk.jmh.Main; 4 | import org.openjdk.jmh.annotations.*; 5 | import org.openjdk.jmh.runner.RunnerException; 6 | 7 | import java.io.IOException; 8 | import java.util.Map; 9 | import java.util.concurrent.ThreadLocalRandom; 10 | import java.util.function.IntFunction; 11 | import java.util.stream.IntStream; 12 | 13 | import static java.util.stream.Collectors.groupingBy; 14 | import static java.util.stream.Collectors.summingDouble; 15 | 16 | @State(Scope.Benchmark) 17 | @BenchmarkMode(Mode.AverageTime) 18 | public class DiceRolls { 19 | 20 | private static final int N = 100000000; 21 | 22 | public static void main(String[] ignore) throws IOException, RunnerException { 23 | final String[] args = { 24 | ".*DiceRolls.*", 25 | "-wi", 26 | "5", 27 | "-i", 28 | "5" 29 | }; 30 | Main.main(args); 31 | } 32 | 33 | @GenerateMicroBenchmark 34 | // BEGIN serial 35 | public Map serialDiceRolls() { 36 | double fraction = 1.0 / N; 37 | return IntStream.range(0, N) 38 | .mapToObj(twoDiceThrows()) 39 | .collect(groupingBy(side -> side, summingDouble(n -> fraction))); 40 | } 41 | // END serial 42 | 43 | @GenerateMicroBenchmark 44 | // BEGIN parallel 45 | public Map parallelDiceRolls() { 46 | double fraction = 1.0 / N; 47 | return IntStream.range(0, N) // <1> 48 | .parallel() // <2> 49 | .mapToObj(twoDiceThrows()) // <3> 50 | .collect(groupingBy(side -> side, // <4> 51 | summingDouble(n -> fraction))); // <5> 52 | } 53 | // END parallel 54 | 55 | private static IntFunction twoDiceThrows() { 56 | return i -> { 57 | ThreadLocalRandom random = ThreadLocalRandom.current(); 58 | int firstThrow = random.nextInt(1, 7); 59 | int secondThrow = random.nextInt(1, 7); 60 | return firstThrow + secondThrow; 61 | }; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter1/Album.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package com.insightfullogic.java8.examples.chapter1; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Objects; 11 | import java.util.stream.Stream; 12 | 13 | import static java.util.Collections.unmodifiableList; 14 | import static java.util.stream.Collectors.toList; 15 | 16 | /** 17 | * 18 | * @author richard 19 | */ 20 | public final class Album implements Performance { 21 | 22 | private String name; 23 | private List tracks; 24 | private List musicians; 25 | 26 | public Album(String name, List tracks, List musicians) { 27 | Objects.requireNonNull(name); 28 | Objects.requireNonNull(tracks); 29 | Objects.requireNonNull(musicians); 30 | 31 | this.name = name; 32 | this.tracks = new ArrayList<>(tracks); 33 | this.musicians = new ArrayList<>(musicians); 34 | } 35 | 36 | /** 37 | * @return the name 38 | */ 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | /** 44 | * @return the tracks 45 | */ 46 | public Stream getTracks() { 47 | return tracks.stream(); 48 | } 49 | 50 | /** 51 | * Used in imperative code examples that need to iterate over a list 52 | */ 53 | public List getTrackList() { 54 | return unmodifiableList(tracks); 55 | } 56 | 57 | /** 58 | * @return the musicians 59 | */ 60 | public Stream getMusicians() { 61 | return musicians.stream(); 62 | } 63 | 64 | /** 65 | * Used in imperative code examples that need to iterate over a list 66 | */ 67 | public List getMusicianList() { 68 | return unmodifiableList(musicians); 69 | } 70 | 71 | public Artist getMainMusician() { 72 | return musicians.get(0); 73 | } 74 | 75 | public Album copy() { 76 | List tracks = getTracks().map(Track::copy).collect(toList()); 77 | List musicians = getMusicians().map(Artist::copy).collect(toList()); 78 | return new Album(name, tracks, musicians); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter2/LambdaExercises.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter2; 2 | 3 | import org.junit.Test; 4 | 5 | import javax.swing.*; 6 | import java.text.DateFormat; 7 | import java.util.Date; 8 | import java.util.Locale; 9 | import java.util.function.Function; 10 | import java.util.function.Predicate; 11 | 12 | import static junit.framework.Assert.assertEquals; 13 | import static junit.framework.Assert.assertTrue; 14 | 15 | public class LambdaExercises { 16 | 17 | @Test 18 | public void _1a() { 19 | assertTrue("Shown in the next chapter", true); 20 | } 21 | 22 | @Test 23 | public void _1b() { 24 | // If you were to model each operation on a calculator as a function. 25 | Function negate = (x) -> -1 * x; 26 | Function square = (x) -> x * x; 27 | Function percent = (x) -> 100 * x; 28 | } 29 | 30 | @Test 31 | public void _1c() { 32 | Function one = x -> x + 1; 33 | // 2 isn't 34 | Function three = x -> x == 1; 35 | } 36 | 37 | @Test 38 | public void _2a() { 39 | assertTrue("ThreadLocal.withInitial", true); 40 | } 41 | 42 | @Test 43 | public void _2b() { 44 | ThreadLocal threadSafeFormatter = ThreadLocal.withInitial(() -> DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.UK)); 45 | DateFormat formatter = threadSafeFormatter.get(); 46 | assertEquals("01-Jan-1970", formatter.format(new Date(0))); 47 | } 48 | 49 | @Test 50 | public void _3a() { 51 | // yes 52 | Runnable helloWorld = () -> System.out.println("hello world"); 53 | } 54 | 55 | @Test 56 | public void _3b() { 57 | // Yes 58 | JButton button = new JButton(); 59 | button.addActionListener(event -> System.out.println(event.getActionCommand())); 60 | } 61 | 62 | @Test 63 | public void _3c() { 64 | // No 65 | // check(x -> x > 5); 66 | } 67 | 68 | private boolean check(Predicate predicate) { 69 | System.out.println("wat?"); 70 | return true; 71 | } 72 | 73 | interface IntPred { 74 | boolean test(Integer value); 75 | } 76 | 77 | private boolean check(IntPred predicate) { 78 | return true; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter9/RxExamples.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | import rx.Observable; 5 | import rx.Observer; 6 | 7 | import java.util.List; 8 | 9 | import static java.util.stream.Collectors.toList; 10 | 11 | public class RxExamples { 12 | 13 | private final List savedArtists; 14 | private final List savedArtistNames; 15 | 16 | public RxExamples(List savedArtists) { 17 | this.savedArtists = savedArtists; 18 | savedArtistNames = savedArtists.stream() 19 | .map(Artist::getName) 20 | .collect(toList()); 21 | } 22 | 23 | // BEGIN search 24 | public Observable search(String searchedName, 25 | String searchedNationality, 26 | int maxResults) { 27 | 28 | return getSavedArtists() // <1> 29 | .filter(name -> name.contains(searchedName)) // <2> 30 | .flatMap(this::lookupArtist) // <3> 31 | .filter(artist -> artist.getNationality() // <4> 32 | .contains(searchedNationality)) 33 | .take(maxResults); // <5> 34 | } 35 | // END search 36 | 37 | // ------------------ FAKE LOOKUP CODE ------------------ 38 | // Again, imaginary external web services 39 | 40 | private Observable getSavedArtists() { 41 | return Observable.from(savedArtistNames); 42 | } 43 | 44 | private Observable lookupArtist(String name) { 45 | Artist required = savedArtists.stream() 46 | .filter(artist -> artist.getName().equals(name)) 47 | .findFirst() 48 | .get(); 49 | 50 | return Observable.from(required); 51 | } 52 | 53 | // Purely for imported code sample 54 | public void creationCodeSample() { 55 | Observer observer = null; 56 | 57 | // BEGIN completing_observable 58 | observer.onNext("a"); 59 | observer.onNext("b"); 60 | observer.onNext("c"); 61 | observer.onCompleted(); 62 | // END completing_observable 63 | 64 | // BEGIN error_observable 65 | observer.onError(new Exception()); 66 | // END error_observable 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter5/Niceties.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.Artist; 5 | 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public class Niceties { 11 | 12 | abstract class ArtistService { 13 | 14 | protected Map artistCache = new HashMap<>(); 15 | 16 | public abstract Artist getArtist(String name); 17 | 18 | protected Artist readArtistFromDB(String name) { 19 | return new Artist(name, "UK"); 20 | } 21 | } 22 | 23 | class OldArtistService extends ArtistService { 24 | // BEGIN ARTIST_CACHE_OLD 25 | public Artist getArtist(String name) { 26 | Artist artist = artistCache.get(name); 27 | if (artist == null) { 28 | artist = readArtistFromDB(name); 29 | artistCache.put(name, artist); 30 | } 31 | return artist; 32 | } 33 | // END ARTIST_CACHE_OLD 34 | } 35 | 36 | class Java8ArtistService extends ArtistService { 37 | // BEGIN ARTIST_CACHE_COMPUTE 38 | public Artist getArtist(String name) { 39 | return artistCache.computeIfAbsent(name, this::readArtistFromDB); 40 | } 41 | // END ARTIST_CACHE_COMPUTE 42 | } 43 | 44 | 45 | class ImperativeCount { 46 | 47 | public Map countAlbums(Map> albumsByArtist) { 48 | // BEGIN COUNT_ALBUMS_VALUES_UGLY 49 | Map countOfAlbums = new HashMap<>(); 50 | for(Map.Entry> entry : albumsByArtist.entrySet()) { 51 | Artist artist = entry.getKey(); 52 | List albums = entry.getValue(); 53 | countOfAlbums.put(artist, albums.size()); 54 | } 55 | // END COUNT_ALBUMS_VALUES_UGLY 56 | return countOfAlbums; 57 | } 58 | } 59 | 60 | class Java8Count { 61 | public Map countAlbums(Map> albumsByArtist) { 62 | // BEGIN COUNT_ALBUMS_VALUES_FOREACH 63 | Map countOfAlbums = new HashMap<>(); 64 | albumsByArtist.forEach((artist, albums) -> { 65 | countOfAlbums.put(artist, albums.size()); 66 | }); 67 | // END COUNT_ALBUMS_VALUES_FOREACH 68 | return countOfAlbums; 69 | } 70 | } 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter3/Iteration.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter3; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Artist; 4 | 5 | import java.util.Iterator; 6 | import java.util.List; 7 | 8 | public class Iteration { 9 | 10 | public int externalCountArtistsFromLondon(List allArtists) { 11 | // BEGIN external_count_londoners 12 | int count = 0; 13 | for (Artist artist : allArtists) { 14 | if (artist.isFrom("London")) { 15 | count++; 16 | } 17 | } 18 | // END external_count_londoners 19 | return count; 20 | } 21 | 22 | public int externalCountArtistsFromLondonExpanded(List allArtists) { 23 | // BEGIN external_count_londoners_expanded 24 | int count = 0; 25 | Iterator iterator = allArtists.iterator(); 26 | while(iterator.hasNext()) { 27 | Artist artist = iterator.next(); 28 | if (artist.isFrom("London")) { 29 | count++; 30 | } 31 | } 32 | // END external_count_londoners_expanded 33 | return count; 34 | } 35 | 36 | 37 | public long internalCountArtistsFromLondon(List allArtists) { 38 | // BEGIN internal_count_londoners 39 | long count = allArtists.stream() 40 | .filter(artist -> artist.isFrom("London")) 41 | .count(); 42 | // END internal_count_londoners 43 | return count; 44 | } 45 | 46 | public void filterArtistsFromLondon(List allArtists) { 47 | // BEGIN filter_londoners 48 | allArtists.stream() 49 | .filter(artist -> artist.isFrom("London")); 50 | // END filter_londoners 51 | } 52 | 53 | public void filterArtistsFromLondonPrinted(List allArtists) { 54 | // BEGIN filter_londoners_printed 55 | allArtists.stream() 56 | .filter(artist -> { 57 | System.out.println(artist.getName()); 58 | return artist.isFrom("London"); 59 | }); 60 | // END filter_londoners_printed 61 | } 62 | 63 | public long internalCountArtistsFromLondonPrinted(List allArtists) { 64 | // BEGIN internal_count_londoners_printed 65 | long count = allArtists.stream() 66 | .filter(artist -> { 67 | System.out.println(artist.getName()); 68 | return artist.isFrom("London"); 69 | }) 70 | .count(); 71 | // END internal_count_londoners_printed 72 | return count; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter8/SingleResponsibilityPrinciple.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter8; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | public class SingleResponsibilityPrinciple { 6 | 7 | public static interface PrimeCounter { 8 | long countPrimes(int upTo); 9 | } 10 | 11 | public static class ImperativeSingleMethodPrimeCounter implements PrimeCounter { 12 | @Override 13 | // BEGIN imperative_single_method 14 | public long countPrimes(int upTo) { 15 | long tally = 0; 16 | for (int i = 1; i < upTo; i++) { 17 | boolean isPrime = true; 18 | for (int j = 2; j < i; j++) { 19 | if (i % j == 0) { 20 | isPrime = false; 21 | } 22 | } 23 | if (isPrime) { 24 | tally++; 25 | } 26 | } 27 | return tally; 28 | } 29 | // END imperative_single_method 30 | } 31 | 32 | public static class ImperativeRefactoredPrimeCounter implements PrimeCounter { 33 | @Override 34 | // BEGIN imperative_refactored 35 | public long countPrimes(int upTo) { 36 | long tally = 0; 37 | for (int i = 1; i < upTo; i++) { 38 | if (isPrime(i)) { 39 | tally++; 40 | } 41 | } 42 | return tally; 43 | } 44 | 45 | private boolean isPrime(int number) { 46 | for (int i = 2; i < number; i++) { 47 | if (number % i == 0) { 48 | return false; 49 | } 50 | } 51 | return true; 52 | } 53 | // END imperative_refactored 54 | } 55 | 56 | public static class FunctionalPrimeCounter implements PrimeCounter { 57 | 58 | @Override 59 | // BEGIN functional 60 | public long countPrimes(int upTo) { 61 | return IntStream.range(1, upTo) 62 | .filter(this::isPrime) 63 | .count(); 64 | } 65 | 66 | private boolean isPrime(int number) { 67 | return IntStream.range(2, number) 68 | .allMatch(x -> (number % x) != 0); 69 | } 70 | // END functional 71 | } 72 | 73 | public static class ParallelFunctionalPrimeCounter implements PrimeCounter { 74 | @Override 75 | // BEGIN parallel_functional 76 | public long countPrimes(int upTo) { 77 | return IntStream.range(1, upTo) 78 | .parallel() 79 | .filter(this::isPrime) 80 | .count(); 81 | } 82 | 83 | private boolean isPrime(int number) { 84 | return IntStream.range(2, number) 85 | .allMatch(x -> (number % x) != 0); 86 | } 87 | // END parallel_functional 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter9/FutureAlbumLookup.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter9; 2 | 3 | import com.insightfullogic.java8.examples.chapter1.Album; 4 | import com.insightfullogic.java8.examples.chapter1.Artist; 5 | import com.insightfullogic.java8.examples.chapter1.Track; 6 | 7 | import java.util.List; 8 | import java.util.concurrent.ExecutionException; 9 | import java.util.concurrent.ExecutorService; 10 | import java.util.concurrent.Executors; 11 | import java.util.concurrent.Future; 12 | 13 | public class FutureAlbumLookup implements AlbumLookup { 14 | 15 | private static final ExecutorService service = Executors.newFixedThreadPool(2); 16 | 17 | private final List tracks; 18 | private final List artists; 19 | 20 | public FutureAlbumLookup(List tracks, List artists) { 21 | this.tracks = tracks; 22 | this.artists = artists; 23 | } 24 | 25 | // BEGIN lookupByName 26 | @Override 27 | public Album lookupByName(String albumName) { 28 | Future trackLogin = loginTo("track"); // <1> 29 | Future artistLogin = loginTo("artist"); 30 | 31 | try { 32 | Future> tracks = lookupTracks(albumName, trackLogin.get()); // <2> 33 | Future> artists = lookupArtists(albumName, artistLogin.get()); 34 | 35 | return new Album(albumName, tracks.get(), artists.get()); // <3> 36 | } catch (InterruptedException | ExecutionException e) { 37 | throw new AlbumLookupException(e.getCause()); // <4> 38 | } 39 | } 40 | // END lookupByName 41 | 42 | // ----------------- FAKE LOOKUP METHODS ----------------- 43 | // Represent API lookup on external services 44 | 45 | private Future> lookupArtists(String albumName, Credentials credentials) { 46 | return service.submit(() -> { 47 | fakeWaitingForExternalWebService(); 48 | return artists; 49 | }); 50 | } 51 | 52 | private Future> lookupTracks(String albumName, Credentials credentials) { 53 | return service.submit(() -> { 54 | return tracks; 55 | }); 56 | } 57 | 58 | private Future loginTo(String serviceName) { 59 | return service.submit(() -> { 60 | if ("track".equals(serviceName)) { 61 | fakeWaitingForExternalWebService(); 62 | } 63 | return new Credentials(); 64 | }); 65 | } 66 | 67 | private void fakeWaitingForExternalWebService() throws InterruptedException { 68 | Thread.sleep(1000); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter6/WordCounting.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter6; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.util.Map; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | import static java.util.Comparator.comparing; 12 | import static java.util.stream.Collectors.counting; 13 | import static java.util.stream.Collectors.groupingBy; 14 | 15 | public class WordCounting { 16 | 17 | public static void main(String[] args) { 18 | InputStream enWiki = WordCounting.class.getResourceAsStream("enwiki-20131230-stubs-meta-hist-incr.xml"); 19 | new WordCounting().countUsers(enWiki); 20 | // InputStream huckleberryFinn = WordCounting.class.getResourceAsStream("huckleberry_finn"); 21 | // new WordCounting().countWords(huckleberryFinn); 22 | } 23 | 24 | private static final Pattern username = Pattern.compile("\\s+(.*?)"); 25 | 26 | public void countUsers(InputStream stream) { 27 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { 28 | Map counts = reader 29 | .lines() 30 | .parallel() 31 | .filter(line -> line.contains("")) 32 | .map(line -> { 33 | Matcher matcher = username.matcher(line); 34 | matcher.find(); 35 | return matcher.group(1); 36 | }) 37 | .collect(groupingBy(word -> word, counting())); 38 | 39 | counts.forEach((word, count) -> System.out.println(word + " -> " + count)); 40 | } catch (IOException e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | 45 | private static final Pattern space = Pattern.compile("\\s+"); 46 | 47 | public void countWords(InputStream stream) { 48 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { 49 | Map counts = reader 50 | .lines() 51 | .flatMap(space::splitAsStream) 52 | .map(String::trim) 53 | .filter(word -> !word.isEmpty()) 54 | .collect(groupingBy(word -> word, counting())); 55 | 56 | counts.forEach((word, count) -> System.out.println(word + " -> " + count)); 57 | } catch (IOException e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/examples/chapter6/ManualDiceRolls.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter6; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.concurrent.*; 7 | 8 | // BEGIN ManualDiceRolls 9 | public class ManualDiceRolls { 10 | 11 | private static final int N = 100000000; 12 | 13 | private final double fraction; 14 | private final Map results; 15 | private final int numberOfThreads; 16 | private final ExecutorService executor; 17 | private final int workPerThread; 18 | 19 | public static void main(String[] args) { 20 | ManualDiceRolls roles = new ManualDiceRolls(); 21 | roles.simulateDiceRoles(); 22 | } 23 | 24 | public ManualDiceRolls() { 25 | fraction = 1.0 / N; 26 | results = new ConcurrentHashMap<>(); 27 | numberOfThreads = Runtime.getRuntime().availableProcessors(); 28 | executor = Executors.newFixedThreadPool(numberOfThreads); 29 | workPerThread = N / numberOfThreads; 30 | } 31 | 32 | public void simulateDiceRoles() { 33 | List> futures = submitJobs(); 34 | awaitCompletion(futures); 35 | printResults(); 36 | } 37 | 38 | private void printResults() { 39 | results.entrySet() 40 | .forEach(System.out::println); 41 | } 42 | 43 | private List> submitJobs() { 44 | List> futures = new ArrayList<>(); 45 | for (int i = 0; i < numberOfThreads; i++) { 46 | futures.add(executor.submit(makeJob())); 47 | } 48 | return futures; 49 | } 50 | 51 | private Runnable makeJob() { 52 | return () -> { 53 | ThreadLocalRandom random = ThreadLocalRandom.current(); 54 | for (int i = 0; i < workPerThread; i++) { 55 | int entry = twoDiceThrows(random); 56 | accumulateResult(entry); 57 | } 58 | }; 59 | } 60 | 61 | private void accumulateResult(int entry) { 62 | results.compute(entry, (key, previous) -> 63 | previous == null ? fraction 64 | : previous + fraction 65 | ); 66 | } 67 | 68 | private int twoDiceThrows(ThreadLocalRandom random) { 69 | int firstThrow = random.nextInt(1, 7); 70 | int secondThrow = random.nextInt(1, 7); 71 | return firstThrow + secondThrow; 72 | } 73 | 74 | private void awaitCompletion(List> futures) { 75 | futures.forEach((future) -> { 76 | try { 77 | future.get(); 78 | } catch (InterruptedException | ExecutionException e) { 79 | e.printStackTrace(); 80 | } 81 | }); 82 | executor.shutdown(); 83 | } 84 | 85 | } 86 | // END ManualDiceRolls 87 | -------------------------------------------------------------------------------- /src/test/java/com/insightfullogic/java8/examples/chapter5/EncounterOrderTest.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.examples.chapter5; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | 6 | import java.util.HashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import static java.util.Arrays.asList; 11 | import static java.util.stream.Collectors.toList; 12 | import static junit.framework.Assert.assertEquals; 13 | import static org.hamcrest.MatcherAssert.assertThat; 14 | import static org.hamcrest.Matchers.hasItem; 15 | 16 | public class EncounterOrderTest { 17 | 18 | @Test 19 | public void listToStream() { 20 | // BEGIN LIST_TO_STREAM 21 | List numbers = asList(1, 2, 3, 4); 22 | 23 | List sameOrder = numbers.stream() 24 | .collect(toList()); 25 | assertEquals(numbers, sameOrder); 26 | // END LIST_TO_STREAM 27 | } 28 | 29 | // NB: to actually get this to fail you need to reverse the order of the numbers. 30 | @Ignore 31 | @Test 32 | public void hashSetToStream() { 33 | // BEGIN HASHSET_TO_STREAM 34 | Set numbers = new HashSet<>(asList(4, 3, 2, 1)); 35 | 36 | List sameOrder = numbers.stream() 37 | .collect(toList()); 38 | 39 | // This may not pass 40 | assertEquals(asList(4, 3, 2, 1), sameOrder); 41 | // END HASHSET_TO_STREAM 42 | } 43 | 44 | @Test 45 | public void hashSetToStreamSorted() { 46 | // BEGIN HASHSET_TO_STREAM_SORTED 47 | Set numbers = new HashSet<>(asList(4, 3, 2, 1)); 48 | 49 | List sameOrder = numbers.stream() 50 | .sorted() 51 | .collect(toList()); 52 | 53 | assertEquals(asList(1, 2, 3, 4), sameOrder); 54 | // END HASHSET_TO_STREAM_SORTED 55 | } 56 | 57 | @Test 58 | public void toStreamMapped() { 59 | // BEGIN TO_STREAM_MAPPED 60 | List numbers = asList(1, 2, 3, 4); 61 | 62 | List stillOrdered = numbers.stream() 63 | .map(x -> x + 1) 64 | .collect(toList()); 65 | 66 | // Reliable encounter ordering 67 | assertEquals(asList(2, 3, 4, 5), stillOrdered); 68 | 69 | Set unordered = new HashSet<>(numbers); 70 | 71 | List stillUnordered = unordered.stream() 72 | .map(x -> x + 1) 73 | .collect(toList()); 74 | 75 | // Can't assume encounter ordering 76 | assertThat(stillUnordered, hasItem(2)); 77 | assertThat(stillUnordered, hasItem(3)); 78 | assertThat(stillUnordered, hasItem(4)); 79 | assertThat(stillUnordered, hasItem(5)); 80 | // END TO_STREAM_MAPPED 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/insightfullogic/java8/answers/chapter6/OptimisationExampleFixed.java: -------------------------------------------------------------------------------- 1 | package com.insightfullogic.java8.answers.chapter6; 2 | 3 | import org.openjdk.jmh.Main; 4 | import org.openjdk.jmh.annotations.*; 5 | import org.openjdk.jmh.runner.RunnerException; 6 | 7 | import java.io.IOException; 8 | import java.util.ArrayList; 9 | import java.util.LinkedList; 10 | import java.util.List; 11 | import java.util.stream.IntStream; 12 | 13 | @State(Scope.Thread) 14 | @BenchmarkMode(Mode.AverageTime) 15 | public class OptimisationExampleFixed { 16 | 17 | public static void main(String[] ignore) throws RunnerException, IOException { 18 | final String[] args = { 19 | ".*OptimisationExampleFixed.*", 20 | "-wi", 21 | "10", 22 | "-i", 23 | "10", 24 | "-f", 25 | "1" 26 | }; 27 | Main.main(args); 28 | } 29 | 30 | private List arrayListOfNumbers; 31 | private List linkedListOfNumbers; 32 | 33 | @Setup 34 | public void init() { 35 | arrayListOfNumbers= new ArrayList<>(); 36 | addNumbers(arrayListOfNumbers); 37 | 38 | linkedListOfNumbers = new LinkedList<>(); 39 | addNumbers(linkedListOfNumbers); 40 | } 41 | 42 | private void addNumbers(List container) { 43 | IntStream.range(0, 1_000_000) 44 | .forEach(container::add); 45 | } 46 | 47 | @GenerateMicroBenchmark 48 | public int slowSumOfSquares() { 49 | return linkedListOfNumbers.parallelStream() 50 | .map(x -> x * x) 51 | .reduce(0, (acc, x) -> acc + x); 52 | } 53 | 54 | @GenerateMicroBenchmark 55 | public int serialSlowSumOfSquares() { 56 | return linkedListOfNumbers.stream() 57 | .map(x -> x * x) 58 | .reduce(0, (acc, x) -> acc + x); 59 | } 60 | 61 | @GenerateMicroBenchmark 62 | public int intermediateSumOfSquares() { 63 | return arrayListOfNumbers.parallelStream() 64 | .map(x -> x * x) 65 | .reduce(0, (acc, x) -> acc + x); 66 | } 67 | 68 | @GenerateMicroBenchmark 69 | public int serialIntermediateSumOfSquares() { 70 | return arrayListOfNumbers.stream() 71 | .map(x -> x * x) 72 | .reduce(0, (acc, x) -> acc + x); 73 | } 74 | 75 | @GenerateMicroBenchmark 76 | public int fastSumOfSquares() { 77 | return arrayListOfNumbers.parallelStream() 78 | .mapToInt(x -> x * x) 79 | .sum(); 80 | } 81 | 82 | @GenerateMicroBenchmark 83 | public int serialFastSumOfSquares() { 84 | return arrayListOfNumbers.stream() 85 | .mapToInt(x -> x * x) 86 | .sum(); 87 | } 88 | 89 | } 90 | --------------------------------------------------------------------------------