├── .claude └── settings.local.json ├── .github ├── dependabot.yml └── workflows │ └── gradle.yml ├── .gitignore ├── CLAUDE.md ├── README.md ├── build.gradle ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── jmh └── java │ ├── benchmarks │ └── LongStreamBenchmark.java │ ├── manning │ └── ParallelStreamBenchmark.java │ └── parallel │ ├── CustomPoolBenchmark.java │ └── DoublingDemo.java ├── main ├── java │ ├── DeferredExecution.java │ ├── IterableDemo.java │ ├── IteratingOverAMap.java │ ├── Iteration.java │ ├── MyChildInterface.java │ ├── MyInterface.java │ ├── PalindromeChecker.java │ ├── Primes.java │ ├── PrimesDemo.java │ ├── Printing.java │ ├── ReduceProduct.java │ ├── StringLengthDemo.java │ ├── SumDoubles.java │ ├── Summarizing.java │ ├── UseFilenameFilter.java │ ├── collectors │ │ ├── Actor.java │ │ ├── AddCollectionToMap.java │ │ ├── Book.java │ │ ├── CollectorsDemo.java │ │ ├── ImmutableCollections.java │ │ ├── Movie.java │ │ └── MysteryMen.java │ ├── concurrency │ │ ├── AllOfDemo.java │ │ ├── AwaitQuiesence.java │ │ ├── CommonPoolSize.java │ │ ├── CompletableFutureDemos.java │ │ ├── FutureDemo.java │ │ ├── ParallelDemo.java │ │ ├── Product.java │ │ ├── SequentialToParallel.java │ │ └── Timer.java │ ├── datetime │ │ ├── AddingAndSubtracting.java │ │ ├── Adjusters.java │ │ ├── AntarcticaTimeZones.java │ │ ├── CTtoIndia.java │ │ ├── ConvertDate.java │ │ ├── DateTimeFormatterDemo.java │ │ ├── DaysToElection.java │ │ ├── FunnyOffsets.java │ │ ├── JavaTimeDemos.java │ │ ├── MonthMethods.java │ │ ├── NowFactoryMethod.java │ │ ├── NumberOfTimeZones.java │ │ ├── OfFactoryMethod.java │ │ ├── PaydayAdjuster.java │ │ ├── PirateQuery.java │ │ ├── RegionIdsByOffset.java │ │ └── Timer.java │ ├── defaults │ │ ├── Company.java │ │ ├── CompanyEmployee.java │ │ ├── DefaultMapMethods.java │ │ ├── DefaultMethodsDemo.java │ │ ├── Employee.java │ │ ├── ForeachDemo.java │ │ └── StaticMethodsDemo.java │ ├── fileio │ │ ├── FileList.java │ │ ├── Jumble.java │ │ ├── ProcessDictionary.java │ │ ├── SearchForFiles.java │ │ └── WalkTheTree.java │ ├── functionpackage │ │ ├── ForEachDemo.java │ │ ├── ImplementConsumer.java │ │ ├── ImplementFunction.java │ │ ├── ImplementPredicate.java │ │ └── ImplementSupplier.java │ ├── generics │ │ ├── Demo.java │ │ ├── Employee.java │ │ ├── ProcessColors.java │ │ ├── ProcessNumbers.java │ │ └── SafeVarargsDemo.java │ ├── gui │ │ └── MyUI.java │ ├── lambdas │ │ ├── Algorithms.java │ │ ├── ClosureVariables.java │ │ ├── CompositionDemo.java │ │ ├── ConsumerDemo.java │ │ ├── ExceptionHandling.java │ │ ├── FunctionWithException.java │ │ ├── LambdasDemo.java │ │ ├── MethodReferencesDemo.java │ │ ├── MyFilter.java │ │ ├── RunnableDemo.java │ │ └── UseFilenameFilter.java │ ├── mapvsflatmap │ │ ├── Customer.java │ │ ├── FlatMapDemo.java │ │ ├── MapExamples.java │ │ ├── Order.java │ │ ├── Person.java │ │ ├── UsePerson.java │ │ └── WordMap.java │ ├── objects │ │ └── ObjectsDemo.java │ ├── optionals │ │ ├── Company.java │ │ ├── Department.java │ │ ├── Employee.java │ │ ├── HR.java │ │ ├── Manager.java │ │ ├── OptionalDemo.java │ │ ├── OptionalMap.java │ │ ├── UseDepartment.java │ │ └── UseOptionalMap.java │ ├── refactoring │ │ └── LoopsSortsAndIfs.java │ ├── sorting │ │ ├── Golfer.java │ │ ├── SortGolfers.java │ │ ├── SortingDemo.java │ │ └── SortingMaps.java │ ├── streams │ │ ├── Book.java │ │ ├── BoxedStreams.java │ │ ├── ConcatStreams.java │ │ ├── CountingElements.java │ │ ├── CreatingStreams.java │ │ ├── Employee.java │ │ ├── FindFirstAny.java │ │ ├── GroupingDemo.java │ │ ├── LazyStreams.java │ │ ├── MaxAndMin.java │ │ ├── PalindromeEvaluator.java │ │ ├── PartitionDemo.java │ │ ├── PeekDemo.java │ │ ├── ProcessDictionary.java │ │ ├── RandomStreams.java │ │ ├── ReduceDemo.java │ │ ├── Stats.java │ │ ├── StreamToIntStream.java │ │ ├── StreamsDemo.java │ │ ├── SumStringLengths.java │ │ ├── Team.java │ │ └── UsingCollect.java │ └── tasks │ │ ├── Task.java │ │ └── UseTasks.java └── resources │ ├── dict │ ├── README │ ├── connectives │ ├── propernames │ ├── web2 │ ├── web2a │ └── words │ ├── function_package.txt │ ├── mlb_team_salaries_2017.txt │ └── simple_file.txt └── test └── java ├── PalindromeCheckerTest.java ├── PrimesTest.java ├── collectors ├── CollectorsDemoTest.java └── ImmutableCollectionsTest.java ├── concurrency ├── AwaitQuiesenceTest.java ├── CompletableFutureDemosTest.java ├── CompletableFutureTests.java └── SequentialToParallelTest.java ├── datetime ├── AddingAndSubtractingTest.java ├── ConvertDateTest.java ├── PaydayAdjusterTest.java ├── RegionIdsByOffsetTest.java ├── TemporalAdjusterTests.java └── TemporalQueriesTests.java ├── defaults └── CompanyEmployeeTest.java ├── fileio ├── JumbleTest.java └── ProcessDictionaryTest.java ├── functionpackage └── ImplementPredicateTest.java ├── generics └── ProcessColorsTest.java ├── lambdas ├── AlgorithmsTest.java ├── CompositionDemoTest.java └── SupplierTest.java ├── mapvsflatmap ├── PersonConstructorTest.java ├── UsePersonTest.java └── WordMapTest.java ├── objects └── ObjectsDemoTest.java ├── optionals ├── HRTest.java └── OptionalDemoTest.java ├── sorting ├── SortingDemoTest.java └── SortingMapsTest.java └── streams ├── ConcatStreamsTest.java ├── PalindromeEvaluatorTest.java ├── PeekDemoTest.java └── StreamsDemoTest.java /.claude/settings.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "permissions": { 3 | "allow": [ 4 | "Bash(./gradlew test:*)", 5 | "Bash(java:*)", 6 | "Bash(find:*)", 7 | "Bash(ls:*)", 8 | "Bash(./gradlew:*)", 9 | "Bash(git add:*)" 10 | ], 11 | "deny": [] 12 | } 13 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gradle 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "10:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: org.openjdk.jmh:jmh-generator-annprocess 11 | versions: 12 | - "1.29" 13 | - dependency-name: org.openjdk.jmh:jmh-core 14 | versions: 15 | - "1.29" 16 | - dependency-name: org.junit.vintage:junit-vintage-engine 17 | versions: 18 | - 5.9.1 19 | - dependency-name: org.junit.jupiter:junit-jupiter 20 | versions: 21 | - 5.9.1 22 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Set up JDK 17 13 | uses: actions/setup-java@v1 14 | with: 15 | java-version: 17 16 | - name: Build with Gradle 17 | run: ./gradlew build 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | build/ 3 | .gradle/ 4 | gradle-app.setting 5 | !gradle-wrapper.jar 6 | 7 | # Java 8 | bin/ 9 | classes/ 10 | out/ 11 | *.class 12 | 13 | # IDE 14 | .idea/ 15 | .vscode/ 16 | .project 17 | .classpath 18 | .settings/ 19 | *.iml 20 | *.ipr 21 | *.iws 22 | 23 | # JMH (Benchmarking) 24 | jmh-result.json 25 | 26 | # JVM 27 | hs_err_pid* 28 | replay_pid* 29 | 30 | # OS 31 | .DS_Store 32 | .DS_Store? 33 | ._* 34 | .Spotlight-V100 35 | .Trashes 36 | ehthumbs.db 37 | Thumbs.db 38 | 39 | # Test reports (backup - build/ should catch these) 40 | test-results/ 41 | jacoco/ 42 | 43 | # Gradle build scan cache 44 | .gradle/build-scan-data/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java 8 Recipes 2 | 3 | Source code for Modern Java Recipes (O'Reilly, 2017) 4 | 5 | http://shop.oreilly.com/product/0636920056669.do 6 | 7 | ## Project Status 8 | 9 | This project has been modernized and updated with the latest tooling: 10 | 11 | - **Java 17** (using Gradle toolchain support) 12 | - **Gradle 8.14.2** (latest stable) 13 | - **JUnit 5.13.2** (migrated from JUnit 4, using BOM management) 14 | - **Modern build configuration** with dependency management 15 | 16 | ## Requirements 17 | 18 | - Java 17 or later (automatically managed by Gradle toolchain) 19 | - No additional setup required - Gradle wrapper handles everything 20 | 21 | ## Quick Start 22 | 23 | ```bash 24 | # Clone the repository 25 | git clone 26 | cd java_8_recipes 27 | 28 | # Run tests 29 | ./gradlew test 30 | 31 | # Build the project 32 | ./gradlew build 33 | ``` 34 | 35 | ## IDE Setup 36 | 37 | ### IntelliJ IDEA 38 | 1. Clone repo or download zip and extract 39 | 2. Use `File -> Open` or if no project is open, `Import` 40 | 3. Navigate to the `build.gradle` file inside the project 41 | 4. Click enter and accept all the defaults 42 | 5. IntelliJ will automatically configure the project with Java 17 43 | 44 | ### Eclipse (and Eclipse-based tools, like STS) 45 | 1. Open a command prompt in the root of the project 46 | 2. Type `./gradlew cleanEclipse eclipse` (Unix/Mac) or `gradlew cleanEclipse eclipse` (Windows) 47 | 3. Wait for the dependencies to be downloaded 48 | 4. Choose `File -> Import… -> General -> Existing Projects into Workspace` 49 | 5. Navigate to the root of the project and select it 50 | 51 | ## Testing 52 | 53 | All tests have been migrated to JUnit 5 and use modern testing patterns: 54 | 55 | ```bash 56 | # Run all tests 57 | ./gradlew test 58 | 59 | # Run tests with detailed output 60 | ./gradlew test --info 61 | 62 | # Run specific test class 63 | ./gradlew test --tests "concurrency.CompletableFutureTests" 64 | ``` 65 | 66 | ## Project Structure 67 | 68 | The project contains examples and tests for Java 8+ features including: 69 | 70 | - **Concurrency**: CompletableFuture, parallel streams 71 | - **Streams**: Operations, collectors, patterns 72 | - **Optional**: Usage patterns and best practices 73 | - **Date/Time**: Modern java.time API 74 | - **Lambdas**: Functional programming patterns 75 | - **Collectors**: Custom and built-in collectors 76 | 77 | ## Recent Updates 78 | 79 | - Upgraded from Gradle 7.5.1 to 8.14.2 80 | - Migrated from Java 11 to Java 17 (using toolchain) 81 | - Complete migration from JUnit 4 to JUnit 5 82 | - Modernized dependency management with version catalogs 83 | - Removed deprecated JUnit vintage engine dependency 84 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'jacoco' 4 | alias(libs.plugins.versions) 5 | alias(libs.plugins.version.catalog.update) 6 | alias(libs.plugins.jmh.gradle) 7 | } 8 | 9 | java { 10 | toolchain { 11 | languageVersion = JavaLanguageVersion.of(17) 12 | } 13 | } 14 | 15 | jacocoTestReport.dependsOn(test) 16 | 17 | repositories { 18 | mavenCentral() 19 | } 20 | 21 | test { 22 | useJUnitPlatform() 23 | maxParallelForks = (int) (Runtime.runtime.availableProcessors() / 2) 24 | } 25 | 26 | dependencies { 27 | // JUnit BOM for consistent versions 28 | testImplementation platform("org.junit:junit-bom:${libs.versions.junit.get()}") 29 | 30 | // JUnit bundle (includes vintage engine) 31 | testImplementation libs.bundles.junit 32 | 33 | // Add explicit JUnit Platform Launcher to fix version mismatch 34 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher' 35 | 36 | // Mockito bundle (inline and JUnit Jupiter engine) 37 | testImplementation libs.bundles.mockito 38 | 39 | // AssertJ 40 | testImplementation libs.assertj 41 | 42 | // JMH 43 | jmh libs.bundles.jmh 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | assertj = "3.27.6" 3 | jmh = "1.37" 4 | junit = "5.13.2" 5 | mockito = "5.2.0" 6 | 7 | [libraries] 8 | assertj = { module = "org.assertj:assertj-core", version.ref = "assertj" } 9 | jmh-ann-proc = { module = "org.openjdk.jmh:jmh-generator-annprocess", version.ref = "jmh" } 10 | jmh-core = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh" } 11 | junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" } 12 | junit-vintage = { module = "org.junit.vintage:junit-vintage-engine" } 13 | mockito-inline = { module = "org.mockito:mockito-inline", version.ref = "mockito" } 14 | mockito-junit = "org.mockito:mockito-junit-jupiter:5.20.0" 15 | 16 | [bundles] 17 | jmh = [ 18 | "jmh-ann-proc", 19 | "jmh-core", 20 | ] 21 | junit = [ 22 | "junit-jupiter", 23 | ] 24 | mockito = [ 25 | "mockito-inline", 26 | "mockito-junit", 27 | ] 28 | 29 | [plugins] 30 | jmh-gradle = "me.champeau.jmh:0.7.3" 31 | version-catalog-update = "nl.littlerobots.version-catalog-update:1.0.0" 32 | versions = "com.github.ben-manes.versions:0.53.0" 33 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kousen/java_8_recipes/6b36a7adcbf37de0c2b86625431fcc34740a4034/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'java_8_recipes' 2 | 3 | -------------------------------------------------------------------------------- /src/jmh/java/benchmarks/LongStreamBenchmark.java: -------------------------------------------------------------------------------- 1 | package benchmarks; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | 5 | import java.util.List; 6 | import java.util.concurrent.TimeUnit; 7 | import java.util.logging.Logger; 8 | import java.util.stream.Collectors; 9 | import java.util.stream.LongStream; 10 | 11 | // Sept 2, 2022. M1 Max 64GB RAM, 10 cores 12 | // Benchmark Mode Cnt Score Error Units 13 | // LongStreamBenchmark.longValue avgt 10 0.568 ± 0.015 ms/op 14 | // LongStreamBenchmark.valueOf avgt 10 2.624 ± 0.019 ms/op 15 | 16 | @SuppressWarnings("ALL") 17 | @BenchmarkMode(Mode.AverageTime) 18 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 19 | @State(Scope.Thread) 20 | @Fork(value = 2, jvmArgs = {"-Xms4G", "-Xmx4G"}) 21 | public class LongStreamBenchmark { 22 | private static final long N = 1_000_000L; 23 | private List nums; 24 | 25 | private Logger logger = Logger.getLogger(this.getClass().getName()); 26 | 27 | public LongStreamBenchmark() { 28 | logger.info("Creating list of " + N + " longs"); 29 | nums = LongStream.rangeClosed(1, N) 30 | .boxed() 31 | .collect(Collectors.toList()); 32 | } 33 | 34 | @Benchmark 35 | public long valueOf() { 36 | return nums.stream() 37 | .mapToLong(Long::valueOf) 38 | .sum(); 39 | } 40 | 41 | @Benchmark 42 | public long longValue() { 43 | return nums.stream() 44 | .mapToLong(Long::longValue) 45 | .sum(); 46 | } 47 | 48 | @TearDown(Level.Invocation) 49 | public void tearDown() { 50 | System.gc(); 51 | } 52 | } -------------------------------------------------------------------------------- /src/jmh/java/manning/ParallelStreamBenchmark.java: -------------------------------------------------------------------------------- 1 | package manning; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | import java.util.stream.LongStream; 7 | import java.util.stream.Stream; 8 | 9 | // From Java 8 and 9 in Action (now called Modern Java in Action) 10 | 11 | // Sept 2, 2022. M1 Max 64GB RAM, 10 cores 12 | // ParallelStreamBenchmark.iterativeSum avgt 10 3.256 ± 0.011 ms/op 13 | // ParallelStreamBenchmark.parallelLongStreamSum avgt 10 0.484 ± 0.003 ms/op 14 | // ParallelStreamBenchmark.parallelStreamSum avgt 10 50.626 ± 1.095 ms/op 15 | // ParallelStreamBenchmark.sequentialLongStreamSum avgt 10 6.381 ± 0.027 ms/op 16 | // ParallelStreamBenchmark.sequentialStreamSum avgt 10 58.474 ± 0.555 ms/op 17 | 18 | @SuppressWarnings("ALL") 19 | @BenchmarkMode(Mode.AverageTime) 20 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 21 | @State(Scope.Thread) 22 | @Fork(value = 2, jvmArgs = {"-Xms4G", "-Xmx4G"}) 23 | public class ParallelStreamBenchmark { 24 | private static final long N = 10_000_000L; 25 | 26 | @Benchmark 27 | public long iterativeSum() { 28 | long result = 0; 29 | for (long i = 1L; i <= N; i++) { 30 | result += i; 31 | } 32 | return result; 33 | } 34 | 35 | @Benchmark // Slowest possible stream 36 | public long sequentialStreamSum() { 37 | return Stream.iterate(1L, i -> i + 1) // Stream 38 | .limit(N) 39 | .reduce(0L, Long::sum); 40 | } 41 | 42 | @Benchmark 43 | public long parallelStreamSum() { 44 | return Stream.iterate(1L, i -> i + 1) 45 | .limit(N) 46 | .parallel() 47 | .reduce(0L, Long::sum); 48 | } 49 | 50 | @Benchmark // Fastest possible stream 51 | public long sequentialLongStreamSum() { 52 | return LongStream.rangeClosed(1, N).sum(); 53 | } 54 | 55 | @Benchmark 56 | public long parallelLongStreamSum() { 57 | return LongStream.rangeClosed(1, N) 58 | .parallel() 59 | .sum(); 60 | } 61 | 62 | @TearDown(Level.Invocation) 63 | public void tearDown() { 64 | System.gc(); 65 | } 66 | } -------------------------------------------------------------------------------- /src/jmh/java/parallel/CustomPoolBenchmark.java: -------------------------------------------------------------------------------- 1 | package parallel; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | 5 | import java.util.concurrent.ExecutionException; 6 | import java.util.concurrent.ForkJoinPool; 7 | import java.util.concurrent.ForkJoinTask; 8 | import java.util.concurrent.TimeUnit; 9 | import java.util.stream.LongStream; 10 | 11 | // Sept 2, 2022. M1 Max 64GB RAM, 10 cores 12 | //Benchmark Mode Cnt Score Error Units 13 | // CustomPoolBenchmark.addNumsBiggerCommonPool avgt 10 0.254 ± 0.003 ms/op 14 | // CustomPoolBenchmark.addNumsCommonPool avgt 10 0.198 ± 0.011 ms/op 15 | // CustomPoolBenchmark.addNumsCustomFJPool avgt 10 0.968 ± 0.013 ms/op 16 | 17 | @BenchmarkMode(Mode.AverageTime) 18 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 19 | @State(Scope.Thread) 20 | @Fork(value = 2, jvmArgs = {"-Xms4G", "-Xmx4G"}) 21 | public class CustomPoolBenchmark { 22 | private static final int SIZE = 3_000_000; 23 | 24 | @Benchmark 25 | public long addNumsCommonPool() { 26 | return LongStream.rangeClosed(1, SIZE) 27 | .parallel() 28 | .sum(); 29 | } 30 | 31 | @Benchmark 32 | @Fork(jvmArgsAppend = "-Djava.util.concurrent.ForkJoinPool.common.parallelism=32") 33 | public long addNumsBiggerCommonPool() { 34 | return LongStream.rangeClosed(1, SIZE) 35 | .parallel() 36 | .sum(); 37 | } 38 | 39 | @Benchmark 40 | public long addNumsCustomFJPool() { 41 | long total; 42 | ForkJoinPool pool = new ForkJoinPool(16); 43 | ForkJoinTask task = pool.submit(() -> LongStream.rangeClosed(1, SIZE) 44 | .parallel() 45 | .sum() 46 | ); 47 | try { 48 | total = task.get(); 49 | } catch (InterruptedException | ExecutionException e) { 50 | throw new RuntimeException(e); 51 | } finally { 52 | pool.shutdown(); 53 | } 54 | return total; 55 | } 56 | 57 | @TearDown(Level.Invocation) 58 | public void tearDown() { 59 | System.gc(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/jmh/java/parallel/DoublingDemo.java: -------------------------------------------------------------------------------- 1 | package parallel; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | import java.util.stream.IntStream; 7 | 8 | // Sept 2, 2022. M1 Max 64GB RAM, 10 cores 9 | // Benchmark Mode Cnt Score Error Units 10 | // DoublingDemo.doubleAndSumParallel avgt 10 104.405 ± 0.283 ms/op 11 | // DoublingDemo.doubleAndSumSequential avgt 10 621.913 ± 1.067 ms/op 12 | 13 | @BenchmarkMode(Mode.AverageTime) 14 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 15 | @State(Scope.Thread) 16 | @Fork(value = 2, jvmArgs = {"-Xms4G", "-Xmx4G"}) 17 | public class DoublingDemo { 18 | public int doubleIt(int n) { 19 | try { 20 | Thread.sleep(100); 21 | } catch (InterruptedException ignored) { 22 | } 23 | return n * 2; 24 | } 25 | 26 | @Benchmark 27 | public int doubleAndSumSequential() { 28 | return IntStream.of(3, 1, 4, 1, 5, 9) 29 | .map(this::doubleIt) 30 | .sum(); 31 | } 32 | 33 | @Benchmark 34 | public int doubleAndSumParallel() { 35 | return IntStream.of(3, 1, 4, 1, 5, 9) 36 | .parallel() 37 | .map(this::doubleIt) 38 | .sum(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/DeferredExecution.java: -------------------------------------------------------------------------------- 1 | import java.util.logging.Level; 2 | import java.util.logging.Logger; 3 | 4 | public class DeferredExecution { 5 | private final Logger logger = Logger.getLogger(this.getClass().getName()); 6 | 7 | private String createExpensiveMessage(String msg) { 8 | System.out.println("Creating expensive message at " 9 | + logger.getLevel() + " level"); 10 | return "The message is " + msg; 11 | } 12 | 13 | public void logStuff(String message) { 14 | logger.info("The message is " + message); 15 | logger.info(() -> "The message is " + message); 16 | } 17 | 18 | public static void main(String[] args) { 19 | DeferredExecution de = new DeferredExecution(); 20 | de.logger.setLevel(Level.SEVERE); 21 | de.logStuff("logging at SEVERE level"); 22 | 23 | de.logger.setLevel(Level.WARNING); 24 | de.logStuff("logging at WARNING level"); 25 | 26 | de.logger.setLevel(Level.INFO); 27 | de.logStuff("logging at INFO level"); 28 | 29 | de.logger.setLevel(Level.FINE); 30 | de.logStuff("logging at FINE level"); 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/IterableDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.util.stream.Collectors; 3 | import java.util.stream.Stream; 4 | 5 | public class IterableDemo { 6 | // @SuppressWarnings("Convert2MethodRef") 7 | public static void main(String[] args) { 8 | List nums = Arrays.asList(3, 1, 4, 1, 5, 9); 9 | // forEach loop 10 | for (Integer num : nums) { 11 | System.out.println(num); 12 | } 13 | 14 | // lambda expression 15 | nums.forEach(x -> System.out.println(x)); 16 | 17 | // method reference 18 | nums.forEach(System.out::println); 19 | 20 | Set sizes = Stream.of("this", "is", "a", "list", "of", "strings") 21 | .map(String::length) 22 | .filter(n -> n % 2 == 0) 23 | .collect(Collectors.toCollection(TreeSet::new)); 24 | System.out.println(sizes.getClass().getName()); 25 | System.out.println("Even lengths: " + sizes); 26 | 27 | Map map = Stream.of("this", "is", "a", "list", "of", "strings") 28 | .collect(Collectors.toMap(e -> e, String::length)); 29 | System.out.println(map); 30 | 31 | map.forEach((k,v) -> System.out.println(k + ": " + v)); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/IteratingOverAMap.java: -------------------------------------------------------------------------------- 1 | import java.util.Map; 2 | import java.util.Set; 3 | import java.util.stream.Collectors; 4 | import java.util.stream.Stream; 5 | 6 | public class IteratingOverAMap { 7 | public static void main(String[] args) { 8 | String s = "this is a string with individual words of varying lengths " + 9 | "to be used in an example that parses it and adds them to a map " + 10 | "for later printing"; 11 | String[] strings = s.split(" "); 12 | 13 | Map> stringMap = Stream.of(strings) 14 | .collect(Collectors.groupingBy(String::length, Collectors.toSet())); 15 | 16 | 17 | // Java 7 printing a map 18 | System.out.printf("len words%n"); 19 | for (Map.Entry> entry : stringMap.entrySet()) { 20 | System.out.printf("%2d: %s%n", entry.getKey(), entry.getValue()); 21 | } 22 | 23 | // Java 8 printing a map 24 | System.out.printf("len words%n"); 25 | stringMap.forEach((len, stringSet) -> 26 | System.out.printf("%2d: %s%n", len, stringSet)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/Iteration.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.HashMap; 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.function.Consumer; 6 | 7 | public class Iteration { 8 | public static void main(String[] args) { 9 | List integers = Arrays.asList(3, 1, 4, 1, 5, 9); 10 | 11 | // Implement Consumer using anonymous inner class 12 | integers.forEach(new Consumer() { 13 | @Override 14 | public void accept(Integer integer) { 15 | System.out.println(integer); 16 | } 17 | }); 18 | 19 | // Full verbose form of lambda 20 | integers.forEach((Integer n) -> { 21 | System.out.println(n); 22 | }); 23 | 24 | // Simplified form of lambda 25 | integers.forEach(n -> System.out.println(n)); 26 | 27 | // Method reference 28 | integers.forEach(System.out::println); 29 | 30 | Map map = new HashMap<>(); 31 | map.put(86L, "Don Adams (Maxwell Smart)"); 32 | map.put(99L, "Barbara Feldon"); 33 | map.put(13L, "David Ketchum"); 34 | 35 | map.forEach((num, agent) -> 36 | System.out.printf("Agent %d, played by %s%n", num, agent)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/MyChildInterface.java: -------------------------------------------------------------------------------- 1 | public interface MyChildInterface extends MyInterface { 2 | int myOtherMethod(); 3 | } 4 | -------------------------------------------------------------------------------- /src/main/java/MyInterface.java: -------------------------------------------------------------------------------- 1 | @FunctionalInterface 2 | public interface MyInterface { 3 | int myMethod(); 4 | // int myOtherMethod(); 5 | 6 | default String sayHello() { 7 | return "Hello, World"; 8 | } 9 | 10 | static void myStaticMethod() { 11 | System.out.println("I'm a static method in an interface"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/PalindromeChecker.java: -------------------------------------------------------------------------------- 1 | @FunctionalInterface 2 | public interface PalindromeChecker { 3 | boolean isPalidrome(String s); 4 | 5 | static boolean checkPalindrome(String s) { 6 | StringBuilder sb = new StringBuilder(); 7 | for (char c : s.toCharArray()) { 8 | if (Character.isLetter(c)) { 9 | sb.append(c); 10 | } 11 | } 12 | 13 | String forward = sb.toString().toLowerCase(); 14 | String backward = sb.reverse().toString().toLowerCase(); 15 | return forward.equals(backward); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/Primes.java: -------------------------------------------------------------------------------- 1 | import java.util.OptionalInt; 2 | import java.util.stream.IntStream; 3 | 4 | public class Primes { 5 | public boolean isPrime(int num) { 6 | int limit = (int) (Math.sqrt(num) + 1); 7 | return num == 2 || num > 1 && IntStream.range(2, limit) 8 | .noneMatch(divisor -> num % divisor == 0); 9 | } 10 | 11 | public int nextPrime(int num) { 12 | OptionalInt optionalInt = IntStream.iterate(num + 1, n -> n + 1) 13 | .filter(this::isPrime) 14 | .findFirst(); 15 | 16 | return optionalInt.orElseThrow(IllegalArgumentException::new); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/PrimesDemo.java: -------------------------------------------------------------------------------- 1 | public class PrimesDemo { 2 | public static void main(String[] args) { 3 | Primes calculator = new Primes(); 4 | System.out.println(calculator.nextPrime(1000)); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/Printing.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.List; 3 | 4 | public class Printing { 5 | public static void main(String[] args) { 6 | List strings = Arrays.asList("this", "is", "a", "list", "of", "strings"); 7 | 8 | strings.forEach(System.out::println); 9 | strings.forEach(s -> System.out.println("The word is " + s)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/ReduceProduct.java: -------------------------------------------------------------------------------- 1 | import java.util.OptionalLong; 2 | import java.util.stream.IntStream; 3 | import java.util.stream.LongStream; 4 | 5 | public class ReduceProduct { 6 | public static void main(String[] args) { 7 | OptionalLong product = LongStream.rangeClosed(1, 5) 8 | .reduce((acc, n) -> acc * n); 9 | System.out.println(product); 10 | 11 | long productValue = LongStream.rangeClosed(1, 5) 12 | .reduce(1L, (acc, n) -> acc * n); 13 | 14 | 15 | System.out.println("Reduce default version"); 16 | int sum1 = IntStream.rangeClosed(1, 10) 17 | .reduce(0, (acc, n) -> { 18 | System.out.println("acc=" + acc + ", n=" + n); 19 | return acc + 2 * n; 20 | }); 21 | System.out.println(sum1); 22 | 23 | int sum = IntStream.rangeClosed(1, 10) 24 | .reduce(0, (acc, n) -> { 25 | System.out.println("acc=" + acc + ", n=" + n); 26 | return acc + n; 27 | }); 28 | System.out.println(sum); 29 | 30 | int total = IntStream.rangeClosed(1, 10) 31 | .reduce(0, Integer::sum); 32 | 33 | /* long productOptional = LongStream.rangeClosed(1, 5) 34 | .reduce((acc, n) -> { 35 | System.out.println("acc=" + acc + ", n=" + n); 36 | return acc * n; 37 | }).orElse(0); 38 | System.out.println(productOptional); 39 | 40 | long prod = LongStream.rangeClosed(1, 5) 41 | .reduce(1, (acc, n) -> { 42 | System.out.printf("acc=%d, n=%d%n", acc, n); 43 | return acc * n * 2; 44 | }); 45 | System.out.println(prod); */ 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/StringLengthDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.stream.Stream; 2 | 3 | public class StringLengthDemo { 4 | public static void main(String[] args) { 5 | int sum = Stream.of("this", "is", "a", "stream", "of", "strings") 6 | .mapToInt(String::length) 7 | .sum(); 8 | System.out.printf("The sum of the lengths is %d%n", sum); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/SumDoubles.java: -------------------------------------------------------------------------------- 1 | import java.util.stream.Stream; 2 | 3 | public class SumDoubles { 4 | public static void main(String[] args) { 5 | Integer sum = Stream.of(3, 1, 4, 1, 5, 9, 2, 6, 5) 6 | .reduce(0, (acc, n) -> { 7 | System.out.printf("acc=%d, n=%d%n", acc, n); 8 | return acc + 2 * n; 9 | }); 10 | 11 | System.out.printf("Sum = %s%n", sum); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/Summarizing.java: -------------------------------------------------------------------------------- 1 | import java.util.DoubleSummaryStatistics; 2 | import java.util.stream.DoubleStream; 3 | 4 | public class Summarizing { 5 | public static void main(String[] args) { 6 | DoubleSummaryStatistics stats = DoubleStream.generate(Math::random) 7 | .limit(1_000_000) 8 | .summaryStatistics(); 9 | 10 | System.out.println(stats); 11 | 12 | System.out.println("count: " + stats.getCount()); 13 | System.out.println("min : " + stats.getMin()); 14 | System.out.println("max : " + stats.getMax()); 15 | System.out.println("sum : " + stats.getSum()); 16 | System.out.println("ave : " + stats.getAverage()); 17 | 18 | DoubleStream.generate(Math::random) 19 | // .map(n -> { 20 | // System.out.println(n); 21 | // return n; 22 | // }) 23 | // .peek(System.out::println) 24 | .limit(10) 25 | .forEach(System.out::println); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /src/main/java/UseFilenameFilter.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FilenameFilter; 3 | import java.util.Arrays; 4 | 5 | @SuppressWarnings({"Convert2Lambda", "CodeBlock2Expr"}) 6 | public class UseFilenameFilter { 7 | public static void main(String[] args) { 8 | File directory = new File("./src/main/java"); 9 | System.out.println(directory.getAbsolutePath()); 10 | 11 | // Anonymous inner class 12 | String[] names = directory.list(new FilenameFilter() { 13 | @Override 14 | public boolean accept(File dir, String name) { 15 | return name.endsWith(".java"); 16 | } 17 | }); 18 | System.out.println(Arrays.asList(names)); 19 | 20 | // Use lambda expression instead 21 | names = directory.list((dir, name) -> name.endsWith(".java")); 22 | System.out.println(Arrays.asList(names)); 23 | 24 | // Explict data types 25 | names = directory.list((File dir, String name) -> name.endsWith(".java")); 26 | System.out.println(Arrays.asList(names)); 27 | 28 | names = directory.list((File dir, String name) -> { 29 | return name.endsWith(".java"); 30 | }); 31 | System.out.println(Arrays.asList(names)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/collectors/Actor.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | public class Actor { 4 | private String name; 5 | private String role; 6 | 7 | public Actor() {} 8 | 9 | public Actor(String name, String role) { 10 | this.name = name; 11 | this.role = role; 12 | } 13 | 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | public void setName(String name) { 19 | this.name = name; 20 | } 21 | 22 | public String getRole() { 23 | return role; 24 | } 25 | 26 | public void setRole(String role) { 27 | this.role = role; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/collectors/AddCollectionToMap.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.function.Function; 7 | import java.util.stream.Collectors; 8 | 9 | public class AddCollectionToMap { 10 | 11 | public static void main(String[] args) { 12 | List books = Arrays.asList( 13 | new Book(1, "Java 8 in Action", 49.99), 14 | new Book(2, "Java SE8 for the Really Impatient", 39.99), 15 | new Book(3, "Core Java Volume I -- Fundamentals", 43.30), 16 | new Book(4, "Functional Programming in Java", 27.64), 17 | new Book(5, "Making Java Groovy", 45.99), 18 | new Book(6, "Head First Java", 26.97), 19 | new Book(7, "Effective Java", 35.47), 20 | new Book(8, "Java 8 Pocket Guide", 10.40), 21 | new Book(9, "Gradle Recipes for Android", 23.76), 22 | new Book(10, "Spring Boot in Action", 39.97) 23 | ); 24 | 25 | Map bookMap = books.stream() 26 | .collect(Collectors.toMap(Book::getId, book -> book)); 27 | 28 | bookMap.forEach((k,v) -> 29 | System.out.println(k + ": " + v) 30 | ); 31 | 32 | bookMap = books.stream() 33 | .collect(Collectors.toMap(Book::getId, Function.identity())); 34 | 35 | bookMap.forEach((k,v) -> 36 | System.out.println(k + ": " + v) 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/collectors/Book.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | public class Book { 4 | private int id; 5 | private String name; 6 | private double price; 7 | 8 | public Book() {} 9 | 10 | public Book(int id, String name, double price) { 11 | this.id = id; 12 | this.name = name; 13 | this.price = price; 14 | } 15 | 16 | public int getId() { 17 | return id; 18 | } 19 | 20 | public void setId(int id) { 21 | this.id = id; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public void setName(String name) { 29 | this.name = name; 30 | } 31 | 32 | public double getPrice() { 33 | return price; 34 | } 35 | 36 | public void setPrice(double price) { 37 | this.price = price; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return "Product{" + 43 | "id=" + id + 44 | ", name='" + name + '\'' + 45 | ", price=" + price + 46 | '}'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/collectors/CollectorsDemo.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | import java.util.*; 4 | import java.util.stream.Collector; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.Stream; 7 | 8 | public class CollectorsDemo { 9 | public List createList() { 10 | return Stream.of("Mr. Furious", "The Blue Raja", "The Shoveler", "The Bowler", 11 | "Invisible Boy", "The Spleen", "The Sphinx") 12 | .collect(Collectors.toList()); 13 | } 14 | 15 | public Set createSet() { 16 | return Stream.of("Casanova Frankenstein", "The Disco Boys", "The Not-So-Goodie Mob", 17 | "The Suits", "The Suzies", "The Furriers", "The Furriers") 18 | .collect(Collectors.toSet()); 19 | } 20 | 21 | public Deque createDeque() { 22 | return Stream.of("Hank Azaria", "Janeane Garofalo", "William H. Macy", 23 | "Paul Reubens", "Ben Stiller", "Kel Mitchell", "Wes Studi") 24 | .collect(Collectors.toCollection(ArrayDeque::new)); 25 | } 26 | 27 | public String[] createArray() { 28 | return Stream.of("The Waffler", "Pencilhead", "Reverse Psychologist", "PMS Avenger") 29 | .toArray(String[]::new); 30 | } 31 | 32 | public List evenLengthStrings(String... strings) { 33 | return Stream.of(strings) 34 | .filter(s -> s.length() % 2 == 0) 35 | .collect(Collectors.toList()); 36 | } 37 | 38 | public SortedSet oddLengthStringSet(String... strings) { 39 | Collector> intoSet = 40 | Collector.of(TreeSet::new, 41 | SortedSet::add, 42 | (left, right) -> { 43 | left.addAll(right); 44 | return left; 45 | }, 46 | Collections::unmodifiableSortedSet); 47 | return Stream.of(strings) 48 | .filter(s -> s.length() % 2 != 0) 49 | .collect(intoSet); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/collectors/ImmutableCollections.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | import java.util.*; 4 | 5 | import static java.util.stream.Collectors.*; 6 | 7 | public class ImmutableCollections { 8 | public final Map map = Collections.unmodifiableMap( 9 | new HashMap() {{ 10 | put("have", 1); 11 | put("the", 2); 12 | put("high", 3); 13 | put("ground", 4); 14 | }}); 15 | 16 | @SafeVarargs 17 | public final List createImmutableList(T... elements) { 18 | return Arrays.stream(elements) 19 | .collect(collectingAndThen(toList(), Collections::unmodifiableList)); 20 | } 21 | 22 | @SafeVarargs 23 | public final List createImmutableListJava7(T... elements) { 24 | return Collections.unmodifiableList(Arrays.asList(elements)); 25 | } 26 | 27 | @SafeVarargs 28 | public final Set createImmutableSet(T... elements) { 29 | return Arrays.stream(elements) 30 | .collect(collectingAndThen(toSet(), Collections::unmodifiableSet)); 31 | } 32 | 33 | @SafeVarargs 34 | public final Set createImmutableSetJava7(T... elements) { 35 | return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(elements))); 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/collectors/Movie.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class Movie { 7 | private Set actors = new HashSet<>(); 8 | 9 | public void addActor(Actor actor) { 10 | actors.add(actor); 11 | } 12 | 13 | public void setActors(Set actors) { 14 | this.actors = actors; 15 | } 16 | 17 | public Set getActors() { 18 | return actors; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/collectors/MysteryMen.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | import java.util.Map; 4 | import java.util.Set; 5 | import java.util.stream.Collectors; 6 | 7 | public class MysteryMen { 8 | public static void main(String[] args) { 9 | Movie mysteryMen = new Movie(); 10 | mysteryMen.addActor(new Actor("Wes Studi", "The Sphinx")); 11 | mysteryMen.addActor(new Actor("Ben Stiller", "Mr. Furious")); 12 | mysteryMen.addActor(new Actor("Hank Azaria", "The Blue Raja")); 13 | mysteryMen.addActor(new Actor("William H. Macy", "The Shoveler")); 14 | mysteryMen.addActor(new Actor("Janeane Garofalo", "The Bowler")); 15 | mysteryMen.addActor(new Actor("Kel Mitchell", "Invisible Boy")); 16 | mysteryMen.addActor(new Actor("Paul Reubens", "The Spleen")); 17 | mysteryMen.addActor(new Actor("Geoffrey Rush", "Casanova Frankenstein")); 18 | mysteryMen.addActor(new Actor("Greg Kinnear", "Captain Amazing")); 19 | 20 | Set actors = mysteryMen.getActors(); 21 | 22 | Map actorMap = actors.stream() 23 | .collect(Collectors.toMap(Actor::getName, Actor::getRole)); 24 | 25 | actorMap.forEach((key,value) -> System.out.printf("%s played %s%n", key, value)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/concurrency/AllOfDemo.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import java.util.Arrays; 4 | import java.util.concurrent.CompletableFuture; 5 | import java.util.stream.Stream; 6 | 7 | public class AllOfDemo { 8 | private int getNextValue() { 9 | try { 10 | Thread.sleep((long) (Math.random() * 100)); 11 | } catch (InterruptedException e) { 12 | throw new RuntimeException(e); 13 | } 14 | return 42; 15 | } 16 | 17 | public CompletableFuture getValue() { 18 | return CompletableFuture.supplyAsync(this::getNextValue); 19 | } 20 | 21 | public static void main(String[] args) { 22 | AllOfDemo demo = new AllOfDemo(); 23 | CompletableFuture[] completableFutures = Stream.generate(demo::getValue) 24 | .limit(10) 25 | .toArray(CompletableFuture[]::new); 26 | 27 | CompletableFuture.allOf(completableFutures).join(); 28 | 29 | Arrays.stream(completableFutures) 30 | .map(CompletableFuture::join) 31 | .forEach(System.out::println); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/concurrency/AwaitQuiesence.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | 5 | public class AwaitQuiesence { 6 | private String sleepThenReturnString() { 7 | try { 8 | Thread.sleep(100); 9 | } catch (InterruptedException ignored) { 10 | } 11 | return "42"; 12 | } 13 | 14 | public CompletableFuture supplyThenAccept() { 15 | return CompletableFuture.supplyAsync(this::sleepThenReturnString) 16 | .thenApply(Integer::parseInt) 17 | .thenApply(x -> 2 * x) 18 | .thenAccept(System.out::println); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/concurrency/CommonPoolSize.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import java.util.concurrent.ExecutionException; 4 | import java.util.concurrent.ForkJoinPool; 5 | import java.util.concurrent.ForkJoinTask; 6 | import java.util.stream.LongStream; 7 | 8 | public class CommonPoolSize { 9 | public static void main(String[] args) { 10 | System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "16"); 11 | long total = LongStream.rangeClosed(1, 3_000_000) 12 | .parallel() 13 | .sum(); 14 | System.out.println("total = " + total); 15 | 16 | int poolSize = ForkJoinPool.commonPool().getPoolSize(); 17 | System.out.println("Pool size: " + poolSize); 18 | System.out.println("Processors: " + Runtime.getRuntime().availableProcessors()); 19 | 20 | ForkJoinPool pool = new ForkJoinPool(15); 21 | ForkJoinTask task = pool.submit(() -> LongStream.rangeClosed(1, 3_000_000) 22 | .parallel() 23 | .sum() 24 | ); 25 | try { 26 | total = task.get(); 27 | System.out.println("total = " + total); 28 | } catch (InterruptedException | ExecutionException e) { 29 | e.printStackTrace(); 30 | } finally { 31 | pool.shutdown(); 32 | } 33 | poolSize = pool.getPoolSize(); 34 | System.out.println("Pool size: " + poolSize); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/concurrency/CompletableFutureDemos.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.CompletableFuture; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | import java.util.logging.Logger; 7 | 8 | public class CompletableFutureDemos { 9 | private final Logger logger = Logger.getLogger(this.getClass().getName()); 10 | 11 | private final Map cache = new ConcurrentHashMap<>(); 12 | 13 | private Product getLocal(int id) { 14 | return cache.get(id); 15 | } 16 | 17 | private Product getRemote(int id) { 18 | try { 19 | Thread.sleep(100); 20 | if (id == 666) { 21 | throw new RuntimeException("Evil request"); 22 | } 23 | } catch (InterruptedException ignored) { 24 | } 25 | return new Product(id, "name"); 26 | } 27 | 28 | public CompletableFuture getProduct(int id) { 29 | try { 30 | Product product = getLocal(id); 31 | if (product != null) { 32 | logger.info("getLocal with id=" + id); 33 | return CompletableFuture.completedFuture(product); 34 | } else { 35 | // Synchronous (simulating legacy system) 36 | logger.info("getRemote with id=" + id); 37 | CompletableFuture future = new CompletableFuture<>(); 38 | Product p = getRemote(id); 39 | cache.put(id, p); 40 | future.complete(p); 41 | return future; 42 | } 43 | } catch (Exception e) { 44 | logger.info("exception thrown"); 45 | CompletableFuture future = new CompletableFuture<>(); 46 | future.completeExceptionally(e); 47 | return future; 48 | } 49 | } 50 | 51 | public CompletableFuture getProductAsync(int id) { 52 | try { 53 | Product product = getLocal(id); 54 | if (product != null) { 55 | logger.info("getLocal with id=" + id); 56 | return CompletableFuture.completedFuture(product); 57 | } else { 58 | logger.info("getRemote with id=" + id); 59 | // Asynchronous 60 | return CompletableFuture.supplyAsync(() -> { 61 | Product p = getRemote(id); 62 | cache.put(id, p); 63 | return p; 64 | }); 65 | } 66 | } catch (Exception e) { 67 | logger.info("exception thrown"); 68 | CompletableFuture future = new CompletableFuture<>(); 69 | future.completeExceptionally(e); 70 | return future; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/concurrency/FutureDemo.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import java.util.concurrent.*; 4 | 5 | public class FutureDemo { 6 | public static void main(String[] args) { 7 | ExecutorService service = Executors.newCachedThreadPool(); 8 | 9 | @SuppressWarnings("Convert2Lambda") 10 | Future future = service.submit(new Callable() { 11 | @Override 12 | public String call() throws Exception { 13 | Thread.sleep(100); 14 | return "Hello, World!"; 15 | } 16 | }); 17 | 18 | System.out.println("Processing..."); 19 | 20 | getIfNotCancelled(future); 21 | 22 | future = service.submit(() -> { 23 | Thread.sleep(10); 24 | return "Hello, World!"; 25 | }); 26 | 27 | System.out.println("More processing..."); 28 | 29 | while (!future.isDone()) { 30 | System.out.println("Waiting..."); 31 | } 32 | 33 | getIfNotCancelled(future); 34 | 35 | future = service.submit(() -> { 36 | Thread.sleep(10); 37 | return "Hello, World!"; 38 | }); 39 | 40 | future.cancel(true); 41 | 42 | System.out.println("Even more processing..."); 43 | 44 | getIfNotCancelled(future); 45 | 46 | if (!service.isShutdown()) 47 | service.shutdown(); 48 | } 49 | 50 | private static void getIfNotCancelled(Future future) { 51 | try { 52 | if (!future.isCancelled()) { 53 | System.out.println(future.get()); 54 | } else { 55 | System.out.println("Cancelled"); 56 | } 57 | } catch (InterruptedException | ExecutionException e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/concurrency/ParallelDemo.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import java.time.Duration; 4 | import java.time.Instant; 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.stream.IntStream; 8 | 9 | public class ParallelDemo { 10 | 11 | public static int doubleIt(int n) { 12 | try { 13 | Thread.sleep(100); 14 | System.out.println(Thread.currentThread().getName() + " with n=" + n); 15 | } catch (InterruptedException ignore) { 16 | } 17 | return n * 2; 18 | } 19 | 20 | @SuppressWarnings("Convert2streamapi") 21 | public static void main(String[] args) { 22 | List ints = Arrays.asList(3, 1, 4, 1, 5, 9); 23 | 24 | // Non-functional, with shared mutable state 25 | int total = 0; 26 | for (int i : ints) { 27 | total += i; 28 | } 29 | System.out.println("Total = " + total); 30 | 31 | // Use Java 8 Streams 32 | total = 0; // local variable; not an attribute 33 | // IntStream.of(3, 1, 4, 1, 5, 9) 34 | // .forEach(n -> total += n); // not legal; total needs to be effectively final 35 | // System.out.println("Total = " + total); 36 | 37 | total = IntStream.of(3, 1, 4, 1, 5, 9, 2, 6) 38 | .sum(); 39 | System.out.println("Total = " + total); 40 | 41 | Instant before = Instant.now(); 42 | total = IntStream.of(3, 1, 4, 1, 5, 9) 43 | .parallel() 44 | .map(ParallelDemo::doubleIt) 45 | .sum(); 46 | Instant after = Instant.now(); 47 | Duration duration = Duration.between(before, after); 48 | System.out.println("Total of doubles = " + total); 49 | System.out.println("time = " + duration.toMillis() + " ms"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/concurrency/Product.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | public class Product { 4 | private final int id; 5 | private final String name; 6 | 7 | public Product(int id, String name) { 8 | this.id = id; 9 | this.name = name; 10 | } 11 | 12 | public int getId() { 13 | return id; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "Product{" + 23 | "id=" + id + 24 | ", name='" + name + '\'' + 25 | '}'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/concurrency/SequentialToParallel.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import java.util.Arrays; 4 | import java.util.stream.DoubleStream; 5 | import java.util.stream.IntStream; 6 | import java.util.stream.Stream; 7 | 8 | public class SequentialToParallel { 9 | @SuppressWarnings("SimplifyStreamApiCallChains") 10 | public static void main(String[] args) { 11 | boolean parallel = Stream.of(3, 1, 4, 1, 5, 9) 12 | .isParallel(); 13 | System.out.println(parallel); 14 | 15 | parallel = IntStream.iterate(1, n -> n + 1) 16 | .isParallel(); 17 | System.out.println(parallel); 18 | 19 | parallel = DoubleStream.generate(Math::random) 20 | .isParallel(); 21 | System.out.println(parallel); 22 | 23 | parallel = Arrays.asList(3, 1, 4, 1, 5, 9).stream() 24 | .isParallel(); 25 | System.out.println(parallel); 26 | 27 | 28 | parallel = Stream.of(3, 1, 4, 1, 5, 9) 29 | .parallel() 30 | .isParallel(); 31 | System.out.println(parallel); 32 | 33 | parallel = Arrays.asList(3, 1, 4, 1, 5, 9).parallelStream() 34 | .isParallel(); 35 | System.out.println(parallel); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/concurrency/Timer.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import java.util.function.Supplier; 4 | 5 | public class Timer { 6 | 7 | public static R time(Supplier block) { 8 | long start = System.nanoTime(); 9 | 10 | R result = block.get(); 11 | 12 | long end = System.nanoTime(); 13 | double elapsedTime = (end - start) / 1e9; 14 | System.out.printf("Elapsed time: %ssec%n", elapsedTime); 15 | return result; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/datetime/AddingAndSubtracting.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.LocalDate; 4 | import java.time.Month; 5 | 6 | public class AddingAndSubtracting { 7 | public static void main(String[] args) { 8 | LocalDate groundHogDay = LocalDate.of(2017, Month.FEBRUARY, 2); 9 | System.out.println(groundHogDay.plusDays(3)); 10 | System.out.println(groundHogDay.plusWeeks(5)); 11 | System.out.println(groundHogDay.plusMonths(7)); 12 | System.out.println(groundHogDay.plusYears(2)); 13 | 14 | System.out.println(groundHogDay.minusDays(3)); 15 | System.out.println(groundHogDay.minusWeeks(5)); 16 | System.out.println(groundHogDay.minusMonths(7)); 17 | System.out.println(groundHogDay.minusYears(2)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/datetime/Adjusters.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.DayOfWeek; 4 | import java.time.LocalDate; 5 | import java.time.temporal.Temporal; 6 | import java.time.temporal.TemporalAdjusters; 7 | 8 | @SuppressWarnings("Duplicates") 9 | public class Adjusters { 10 | public static Temporal adjustInto(Temporal input) { 11 | LocalDate date = LocalDate.from(input); 12 | int day; 13 | if (date.getDayOfMonth() < 15) { 14 | day = 15; 15 | } else { 16 | day = date.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth(); 17 | } 18 | date = date.withDayOfMonth(day); 19 | if (date.getDayOfWeek() == DayOfWeek.SATURDAY || 20 | date.getDayOfWeek() == DayOfWeek.SUNDAY) { 21 | date = date.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)); 22 | } 23 | 24 | return input.with(date); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/datetime/AntarcticaTimeZones.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.ZoneId; 5 | import java.time.ZonedDateTime; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | 9 | import static java.util.Comparator.comparingInt; 10 | 11 | public class AntarcticaTimeZones { 12 | public static void main(String[] args) { 13 | LocalDateTime now = LocalDateTime.now(); 14 | List antarcticZones = 15 | ZoneId.getAvailableZoneIds().stream() // Stream 16 | .filter(regionId -> regionId.contains("Antarctica")) 17 | .map(ZoneId::of) // Stream 18 | .map(now::atZone) // Stream 19 | .sorted(comparingInt( 20 | zoneId -> zoneId.getOffset().getTotalSeconds())) 21 | .collect(Collectors.toList()); 22 | 23 | antarcticZones.forEach(zdt -> 24 | System.out.printf("%7s: %25s %7s%n", zdt.getOffset(), zdt.getZone(), 25 | zdt.getZone().getRules().isDaylightSavings(zdt.toInstant()))); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/datetime/CTtoIndia.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.LocalDate; 4 | import java.time.LocalTime; 5 | import java.time.ZoneId; 6 | import java.time.ZonedDateTime; 7 | import java.time.format.DateTimeFormatter; 8 | import java.util.stream.IntStream; 9 | 10 | public class CTtoIndia { 11 | public static void main(String[] args) { 12 | LocalDate localDate = LocalDate.now(); 13 | LocalTime localTime = LocalTime.MIDNIGHT; 14 | ZonedDateTime zdt = ZonedDateTime.of(localDate, localTime, 15 | ZoneId.of("America/New_York")); 16 | ZoneId india = ZoneId.of("Asia/Kolkata"); 17 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mma"); 18 | 19 | System.out.println("Connecticut India"); 20 | IntStream.rangeClosed(20, 30) // start at 8pm, incr by 1 hr 10 times 21 | .mapToObj(zdt::plusHours) 22 | .forEach(zonedDateTime -> System.out.printf(" %s %s%n", 23 | zonedDateTime.toLocalTime().format(formatter), 24 | zonedDateTime.withZoneSameInstant(india).toLocalTime())); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/datetime/ConvertDate.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.sql.Timestamp; 4 | import java.text.DateFormat; 5 | import java.text.SimpleDateFormat; 6 | import java.time.LocalDate; 7 | import java.time.LocalDateTime; 8 | import java.time.ZoneId; 9 | import java.time.ZonedDateTime; 10 | import java.time.format.DateTimeFormatter; 11 | import java.util.Calendar; 12 | import java.util.Date; 13 | import java.util.GregorianCalendar; 14 | 15 | public class ConvertDate { 16 | public LocalDate convertFromUtilDateUsingInstant(Date date) { 17 | return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); 18 | } 19 | 20 | public LocalDate convertFromSqlDatetoLD(java.sql.Date sqlDate) { 21 | return sqlDate.toLocalDate(); 22 | } 23 | 24 | public java.sql.Date convertToSqlDateFromLD(LocalDate localDate) { 25 | return java.sql.Date.valueOf(localDate); 26 | } 27 | 28 | public LocalDateTime convertFromTimestampToLDT(Timestamp timestamp) { 29 | return timestamp.toLocalDateTime(); 30 | } 31 | 32 | public Timestamp convertToTimestampFromLDT(LocalDateTime localDateTime) { 33 | return Timestamp.valueOf(localDateTime); 34 | } 35 | 36 | public LocalDate convertFromUtilDateToLocalDate(Date date) { 37 | return new java.sql.Date(date.getTime()).toLocalDate(); 38 | } 39 | 40 | public LocalDateTime convertFromUtilDateToLDUsingString(Date date) { 41 | DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 42 | return LocalDateTime.parse(df.format(date), DateTimeFormatter.ISO_LOCAL_DATE_TIME); 43 | } 44 | 45 | public ZonedDateTime convertFromCalendar(Calendar cal) { 46 | return ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId()); 47 | } 48 | 49 | public LocalDateTime convertFromCalendarUsingGetters(Calendar cal) { 50 | return LocalDateTime.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 51 | cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)); 52 | } 53 | 54 | public ZonedDateTime convertFromGregorianCalendar(Calendar cal) { 55 | return ((GregorianCalendar) cal).toZonedDateTime(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/datetime/DateTimeFormatterDemo.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.*; 4 | import java.time.format.DateTimeFormatter; 5 | import java.time.format.FormatStyle; 6 | import java.util.Locale; 7 | 8 | public class DateTimeFormatterDemo { 9 | public static void main(String[] args) { 10 | LocalDateTime now = LocalDateTime.now(); 11 | 12 | String text = now.format(DateTimeFormatter.ISO_DATE_TIME); 13 | System.out.println(text); 14 | 15 | LocalDateTime dateTime = LocalDateTime.parse(text); 16 | System.out.println(dateTime); 17 | 18 | LocalDate date = LocalDate.of(2018, Month.MARCH, 13); 19 | 20 | System.out.println("Full : " + date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL))); 21 | System.out.println("Long : " + date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG))); 22 | System.out.println("Medium: " + date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))); 23 | System.out.println("Short : " + date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))); 24 | 25 | System.out.println(); 26 | System.out.println("France : " + 27 | date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.FRANCE))); 28 | System.out.println("India : " + 29 | date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(new Locale("hin", "IN")))); 30 | System.out.println("Brazil : " + 31 | date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(new Locale("pt", "BR")))); 32 | System.out.println("Japan : " + 33 | date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.JAPAN))); 34 | 35 | Locale loc = new Locale.Builder() 36 | .setLanguage("sr") 37 | .setScript("Latn") 38 | .setRegion("RS") 39 | .build(); 40 | System.out.println("Serbian: " + 41 | date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(loc))); 42 | 43 | System.out.println(); 44 | 45 | 46 | ZonedDateTime moonLanding = ZonedDateTime.of( 47 | LocalDate.of(1969, Month.JULY, 20), 48 | LocalTime.of(20, 18), 49 | ZoneId.of("UTC") 50 | ); 51 | System.out.println(moonLanding.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); 52 | 53 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu/MMMM/dd hh:mm:ss a zzz GG"); 54 | System.out.println(moonLanding.format(formatter)); 55 | formatter = DateTimeFormatter.ofPattern("uuuu/MMMM/dd hh:mm:ss a VV xxxxx"); 56 | System.out.println(moonLanding.format(formatter)); 57 | 58 | ZonedDateTime zdt = ZonedDateTime.of(2018, 3, 11, 2, 30, 0, 0, ZoneId.of("America/New_York")); 59 | System.out.println(zdt.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL))); 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/datetime/DaysToElection.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.LocalDate; 4 | import java.time.Month; 5 | import java.time.Period; 6 | 7 | import static java.time.temporal.ChronoUnit.*; 8 | 9 | public class DaysToElection { 10 | private static String pluralize(long num) { 11 | return num == 1 ? "" : "s"; 12 | } 13 | 14 | public static void main(String[] args) { 15 | LocalDate electionDay = LocalDate.of(2020, Month.NOVEMBER, 3); 16 | LocalDate today = LocalDate.now(); 17 | 18 | // Using "between" 19 | System.out.printf("%d days to go...%n", DAYS.between(today, electionDay)); 20 | 21 | long years = YEARS.between(today, electionDay); 22 | long months = MONTHS.between(today.plusYears(years), electionDay); 23 | long days = DAYS.between(today.plusYears(years).plusMonths(months), electionDay); 24 | System.out.printf("%d year%s, %d month%s, and %d day%s%n", 25 | years, pluralize(years), 26 | months, pluralize(months), 27 | days, pluralize(days)); 28 | 29 | // Using "until" 30 | Period until = today.until(electionDay); 31 | System.out.println(today.until(electionDay)); 32 | 33 | years = until.getYears(); 34 | months = until.getMonths(); 35 | days = until.getDays(); 36 | System.out.printf("%d year%s, %d month%s, and %d day%s%n", 37 | years, pluralize(years), 38 | months, pluralize(months), 39 | days, pluralize(days)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/datetime/FunnyOffsets.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.Instant; 4 | import java.time.ZoneId; 5 | import java.time.ZoneOffset; 6 | import java.time.ZonedDateTime; 7 | import java.time.format.DateTimeFormatter; 8 | import java.time.format.FormatStyle; 9 | 10 | import static java.util.Comparator.comparingInt; 11 | 12 | /* 13 | * Alternative equivalent sorts: 14 | * .sorted((zoneId1, zoneId2) -> 15 | * (int) Duration.between(now.atZone(zoneId1), now.atZone(zoneId2)).getSeconds()) 16 | * -- or -- 17 | * .sorted((zoneId1, zoneId2) -> 18 | * (int) ChronoUnit.MINUTES.between(now.atZone(zoneId1), now.atZone(zoneId2)) 19 | */ 20 | public class FunnyOffsets { 21 | public static void main(String[] args) { 22 | Instant instant = Instant.now(); 23 | ZonedDateTime current = instant.atZone(ZoneId.systemDefault()); 24 | // equivalent to ZonedDateTime.now() 25 | System.out.printf("Current time is %s%n%n", current); 26 | 27 | System.out.printf("%10s %20s %13s%n", "Offset", "ZoneId", "Time"); 28 | ZoneId.getAvailableZoneIds().stream() 29 | .map(ZoneId::of) // Stream> 30 | .filter(zoneId -> { 31 | ZoneOffset offset = instant.atZone(zoneId).getOffset(); 32 | return offset.getTotalSeconds() % (60 * 60) != 0; 33 | }) 34 | .sorted(comparingInt(zoneId -> 35 | instant.atZone(zoneId).getOffset().getTotalSeconds())) 36 | .forEach(zoneId -> { 37 | ZonedDateTime zdt = current.withZoneSameInstant(zoneId); 38 | System.out.printf("%10s %25s %10s%n", zdt.getOffset(), zoneId, 39 | zdt.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT))); 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/datetime/MonthMethods.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.Month; 4 | 5 | public class MonthMethods { 6 | public static void main(String[] args) { 7 | System.out.println("Days in Feb in a leap year: " + 8 | Month.FEBRUARY.length(true)); 9 | System.out.println("Day of year for first day of Aug (leap year): " + 10 | Month.AUGUST.firstDayOfYear(true)); 11 | System.out.println("Month.of(1): " + Month.of(1)); 12 | System.out.println("Adding two months: " + 13 | Month.JANUARY.plus(2)); 14 | System.out.println("Subtracting a month: " + 15 | Month.MARCH.minus(1)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/datetime/NowFactoryMethod.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.*; 4 | 5 | public class NowFactoryMethod { 6 | public static void main(String[] args) { 7 | System.out.println("Instant.now(): " + Instant.now()); 8 | System.out.println("LocalDate.now(): " + LocalDate.now()); 9 | System.out.println("LocalTime.now(): " + LocalTime.now()); 10 | System.out.println("LocalDateTime.now(): " + LocalDateTime.now()); 11 | System.out.println("ZonedDateTime.now(): " + ZonedDateTime.now()); 12 | 13 | Clock antarctica = Clock.system(ZoneId.of("Antarctica/South_Pole")); 14 | System.out.println(ZonedDateTime.now(antarctica)); 15 | 16 | // Easier to do the Antarctica time this way (now() uses ZoneId directly) 17 | System.out.println(ZonedDateTime.now(ZoneId.of("Antarctica/South_Pole"))); 18 | 19 | // Can create a Clock with an offset, though 20 | System.out.println(ZonedDateTime.now( 21 | Clock.offset(antarctica, Duration.ofHours(1)))); 22 | 23 | // Other factory methods on Clock 24 | System.out.println(ZonedDateTime.now(Clock.systemDefaultZone())); 25 | System.out.println(ZonedDateTime.now(Clock.systemUTC())); 26 | 27 | // Clock that always returns the same instant 28 | Clock fixed = Clock.fixed(Instant.now(), ZoneId.of("Antarctica/South_Pole")); 29 | System.out.println(ZonedDateTime.now(fixed)); 30 | System.out.println(ZonedDateTime.now(fixed)); 31 | System.out.println(ZonedDateTime.now(fixed)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/datetime/NumberOfTimeZones.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.ZoneId; 4 | 5 | public class NumberOfTimeZones { 6 | public static void main(String[] args) { 7 | System.out.println(ZoneId.getAvailableZoneIds().size()); 8 | ZoneId.getAvailableZoneIds() 9 | .forEach(System.out::println); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/datetime/OfFactoryMethod.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.LocalDate; 4 | import java.time.LocalDateTime; 5 | import java.time.LocalTime; 6 | import java.time.Month; 7 | 8 | public class OfFactoryMethod { 9 | public static void main(String[] args) { 10 | System.out.println("First landing on the Moon:"); 11 | LocalDate moonLandingDate = LocalDate.of(1969, Month.JULY, 20); 12 | LocalTime moonLandingTime = LocalTime.of(20, 18); 13 | System.out.println("Date: " + moonLandingDate); 14 | System.out.println("Time: " + moonLandingTime); 15 | 16 | System.out.println("Neal Armstrong steps onto the surface: "); 17 | LocalTime walkTime = LocalTime.of(20, 2, 56, 150_000_000); 18 | LocalDateTime walk = LocalDateTime.of(moonLandingDate, walkTime); 19 | System.out.println(walk); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/datetime/PaydayAdjuster.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * - Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * - Neither the name of Oracle or the names of its 16 | * contributors may be used to endorse or promote products derived 17 | * from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | package datetime; 32 | 33 | import java.time.DayOfWeek; 34 | import java.time.LocalDate; 35 | import java.time.temporal.Temporal; 36 | import java.time.temporal.TemporalAdjuster; 37 | import java.time.temporal.TemporalAdjusters; 38 | 39 | // From the Java Tutorial: 40 | // https://docs.oracle.com/javase/tutorial/datetime/iso/adjusters.html 41 | @SuppressWarnings("Duplicates") 42 | public class PaydayAdjuster implements TemporalAdjuster { 43 | public Temporal adjustInto(Temporal input) { 44 | LocalDate date = LocalDate.from(input); 45 | int day; 46 | if (date.getDayOfMonth() < 15) { 47 | day = 15; 48 | } else { 49 | day = date.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth(); 50 | } 51 | date = date.withDayOfMonth(day); 52 | if (date.getDayOfWeek() == DayOfWeek.SATURDAY || 53 | date.getDayOfWeek() == DayOfWeek.SUNDAY) { 54 | date = date.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)); 55 | } 56 | 57 | return input.with(date); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/datetime/PirateQuery.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.LocalDate; 4 | import java.time.Month; 5 | import java.time.temporal.ChronoField; 6 | import java.time.temporal.ChronoUnit; 7 | import java.time.temporal.TemporalAccessor; 8 | 9 | public class PirateQuery { 10 | public static long daysUntilPirateDay(TemporalAccessor temporal) { 11 | int day = temporal.get(ChronoField.DAY_OF_MONTH); 12 | int month = temporal.get(ChronoField.MONTH_OF_YEAR); 13 | int year = temporal.get(ChronoField.YEAR); 14 | LocalDate date = LocalDate.of(year, month, day); 15 | LocalDate tlapd = LocalDate.of(year, Month.SEPTEMBER, 19); 16 | if (date.isAfter(tlapd)) { 17 | tlapd = tlapd.plusYears(1); 18 | } 19 | return ChronoUnit.DAYS.between(date, tlapd); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/datetime/RegionIdsByOffset.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.ZoneId; 5 | import java.time.ZoneOffset; 6 | import java.time.ZonedDateTime; 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | public class RegionIdsByOffset { 11 | 12 | public static List getRegionNamesForZoneId(ZoneId zoneId) { 13 | LocalDateTime now = LocalDateTime.now(); 14 | ZonedDateTime zdt = now.atZone(zoneId); 15 | ZoneOffset offset = zdt.getOffset(); 16 | return RegionIdsByOffset.getRegionNamesForOffset(offset); 17 | } 18 | 19 | public static List getRegionNamesForOffset(ZoneOffset offset) { 20 | LocalDateTime now = LocalDateTime.now(); 21 | return ZoneId.getAvailableZoneIds().stream() 22 | .map(ZoneId::of) 23 | .filter(zoneId -> now.atZone(zoneId).getOffset().equals(offset)) 24 | .map(ZoneId::toString) 25 | .sorted() 26 | .collect(Collectors.toList()); 27 | } 28 | 29 | public static List getRegionNamesForOffset(int hours, int minutes) { 30 | ZoneOffset offset = ZoneOffset.ofHoursMinutes(hours, minutes); 31 | return getRegionNamesForOffset(offset); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/datetime/Timer.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import java.time.Duration; 4 | import java.time.Instant; 5 | 6 | public class Timer { 7 | public static double getTiming(Instant start, Instant end) { 8 | return Duration.between(start, end).toMillis() / 1000.0; 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | Instant start = Instant.now(); 14 | try { 15 | Thread.sleep(100); 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); 18 | } 19 | Instant end = Instant.now(); 20 | System.out.println(getTiming(start, end) + " seconds"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/defaults/Company.java: -------------------------------------------------------------------------------- 1 | package defaults; 2 | 3 | public interface Company { 4 | default String getName() { 5 | return "Initech"; 6 | } 7 | 8 | // String getName(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/defaults/CompanyEmployee.java: -------------------------------------------------------------------------------- 1 | package defaults; 2 | 3 | public class CompanyEmployee implements Company, Employee { 4 | private String first; 5 | private String last; 6 | 7 | public CompanyEmployee() {} 8 | 9 | public CompanyEmployee(String first, String last) { 10 | this.first = first; 11 | this.last = last; 12 | } 13 | 14 | // @Override 15 | public String getName() { 16 | return String.format("%s works for %s", 17 | Employee.super.getName(), Company.super.getName()); 18 | } 19 | 20 | @Override 21 | public void convertCaffeineToCode() { 22 | System.out.println("Coding..."); 23 | } 24 | 25 | @Override 26 | public String getFirst() { 27 | return first; 28 | } 29 | 30 | @Override 31 | public String getLast() { 32 | return last; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/defaults/DefaultMapMethods.java: -------------------------------------------------------------------------------- 1 | package defaults; 2 | 3 | import java.math.BigInteger; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | import java.util.stream.LongStream; 9 | 10 | public class DefaultMapMethods { 11 | private final Map cache = new ConcurrentHashMap<>(); 12 | private final Map longCache = new HashMap<>(); 13 | 14 | public BigInteger fib(long i) { 15 | if (i == 0) return BigInteger.ZERO; 16 | if (i == 1) return BigInteger.ONE; 17 | 18 | return cache.computeIfAbsent(i, n -> fib(n - 2).add(fib(n - 1))); 19 | } 20 | 21 | // Overflows a long at longfib(93) 22 | public long longfib(long i) { 23 | if (i == 0) return 0; 24 | if (i == 1) return 1; 25 | 26 | return longCache.computeIfAbsent(i, n -> longfib(n - 2) + longfib(n - 1)); 27 | } 28 | 29 | public Map countWords(String passage, String... strings) { 30 | Map wordCounts = new HashMap<>(); 31 | 32 | // Put the words we care about in the map with a count of zero 33 | Arrays.stream(strings).forEach(s -> wordCounts.put(s, 0)); 34 | 35 | // Read the passage, updating the counts only for the words we care about 36 | Arrays.stream(passage.split(" ")).forEach(word -> 37 | wordCounts.computeIfPresent(word, (key, val) -> val + 1)); 38 | 39 | return wordCounts; 40 | } 41 | 42 | public Map fullWordCounts(String passage) { 43 | Map wordCounts = new HashMap<>(); 44 | String testString = passage.toLowerCase().replaceAll("\\W"," "); 45 | 46 | Arrays.stream(testString.split("\\s+")).forEach(word -> 47 | wordCounts.merge(word, 1, Integer::sum)); 48 | 49 | return wordCounts; 50 | } 51 | 52 | public static void main(String[] args) { 53 | DefaultMapMethods demo = new DefaultMapMethods(); 54 | LongStream.range(1, 100) 55 | .forEach(n -> System.out.printf("%3d: %21d %21d%n", n, demo.fib(n), demo.longfib(n))); 56 | 57 | String passage = "NSA agent walks into a bar. Bartender says, " + 58 | "'Hey, I have a new joke for you.' NSA agent says, 'heard it'."; 59 | Map counts = demo.countWords(passage, "NSA", "agent", "joke"); 60 | counts.forEach((word, count) -> System.out.println(word + "=" + count)); 61 | 62 | Map map = demo.fullWordCounts(passage); 63 | System.out.println(map); 64 | System.out.println(map.getOrDefault("nope", 0)); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/defaults/DefaultMethodsDemo.java: -------------------------------------------------------------------------------- 1 | package defaults; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class DefaultMethodsDemo { 7 | public static void main(String[] args) { 8 | List nums = new ArrayList<>(); 9 | nums.add(-3); nums.add(1); nums.add(4); 10 | nums.add(-1); nums.add(5); nums.add(9); 11 | System.out.println(nums); 12 | 13 | // removeIf is a default method in Collection 14 | // returns true if any elements were removed 15 | boolean removed = nums.removeIf(n -> n <= 0); 16 | System.out.println("Elements were" + (removed ? " " : "NOT ") + "removed"); 17 | System.out.println(nums); 18 | 19 | // Iterator has a default forEach method 20 | nums.forEach(System.out::println); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/defaults/Employee.java: -------------------------------------------------------------------------------- 1 | package defaults; 2 | 3 | public interface Employee { 4 | String getFirst(); 5 | 6 | String getLast(); 7 | 8 | void convertCaffeineToCode(); 9 | 10 | default String getName() { 11 | return String.format("%s %s", getFirst(), getLast()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/defaults/ForeachDemo.java: -------------------------------------------------------------------------------- 1 | package defaults; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class ForeachDemo { 7 | public static void main(String[] args) { 8 | List strings = Arrays.asList("here", "are", "some", "strings"); 9 | 10 | strings.forEach(System.out::println); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/defaults/StaticMethodsDemo.java: -------------------------------------------------------------------------------- 1 | package defaults; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | public class StaticMethodsDemo { 9 | public static void main(String[] args) { 10 | List bonds = Arrays.asList("Connery", "Lazenby", "Moore", "Dalton", 11 | "Brosnan", "Craig"); 12 | 13 | // Sorted in natural order 14 | List sorted = bonds.stream() 15 | .sorted(Comparator.naturalOrder()) // same as "sorted()" 16 | .collect(Collectors.toList()); 17 | System.out.println(sorted); 18 | 19 | // Sorted in the reverse of the natural order 20 | sorted = bonds.stream() 21 | .sorted(Comparator.reverseOrder()) 22 | .collect(Collectors.toList()); 23 | System.out.println(sorted); 24 | 25 | // Sorted by name, all lowercase 26 | sorted = bonds.stream() 27 | .sorted(Comparator.comparing(String::toLowerCase)) 28 | .collect(Collectors.toList()); 29 | System.out.println(sorted); 30 | 31 | // Sorted by length 32 | sorted = bonds.stream() 33 | .sorted(Comparator.comparingInt(String::length)) 34 | .collect(Collectors.toList()); 35 | System.out.println(sorted); 36 | 37 | // Sorted by length then natural order 38 | sorted = bonds.stream() 39 | .sorted(Comparator.comparingInt(String::length) 40 | .thenComparing(Comparator.naturalOrder())) 41 | .collect(Collectors.toList()); 42 | System.out.println(sorted); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/fileio/FileList.java: -------------------------------------------------------------------------------- 1 | package fileio; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | import java.util.stream.Stream; 8 | 9 | public class FileList { 10 | public static void main(String[] args) { 11 | try (Stream list = Files.list(Paths.get("src", "main", "java"))) { 12 | list.forEach(System.out::println); 13 | } catch (IOException e) { 14 | e.printStackTrace(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/fileio/Jumble.java: -------------------------------------------------------------------------------- 1 | package fileio; 2 | 3 | import java.io.IOException; 4 | import java.io.UncheckedIOException; 5 | import java.nio.file.Files; 6 | import java.nio.file.Paths; 7 | import java.util.Arrays; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.stream.Collectors; 12 | import java.util.stream.Stream; 13 | 14 | public class Jumble { 15 | private final Map> wordMap; 16 | 17 | public Jumble() { 18 | try (Stream words = Files.lines(Paths.get("src/main/resources/dict/words"))) { 19 | wordMap = words.filter(word -> word.length() == 5 || word.length() == 6) 20 | .collect(Collectors.groupingBy(this::word2key)); 21 | } catch (IOException e) { 22 | throw new UncheckedIOException(e); 23 | } 24 | } 25 | 26 | private String word2key(String word) { 27 | return Arrays.stream(word.split("")) 28 | .sorted() 29 | .collect(Collectors.joining()); 30 | } 31 | 32 | public String solve(String clue) { 33 | return wordMap.getOrDefault(word2key(clue), 34 | Collections.singletonList("")).get(0); 35 | } 36 | 37 | public List parallelSolve(String... clues) { 38 | return Arrays.stream(clues) 39 | .parallel() 40 | .map(this::solve) 41 | .collect(Collectors.toList()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/fileio/SearchForFiles.java: -------------------------------------------------------------------------------- 1 | package fileio; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | import java.util.stream.Stream; 8 | 9 | public class SearchForFiles { 10 | public static void main(String[] args) { 11 | try (Stream paths = Files.find(Paths.get("src/main/java"), Integer.MAX_VALUE, 12 | (path, attributes) -> !attributes.isDirectory() && path.toString().contains("fileio"))) { 13 | paths.forEach(System.out::println); 14 | } catch (IOException e) { 15 | e.printStackTrace(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/fileio/WalkTheTree.java: -------------------------------------------------------------------------------- 1 | package fileio; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.FileVisitOption; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.stream.Stream; 9 | 10 | public class WalkTheTree { 11 | public static void main(String[] args) { 12 | try (Stream paths = Files.walk(Paths.get("src/main/java"))) { 13 | paths.forEach(System.out::println); 14 | } catch (IOException e) { 15 | e.printStackTrace(); 16 | } 17 | 18 | FileVisitOption[] values = FileVisitOption.values(); 19 | System.out.println(values.length); 20 | System.out.println(values[0]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/functionpackage/ForEachDemo.java: -------------------------------------------------------------------------------- 1 | package functionpackage; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.function.Consumer; 6 | 7 | public class ForEachDemo { 8 | public static void main(String[] args) { 9 | List strings = Arrays.asList("This", "is", "a", "list", "of", "strings"); 10 | 11 | strings.forEach(new Consumer() { 12 | @Override 13 | public void accept(String s) { 14 | System.out.println(s); 15 | } 16 | }); 17 | 18 | //noinspection Convert2MethodRef 19 | strings.forEach(s -> System.out.println(s)); 20 | 21 | strings.forEach(System.out::println); 22 | 23 | Consumer printer = System.out::println; 24 | strings.forEach(printer); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/functionpackage/ImplementConsumer.java: -------------------------------------------------------------------------------- 1 | package functionpackage; 2 | 3 | import java.util.function.Consumer; 4 | import java.util.function.IntConsumer; 5 | import java.util.logging.Logger; 6 | import java.util.stream.IntStream; 7 | import java.util.stream.Stream; 8 | 9 | public class ImplementConsumer { 10 | private static final Logger log = Logger.getLogger(ImplementConsumer.class.getName()); 11 | 12 | @SuppressWarnings({"Convert2Lambda", "Convert2MethodRef"}) 13 | public static void main(String[] args) { 14 | log.warning(() -> "Logging a message at warn level"); 15 | IntStream.of(3, 1, 4, 1, 5, 9) 16 | .forEach(new IntConsumer() { 17 | @Override 18 | public void accept(int x) { 19 | System.out.println(x); 20 | } 21 | }); 22 | 23 | IntStream.of(3, 1, 4, 1, 5, 9) 24 | .forEach(x -> System.out.println(x)); 25 | 26 | IntStream.of(3, 1, 4, 1, 5, 9) 27 | .forEach(System.out::println); 28 | 29 | // In Java 8, must declare on RHS 30 | // In Java 9+, can use diamond operator 31 | Consumer consumer = new Consumer() { 32 | @Override 33 | public void accept(String s) { 34 | System.out.println(s); 35 | } 36 | }; 37 | Stream.of("this", "is", "a", "list") 38 | .forEach(consumer); 39 | 40 | // Simpler 41 | consumer = s -> System.out.println(s); 42 | consumer = System.out::println; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/functionpackage/ImplementFunction.java: -------------------------------------------------------------------------------- 1 | package functionpackage; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.function.Function; 6 | import java.util.stream.Collectors; 7 | 8 | public class ImplementFunction { 9 | @SuppressWarnings({"UnusedAssignment", "Convert2Lambda", "Anonymous2MethodRef"}) 10 | public static void main(String[] args) { 11 | List names = Arrays.asList("Mal", "Wash", "Kaylee", "Inara", 12 | "Zoë", "Jayne", "Simon", "River", "Shepherd Book"); 13 | 14 | // anonymous inner class 15 | List nameLengths = names.stream() 16 | .map(new Function() { 17 | @Override 18 | public Integer apply(String s) { 19 | return s.length(); 20 | } 21 | }) 22 | .collect(Collectors.toList()); 23 | 24 | // lambda expression 25 | //noinspection Convert2MethodRef 26 | nameLengths = names.stream() 27 | .map(s -> s.length()) 28 | .collect(Collectors.toList()); 29 | 30 | // method reference 31 | nameLengths = names.stream() 32 | .map(String::length) 33 | .collect(Collectors.toList()); 34 | 35 | System.out.printf("nameLengths = %s%n", nameLengths); 36 | // nameLengths == [3, 4, 6, 5, 3, 5, 5, 5, 13] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/functionpackage/ImplementPredicate.java: -------------------------------------------------------------------------------- 1 | package functionpackage; 2 | 3 | import java.util.Arrays; 4 | import java.util.function.Predicate; 5 | import java.util.stream.Collectors; 6 | 7 | public class ImplementPredicate { 8 | public static final Predicate LENGTH_FIVE = s -> s.length() == 5; 9 | public static final Predicate STARTS_WITH_S = s -> s.startsWith("S"); 10 | 11 | public String getNames(String... names) { 12 | return String.join(", ", names); 13 | } 14 | 15 | public String getNamesOfLength(int length, String... names) { 16 | return Arrays.stream(names) 17 | .filter(s -> s.length() == length) 18 | .collect(Collectors.joining(", ")); 19 | } 20 | 21 | public String getNamesStartingWith(String letter, String... names) { 22 | return Arrays.stream(names) 23 | .filter(s -> s.startsWith(letter)) 24 | .collect(Collectors.joining(", ")); 25 | } 26 | 27 | public String getNamesSatisfyingCondition(Predicate condition, String... names) { 28 | return Arrays.stream(names) 29 | .filter(condition) 30 | .collect(Collectors.joining(", ")); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/functionpackage/ImplementSupplier.java: -------------------------------------------------------------------------------- 1 | package functionpackage; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Optional; 6 | import java.util.function.DoubleSupplier; 7 | import java.util.stream.Collectors; 8 | 9 | public class ImplementSupplier { 10 | 11 | public static void main(String[] args) { 12 | 13 | // Anonymous inner class 14 | @SuppressWarnings({"Convert2Lambda", "UnusedAssignment"}) 15 | DoubleSupplier randomSupplier = new DoubleSupplier() { 16 | @Override 17 | public double getAsDouble() { 18 | return Math.random(); 19 | } 20 | }; 21 | 22 | // Lambda expression 23 | //noinspection Convert2MethodRef,UnusedAssignment 24 | randomSupplier = () -> Math.random(); 25 | 26 | // Method reference 27 | randomSupplier = Math::random; 28 | 29 | System.out.println(randomSupplier.getAsDouble()); 30 | 31 | List names = Arrays.asList("Mal", "Wash", "Kaylee", "Inara", 32 | "Zoë", "Jayne", "Simon", "River", "Shepherd Book"); 33 | 34 | Optional first = names.stream() 35 | .filter(name -> name.startsWith("C")) 36 | .findFirst(); 37 | 38 | System.out.println(first); // prints Optional.empty 39 | System.out.println(first.orElse("None")); // prints None 40 | 41 | System.out.println(first.orElse(String.format("No result found in %s", 42 | String.join(", ", names)))); 43 | 44 | System.out.println(first.orElseGet(() -> 45 | String.format("No result found in %s", 46 | String.join(", ", names)))); 47 | 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/generics/Employee.java: -------------------------------------------------------------------------------- 1 | package generics; 2 | 3 | public class Employee { 4 | public static final Employee DEFAULT_EMPLOYEE = new Employee(0, "No Name"); 5 | 6 | private final int id; 7 | private final String name; 8 | 9 | public Employee(int id, String name) { 10 | this.id = id; 11 | this.name = name; 12 | } 13 | 14 | public int getId() { 15 | return id; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return name; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/generics/ProcessColors.java: -------------------------------------------------------------------------------- 1 | package generics; 2 | 3 | import java.awt.*; 4 | import java.util.Arrays; 5 | import java.util.function.Function; 6 | import java.util.function.UnaryOperator; 7 | 8 | public class ProcessColors { 9 | private Color color; 10 | 11 | public void setColor(Color color) { 12 | this.color = color; 13 | } 14 | 15 | public Color applyFilter(UnaryOperator filter) { 16 | return filter.apply(color); 17 | } 18 | 19 | @SafeVarargs 20 | public final Color applyFilters(Function... filters) { 21 | return Arrays.stream(filters) 22 | .reduce(Function.identity(), Function::andThen) 23 | .apply(color); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/generics/ProcessNumbers.java: -------------------------------------------------------------------------------- 1 | package generics; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /** 8 | * Based on examples from the Java Tutorial 9 | */ 10 | public class ProcessNumbers { 11 | 12 | public static double sumListAsDoubles(List numbers) { 13 | return numbers.stream() 14 | .mapToDouble(Number::doubleValue) 15 | .sum(); 16 | } 17 | 18 | public static void printList(List elements) { 19 | elements.forEach(System.out::println); 20 | } 21 | 22 | public static void main(String[] args) { 23 | 24 | List integers = Arrays.asList(1, 2, 3, 4, 5); 25 | List doubles = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0); 26 | List bigDecimals = Arrays.asList( 27 | new BigDecimal("1.0"), 28 | new BigDecimal("2.0"), 29 | new BigDecimal("3.0"), 30 | new BigDecimal("4.0"), 31 | new BigDecimal("5.0")); 32 | 33 | List strings = Arrays.asList("this", "is", "a", "list", "of", "strings"); 34 | 35 | System.out.println(sumListAsDoubles(integers)); 36 | System.out.println(sumListAsDoubles(doubles)); 37 | System.out.println(sumListAsDoubles(bigDecimals)); 38 | 39 | printList(integers); 40 | printList(strings); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/generics/SafeVarargsDemo.java: -------------------------------------------------------------------------------- 1 | package generics; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | public class SafeVarargsDemo { 8 | 9 | @SafeVarargs 10 | public static List createList(T... values) { 11 | return Arrays.stream(values) 12 | .collect(Collectors.toList()); 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/gui/MyUI.java: -------------------------------------------------------------------------------- 1 | package gui; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | 6 | public class MyUI extends JPanel { 7 | private final JTextField source = new JTextField("Type text here"); 8 | private final JTextField destination = new JTextField("Result will be here"); 9 | 10 | public MyUI() { 11 | super(new BorderLayout()); 12 | JPanel north = new JPanel(); 13 | north.add(source); 14 | north.add(destination); 15 | JPanel south = new JPanel(); 16 | JButton go = new JButton("Go!"); 17 | south.add(go); 18 | 19 | String greeting = "Hello, %s!"; 20 | 21 | go.addActionListener(e -> destination.setText( 22 | String.format(greeting, source.getText()))); 23 | 24 | this.add(north, BorderLayout.NORTH); 25 | this.add(south, BorderLayout.SOUTH); 26 | } 27 | 28 | private static void createAndShowGUI() { 29 | JFrame frame = new JFrame(); 30 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 31 | 32 | JComponent newContentPane = new MyUI(); 33 | newContentPane.setOpaque(true); 34 | frame.setContentPane(newContentPane); 35 | 36 | System.setProperty("apple.laf.useScreenMenuBar", "true"); 37 | System.setProperty("com.apple.mrj.application.apple.menu.about.name", "MyUI"); 38 | 39 | try { 40 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 41 | } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { 42 | e.printStackTrace(); 43 | } 44 | 45 | frame.pack(); 46 | frame.setVisible(true); 47 | } 48 | 49 | public static void main(String[] args) { 50 | SwingUtilities.invokeLater(MyUI::createAndShowGUI); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/lambdas/Algorithms.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import java.math.BigInteger; 4 | import java.util.stream.Stream; 5 | 6 | public class Algorithms { 7 | public static BigInteger factorial(long num) { 8 | return num == 0 || num == 1 ? BigInteger.ONE : 9 | Stream.iterate(BigInteger.valueOf(2), x -> x.add(BigInteger.ONE)) 10 | .limit(num - 1) 11 | .reduce(BigInteger.ONE, 12 | BigInteger::multiply); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/lambdas/ClosureVariables.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.function.Predicate; 7 | import java.util.stream.Collectors; 8 | 9 | public class ClosureVariables { 10 | 11 | private static boolean isEvenLength(String s) { 12 | try { 13 | Thread.sleep(100); 14 | } catch (InterruptedException ignored) { 15 | } 16 | System.out.printf("%s with %s%n", Thread.currentThread().getName(), s); 17 | return s.length() % 2 == 0; 18 | } 19 | 20 | @SuppressWarnings({"Convert2streamapi", "UnusedAssignment", "unused"}) 21 | public static void main(String[] args) { 22 | 23 | // Sum using loop (iterative and shared mutable state) 24 | int total = 0; 25 | List nums = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5); 26 | for (int n : nums) { 27 | total += n; 28 | } 29 | System.out.printf("The total is %d%n", total); 30 | 31 | // Functional, but shared mutable state (won't compile) 32 | total = 0; 33 | nums.forEach(n -> { 34 | // Can't modify "total" 35 | // total += n; 36 | } 37 | ); 38 | 39 | // Functional, no shared mutable state 40 | total = nums.stream() 41 | .mapToInt(Integer::intValue) 42 | .sum(); 43 | System.out.printf("The total is %d%n", total); 44 | 45 | // Find even-length strings 46 | List strings = Arrays.asList("this", "is", "a", 47 | "list", "of", "strings"); 48 | Predicate evenlengths = (String s) -> { 49 | try { 50 | Thread.sleep(100); 51 | } catch (InterruptedException ignored) { 52 | } 53 | System.out.println(Thread.currentThread().getName()); 54 | return s.length() % 2 == 0; 55 | }; 56 | 57 | 58 | // Side effects --> legal, but not safe 59 | List evenLengths = new ArrayList<>(); 60 | strings.stream() 61 | .filter(s -> s.length() % 2 == 0) 62 | .forEach(evenLengths::add); 63 | System.out.println("Using add: " + evenLengths); 64 | 65 | // No side-effects 66 | System.out.println("Before: " + strings); 67 | evenLengths = strings.stream() 68 | .filter(s -> s.length() % 2 == 0) 69 | .collect(Collectors.toList()); 70 | System.out.println("After: " + evenLengths); 71 | 72 | 73 | // No side-effects 74 | long start = System.nanoTime(); 75 | List evens = strings.parallelStream() 76 | .filter(ClosureVariables::isEvenLength) 77 | //.filter(s -> s.length() % 2 == 0) 78 | .collect(Collectors.toList()); 79 | long end = System.nanoTime(); 80 | System.out.println(evens); 81 | System.out.printf("Time: %s%s%n", (end - start) / 1e9, "sec"); 82 | 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/lambdas/CompositionDemo.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import java.util.function.Consumer; 4 | import java.util.function.Function; 5 | import java.util.function.Predicate; 6 | import java.util.function.UnaryOperator; 7 | import java.util.logging.Logger; 8 | import java.util.stream.IntStream; 9 | import java.util.stream.Stream; 10 | 11 | public class CompositionDemo { 12 | private static int add2(int x) { 13 | return x + 2; 14 | } 15 | 16 | private static int mult3(int x) { 17 | return x * 3; 18 | } 19 | 20 | public static boolean isPerfect(int x) { 21 | return Math.sqrt(x) % 1 == 0; 22 | } 23 | 24 | public static boolean isPrime(int num) { 25 | int limit = (int) (Math.sqrt(num) + 1); 26 | return num == 2 || num > 1 && IntStream.range(2, limit) 27 | .noneMatch(divisor -> num % divisor == 0); 28 | } 29 | 30 | public static boolean isTriangular(int x) { 31 | double val = (Math.sqrt(8 * x + 1) - 1) / 2; 32 | return val % 1 == 0; 33 | } 34 | 35 | public static void main(String[] args) { 36 | 37 | Function a2 = x -> x + 2; 38 | Function m3 = x -> x * 3; 39 | Function m3a2 = a2.compose(m3); 40 | Function a2m3 = a2.andThen(m3); 41 | System.out.println("m3a2(1): " + m3a2.apply(1)); 42 | System.out.println("a2m3(1): " + a2m3.apply(1)); 43 | 44 | Function mult3add2 = ((Function) (x -> x + 2)) 45 | .compose(x -> x * 3); 46 | System.out.println(mult3add2.apply(1)); 47 | 48 | Function add2mult3 = ((Function) (x -> x + 2)) 49 | .andThen(x -> x * 3); 50 | System.out.println(add2mult3.apply(1)); 51 | 52 | mult3add2 = ((UnaryOperator) CompositionDemo::add2).compose(CompositionDemo::mult3); 53 | add2mult3 = ((UnaryOperator) CompositionDemo::add2).andThen(CompositionDemo::mult3); 54 | 55 | System.out.println(mult3add2.apply(1)); 56 | System.out.println(add2mult3.apply(1)); 57 | 58 | Function plus2toString = a2.andThen(Object::toString); 59 | System.out.println(plus2toString.apply(1).getClass().getName()); 60 | 61 | Function parseThenAdd2 = a2.compose(Integer::parseInt); 62 | System.out.println(parseThenAdd2.apply("1")); 63 | 64 | Logger log = Logger.getLogger("my logger"); 65 | Consumer printer = System.out::println; 66 | Consumer logger = log::info; 67 | 68 | Consumer printThenLog = printer.andThen(logger); 69 | Stream.of("this", "is", "a", "stream", "of", "strings").forEach(printThenLog); 70 | 71 | Predicate isEven = n -> n % 2 == 0; 72 | Predicate isDivBy5 = n -> n % 5 == 0; 73 | 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/lambdas/ConsumerDemo.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import java.util.*; 4 | import java.util.function.Consumer; 5 | import java.util.stream.Collectors; 6 | 7 | public class ConsumerDemo { 8 | public static void main(String[] args) { 9 | List integers = Arrays.asList(3, 1, 4, 1, 5, 9); 10 | // Anonymous inner class 11 | integers.forEach(new Consumer() { 12 | @Override 13 | public void accept(Integer integer) { 14 | System.out.println("The value in the anon. inner class is " + integer); 15 | } 16 | }); 17 | 18 | // Lambda expression 19 | integers.forEach(x -> System.out.println("The value of x is " + x)); 20 | 21 | // Method reference 22 | integers.forEach(System.out::println); 23 | 24 | Set nums = integers.stream() 25 | .map(n -> n * 2) // Function to double the numbers 26 | .filter(n -> n % 3 == 0) // Predicate to only return multiples of 3 27 | .collect(Collectors.toSet()); // Convert stream to a Set 28 | System.out.println(nums); 29 | 30 | Deque collection = integers.stream() 31 | .map(n -> n * 2) 32 | .filter(n -> n % 3 == 0) 33 | .collect(Collectors.toCollection(ArrayDeque::new)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/lambdas/FunctionWithException.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | @FunctionalInterface 4 | public interface FunctionWithException { 5 | R apply(T t) throws E; 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/lambdas/LambdasDemo.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.function.Consumer; 6 | import java.util.function.IntUnaryOperator; 7 | import java.util.function.Predicate; 8 | import java.util.stream.IntStream; 9 | import java.util.stream.Stream; 10 | 11 | @SuppressWarnings("Convert2MethodRef") 12 | public class LambdasDemo { 13 | // @SuppressWarnings("Convert2MethodRef") 14 | public static void main(String[] args) { 15 | List strings = Arrays.asList("this", "is", "a", 16 | "list", "of", "strings"); 17 | 18 | // Java 7 syntax 19 | System.out.println("Printing using anonymous inner class:"); 20 | strings.forEach(new Consumer() { 21 | @Override 22 | public void accept(String s) { 23 | System.out.println(s); 24 | } 25 | }); 26 | 27 | // forEach takes a Consumer 28 | // verbose lambda syntax (block lambda) 29 | strings.forEach((String s) -> { 30 | System.out.println(s); 31 | }); 32 | 33 | // simplified lambda syntax (expression lambda) 34 | System.out.println("Printing using lambda expression:"); 35 | strings.forEach(s -> System.out.println(s)); 36 | 37 | System.out.println("Printing using method reference:"); 38 | strings.forEach(System.out::println); 39 | 40 | int totalLength = strings.stream() 41 | .mapToInt(String::length) 42 | .sum(); 43 | System.out.printf("The total length of the strings is %d%n", totalLength); 44 | 45 | Stream.of(3, 1, 4, 1, 5, 9) 46 | .forEach(System.out::println); 47 | 48 | // Define Consumer separately 49 | Consumer printer = n -> System.out.println(n); 50 | Stream.of(3, 1, 4, 1, 5, 9) 51 | .forEach(printer); 52 | 53 | System.out.println(); 54 | // Predicate returns boolean 55 | Predicate mod3 = n -> n % 3 == 0; 56 | Stream.of(3, 1, 4, 1, 5, 9) 57 | .filter(mod3) 58 | .forEach(printer); 59 | 60 | System.out.println(); 61 | // Function of one type, returns one type 62 | IntUnaryOperator doubler = n -> n * 2; 63 | int sum = IntStream.range(1, 10) 64 | .filter(n -> n % 3 == 0) 65 | .peek(n -> System.out.println("After the filter: " + n)) 66 | .map(doubler) 67 | .peek(n -> System.out.println("After the doubler: " + n)) 68 | .sum(); 69 | System.out.println("The total is " + sum); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/lambdas/MethodReferencesDemo.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import java.util.List; 4 | import java.util.function.Consumer; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.Stream; 7 | 8 | public class MethodReferencesDemo { 9 | @SuppressWarnings("Convert2MethodRef") 10 | public static void main(String[] args) { 11 | Stream.of(3, 1, 4, 1, 5, 9) 12 | .forEach(x -> System.out.println(x)); 13 | 14 | Stream.of(3, 1, 4, 1, 5, 9) 15 | .forEach(System.out::println); 16 | 17 | Consumer printer = System.out::println; 18 | Stream.of(3, 1, 4, 1, 5, 9) 19 | .forEach(printer); 20 | 21 | Stream.generate(Math::random) 22 | .limit(10) 23 | .forEach(System.out::println); 24 | 25 | Stream.of("this", "is", "a", "stream", "of", "strings") 26 | .mapToInt(String::length) 27 | .forEach(System.out::println); 28 | 29 | Stream.of("this", "is", "a", "stream", "of", "strings") 30 | .mapToInt((s) -> s.length()) 31 | .forEach(x -> System.out.println(x)); 32 | 33 | List sorted = Stream.of("this", "is", "a", "list", "of", "strings") 34 | .sorted((s1, s2) -> s1.compareTo(s2)) 35 | .collect(Collectors.toList()); 36 | System.out.println(sorted); 37 | 38 | sorted = Stream.of("this", "is", "a", "list", "of", "strings") 39 | .sorted(String::compareTo) 40 | .collect(Collectors.toList()); 41 | System.out.println(sorted); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/lambdas/MyFilter.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import java.io.File; 4 | import java.io.FilenameFilter; 5 | 6 | public class MyFilter implements FilenameFilter { 7 | @Override 8 | public boolean accept(File dir, String name) { 9 | return name.endsWith(".java"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/lambdas/RunnableDemo.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | public class RunnableDemo { 4 | //@SuppressWarnings("Convert2Lambda") 5 | public static void main(String[] args) { 6 | 7 | // Use in Java 7 or earlier: 8 | new Thread(new Runnable() { 9 | @Override 10 | public void run() { 11 | System.out.println("inside runnable using anonymous inner class"); 12 | } 13 | }).start(); 14 | 15 | new Thread(() -> System.out.println("inside runnable using a lambda")).start(); 16 | 17 | Runnable r = () -> System.out.println("using a lambda as a variable"); 18 | new Thread(r).start(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/lambdas/UseFilenameFilter.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import java.io.File; 4 | import java.io.FilenameFilter; 5 | import java.util.Arrays; 6 | 7 | @SuppressWarnings("ConstantConditions") 8 | public class UseFilenameFilter { 9 | public static void main(String[] args) { 10 | File dir = new File("src/main/java"); 11 | String[] names = dir.list(); 12 | System.out.println(Arrays.asList(names)); 13 | 14 | // Using anonymous inner class 15 | names = dir.list(new FilenameFilter() { 16 | @Override 17 | public boolean accept(File directory, String name) { 18 | return name.endsWith(".java"); 19 | } 20 | }); 21 | System.out.println(Arrays.asList(names)); 22 | 23 | // Use a lambda expression 24 | names = dir.list((dr, name) -> name.endsWith(".java")); 25 | System.out.println(Arrays.asList(names)); 26 | 27 | Arrays.asList(names).forEach(System.out::println); 28 | 29 | names = dir.list(new MyFilter()); 30 | System.out.println(Arrays.asList(names)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/mapvsflatmap/Customer.java: -------------------------------------------------------------------------------- 1 | package mapvsflatmap; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Customer { 7 | private final String name; 8 | private final List orders = new ArrayList<>(); 9 | 10 | public Customer(String name) { 11 | this.name = name; 12 | } 13 | 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | public Customer addOrder(Order order) { 19 | orders.add(order); 20 | return this; 21 | } 22 | 23 | public List getOrders() { 24 | return orders; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return name; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/mapvsflatmap/FlatMapDemo.java: -------------------------------------------------------------------------------- 1 | package mapvsflatmap; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Stream; 6 | 7 | public class FlatMapDemo { 8 | public static void main(String[] args) { 9 | 10 | Customer sheridan = new Customer("Sheridan"); 11 | Customer ivanova = new Customer("Ivanova"); 12 | Customer garibaldi = new Customer("Garibaldi"); 13 | 14 | sheridan.addOrder(new Order(1)) 15 | .addOrder(new Order(2)) 16 | .addOrder(new Order(3)); 17 | ivanova.addOrder(new Order(4)) 18 | .addOrder(new Order(5)); 19 | 20 | List customers = Arrays.asList(sheridan, ivanova, garibaldi); 21 | 22 | // map for 1-1 customer to name --> Stream 23 | customers.stream() 24 | .map(Customer::getName) // function 25 | .forEach(System.out::println); 26 | 27 | // map 1-many customer to orders --> Stream> 28 | customers.stream() 29 | .map(Customer::getOrders) // function> 30 | .forEach(System.out::println); 31 | 32 | // map 1-many customer to orders.stream() --> Stream> 33 | customers.stream() 34 | .map(customer -> customer.getOrders().stream()) // function> 35 | .forEach(System.out::println); 36 | 37 | // stream() on an empty collection is already an empty Stream 38 | customers.stream() 39 | .flatMap(customer -> customer.getOrders().stream()) // function> 40 | .forEach(System.out::println); 41 | 42 | // flatMap 1-many customer to orders.stream() --> Stream 43 | // Note: extra detail included just for illustration; 44 | // stream() on an empty collection already returns an empty stream 45 | customers.stream() 46 | .flatMap(customer -> 47 | customer.getOrders().size() == 0 ? Stream.empty() : 48 | customer.getOrders().stream()) 49 | .forEach(System.out::println); 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/mapvsflatmap/MapExamples.java: -------------------------------------------------------------------------------- 1 | package mapvsflatmap; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.Stream; 7 | 8 | public class MapExamples { 9 | public static void main(String[] args) { 10 | List sizes = Stream.of("This", "is", "a", "stream", "of", "strings") 11 | .map(String::length) 12 | .collect(Collectors.toList()); 13 | System.out.println(sizes); 14 | 15 | List names = Stream.of(new Person("Steve"), 16 | new Person("Tony"), new Person("Thor"), 17 | new Person("Natasha"), new Person("Bruce"), 18 | new Person("Clint")) 19 | .map(Person::getName) 20 | .collect(Collectors.toList()); 21 | System.out.println(names); 22 | 23 | Map> map = 24 | Stream.of("This", "is", "a", "stream", "of", "strings") 25 | .collect(Collectors.groupingBy(String::length)); 26 | 27 | map.forEach((k,v) -> { 28 | System.out.println(k + ": " + v); 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/mapvsflatmap/Order.java: -------------------------------------------------------------------------------- 1 | package mapvsflatmap; 2 | 3 | public class Order { 4 | private int id; 5 | 6 | public Order(int id) { 7 | this.id = id; 8 | } 9 | 10 | public void setId(int id) { 11 | this.id = id; 12 | } 13 | 14 | public int getId() { 15 | return id; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "Order{" + 21 | "id=" + id + 22 | '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/mapvsflatmap/Person.java: -------------------------------------------------------------------------------- 1 | package mapvsflatmap; 2 | 3 | import java.util.Arrays; 4 | import java.util.Objects; 5 | 6 | @SuppressWarnings("unused") 7 | public class Person { 8 | private String name; 9 | 10 | public Person() { 11 | } 12 | 13 | public Person(String name) { 14 | this.name = name; 15 | } 16 | 17 | public Person(String... names) { // String... internally is viewed an a String[] 18 | System.out.println("Varargs ctor, names=" + Arrays.asList(names)); 19 | name = String.join(" ", names); // concats all strings together 20 | } 21 | 22 | public Person(Person p) { 23 | this.name = p.name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public String toString() { 35 | return String.format("mapvsflatmap.Person(%s)", name); 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) return true; 41 | if (o == null || getClass() != o.getClass()) return false; 42 | 43 | Person person = (Person) o; 44 | 45 | return Objects.equals(name, person.name); 46 | } 47 | 48 | @Override 49 | public int hashCode() { 50 | return name != null ? name.hashCode() : 0; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/mapvsflatmap/WordMap.java: -------------------------------------------------------------------------------- 1 | package mapvsflatmap; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | import java.util.Map; 8 | import java.util.stream.Stream; 9 | 10 | import static java.util.stream.Collectors.counting; 11 | import static java.util.stream.Collectors.groupingBy; 12 | 13 | public class WordMap { 14 | private final Path resourceDir = Paths.get("src/main/resources"); 15 | private String fileName = "simple_file.txt"; 16 | 17 | public Map createMap() { 18 | try (Stream lines = Files.lines(resourceDir.resolve(fileName))) { 19 | return lines.flatMap(line -> line.length() == 0 ? Stream.empty() : 20 | Stream.of(line.split(" "))) 21 | .map(String::toLowerCase) 22 | .collect(groupingBy(word -> word, counting())); 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | return null; 26 | } 27 | } 28 | 29 | public void setFileName(String fileName) { 30 | this.fileName = fileName; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/objects/ObjectsDemo.java: -------------------------------------------------------------------------------- 1 | package objects; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Objects; 6 | import java.util.stream.Collectors; 7 | 8 | public class ObjectsDemo { 9 | private List strings = Arrays.asList("this", "is", "a", "list", "of", "strings"); 10 | 11 | public void setStrings(List strings) { 12 | this.strings = strings; 13 | } 14 | 15 | public List getStrings() { 16 | return strings; 17 | } 18 | 19 | public List getNonNullStrings() { 20 | return strings.stream() 21 | .filter(Objects::nonNull) 22 | .collect(Collectors.toList()); 23 | } 24 | 25 | public List getNonNullElements(List list) { 26 | return list.stream() 27 | .filter(Objects::nonNull) 28 | .collect(Collectors.toList()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/optionals/Company.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | import java.util.Optional; 4 | 5 | public class Company { 6 | private Department department; 7 | 8 | public Optional getDepartment() { 9 | return Optional.ofNullable(department); 10 | } 11 | 12 | public void setDepartment(Department department) { 13 | this.department = department; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/optionals/Department.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | import java.util.Optional; 4 | 5 | public class Department { 6 | private String name; 7 | private Manager boss; 8 | 9 | public Optional getBoss() { 10 | return Optional.ofNullable(boss); 11 | } 12 | 13 | public void setBoss(Manager boss) { 14 | this.boss = boss; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "Department{" + 28 | "boss=" + boss + 29 | '}'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/optionals/Employee.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | public class Employee { 4 | private final int id; 5 | private String name; 6 | private static int nextId; 7 | 8 | public Employee(String name) { 9 | id = nextId++; 10 | this.name = name; 11 | } 12 | 13 | public int getId() { 14 | return id; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public static int getNextId() { 26 | return nextId; 27 | } 28 | 29 | public static void setNextId(int nextId) { 30 | Employee.nextId = nextId; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return "Employee{" + 36 | "id=" + id + 37 | ", name='" + name + '\'' + 38 | '}'; 39 | } 40 | 41 | @Override 42 | public boolean equals(Object o) { 43 | if (this == o) return true; 44 | if (!(o instanceof Employee)) return false; 45 | 46 | Employee employee = (Employee) o; 47 | 48 | return id == employee.id; 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | return id; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/optionals/HR.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.Objects; 6 | import java.util.Optional; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | import java.util.function.Function; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.Stream; 11 | 12 | @SuppressWarnings({"UnusedReturnValue", "unused"}) 13 | public class HR { 14 | private static final HR INSTANCE = new HR(); 15 | 16 | private final Map employeeMap = new ConcurrentHashMap<>(); 17 | 18 | private HR() {} 19 | 20 | public static HR getInstance() { 21 | return INSTANCE; 22 | } 23 | 24 | public int hire(Employee e) { 25 | Objects.requireNonNull(e); 26 | employeeMap.put(e.getId(), e); 27 | return employeeMap.containsKey(e.getId()) ? 1 : 0; 28 | } 29 | 30 | public int hire(List emps) { 31 | int before = employeeMap.size(); 32 | Map newEmps = emps.stream() 33 | .collect(Collectors.toMap(Employee::getId, Function.identity())); 34 | employeeMap.putAll(newEmps); 35 | return employeeMap.size() - before; 36 | } 37 | 38 | 39 | public int fire(int id) { 40 | Employee emp = employeeMap.remove(id); 41 | return emp != null ? 1 : 0; 42 | } 43 | 44 | public int reset() { 45 | employeeMap.clear(); 46 | return employeeMap.size(); 47 | } 48 | 49 | public Optional findEmployeeById(int id) { 50 | return Optional.ofNullable(employeeMap.get(id)); 51 | } 52 | 53 | // Check the Optional content before extracting values 54 | public List findEmployeesByIds1(List ids) { 55 | return ids.stream() 56 | .map(this::findEmployeeById) 57 | // returns Stream> 58 | .filter(Optional::isPresent) 59 | .map(Optional::get) 60 | .collect(Collectors.toList()); 61 | } 62 | 63 | // Use a flatmap instead 64 | public List findEmployeesByIds2(List ids) { 65 | return ids.stream() 66 | .map(this::findEmployeeById) 67 | .flatMap(optional -> optional.map(Stream::of).orElseGet(Stream::empty)) 68 | // .flatMap(optional -> optional.isPresent() ? 69 | // Stream.of(optional.get()) : 70 | // Stream.empty()) 71 | .collect(Collectors.toList()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/optionals/Manager.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | public class Manager { 4 | private String name; 5 | 6 | public Manager() { 7 | } 8 | 9 | public Manager(String name) { 10 | this.name = name; 11 | } 12 | 13 | public String getName() { 14 | return name; 15 | } 16 | 17 | public void setName(String name) { 18 | this.name = name; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "Manager{" + 24 | "name='" + name + '\'' + 25 | '}'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/optionals/OptionalDemo.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Optional; 6 | import java.util.function.Predicate; 7 | import java.util.stream.Stream; 8 | 9 | public class OptionalDemo { 10 | public static final Predicate EVENS = s -> s.length() % 2 == 0; 11 | 12 | 13 | private List strings = new ArrayList<>(); 14 | 15 | public void setStrings(List strings) { 16 | this.strings = strings; 17 | } 18 | 19 | public Optional findFirst(Predicate predicate) { 20 | return strings.stream() 21 | .filter(predicate) 22 | .findFirst(); 23 | } 24 | 25 | public static Optional createOptionalTheHardWay(T value) { 26 | return value == null ? Optional.empty() : Optional.of(value); 27 | } 28 | 29 | public static Optional createOptionalTheEasyWay(T value) { 30 | return Optional.ofNullable(value); 31 | } 32 | 33 | public static void main(String[] args) { 34 | String first = Stream.of("this is a list of strings".split(" ")) 35 | .filter(s -> s.length() > 10) 36 | .findFirst().orElse("No string satisfying predicate found"); 37 | System.out.println(first); 38 | // System.out.println(first.orElseThrow(NoSuchElementException::new)); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/optionals/OptionalMap.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Optional; 6 | 7 | public class OptionalMap { 8 | private final Map map = new HashMap<>(); 9 | 10 | public Map getMap() { 11 | return map; 12 | } 13 | 14 | public void put(K key, V value) { 15 | map.put(key, value); 16 | } 17 | 18 | public Optional get(K key) { 19 | return Optional.ofNullable(map.get(key)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/optionals/UseDepartment.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | import java.util.Optional; 4 | 5 | public class UseDepartment { 6 | public static void main(String[] args) { 7 | Manager mrSlate = new Manager("Mr. Slate"); 8 | 9 | // Department with a manager 10 | Department d = new Department(); 11 | d.setName("Construction"); 12 | d.setBoss(mrSlate); 13 | 14 | System.out.println("Boss: " + d.getBoss()); 15 | // prints: Boss: Optional[Manager{name='Mr. Slate'}] 16 | 17 | // Department without a manager 18 | Department d1 = new Department(); 19 | System.out.println("Boss: " + d1.getBoss()); 20 | // prints: Boss: Optional.empty 21 | 22 | // Can't call getName on an Optional, so either... 23 | System.out.println("Name: " + 24 | d.getBoss().orElse(new Manager("Unknown")).getName()); 25 | // prints: Name: Mr. Slate 26 | 27 | System.out.println("Name: " + 28 | d.getBoss().map(Manager::getName)); // function 29 | // prints: Name: Optional[Mr. Slate] 30 | 31 | System.out.println("Name: " + 32 | d1.getBoss().orElse(new Manager("Unknown")).getName()); 33 | // prints: Name: Unknown 34 | 35 | // or... 36 | System.out.println("Name: " + d.getBoss().map(Manager::getName)); 37 | // prints: Name: Optional[Mr. Slate] 38 | 39 | System.out.println("Name: " + d1.getBoss().map(Manager::getName)); 40 | // prints: Name: Optional.empty 41 | 42 | Company co = new Company(); 43 | co.setDepartment(d); 44 | 45 | System.out.println("Company Dept: " + co.getDepartment()); 46 | // prints: Company Dept: Optional[Department{boss=Manager{name='Mr. Slate'}}] 47 | 48 | System.out.println("Company Dept Manager: " + co.getDepartment() 49 | .map(Department::getBoss)); // function > 50 | // prints: Company Dept Manager: Optional[Optional[Manager{name='Mr. Slate'}]] 51 | 52 | System.out.println( 53 | co.getDepartment() 54 | .flatMap(Department::getBoss) 55 | .map(Manager::getName)); 56 | 57 | Optional company = Optional.of(co); 58 | 59 | System.out.println( 60 | company 61 | .flatMap(Company::getDepartment) 62 | .flatMap(Department::getBoss) 63 | .map(Manager::getName).orElse("No Manager Name") 64 | ); 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/optionals/UseOptionalMap.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | public class UseOptionalMap { 4 | public static void main(String[] args) { 5 | OptionalMap uo = new OptionalMap<>(); 6 | 7 | uo.put("a", 1); 8 | uo.put("b", 2); 9 | uo.put("c", 2); 10 | System.out.println(uo.getMap()); // {a=1, b=2, c=2} 11 | System.out.println(uo.getMap().get("d")); // null 12 | System.out.println(uo.get("d")); // Optional.empty 13 | System.out.println(uo.get("d").orElse(999)); // 999 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/refactoring/LoopsSortsAndIfs.java: -------------------------------------------------------------------------------- 1 | package refactoring; 2 | 3 | import java.util.*; 4 | 5 | public class LoopsSortsAndIfs { 6 | public static void main(String[] args) { 7 | String[] strings = "this is an array of strings".split(" "); 8 | 9 | List evenLengths = new ArrayList<>(); 10 | for (String s : strings) { 11 | if (s.length() % 2 == 0) { 12 | evenLengths.add(s); 13 | } 14 | } 15 | 16 | Collections.sort(evenLengths, new Comparator() { 17 | @Override 18 | public int compare(String s1, String s2) { 19 | return s1.length() - s2.length(); 20 | } 21 | }); 22 | 23 | for (String s : evenLengths) { 24 | System.out.println(s); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/sorting/Golfer.java: -------------------------------------------------------------------------------- 1 | package sorting; 2 | 3 | import java.util.Objects; 4 | 5 | public class Golfer implements Comparable { 6 | private String first; 7 | private String last; 8 | private int score; 9 | 10 | public Golfer() {} 11 | 12 | public Golfer(String first, String last) { 13 | this.first = first; 14 | this.last = last; 15 | } 16 | 17 | public Golfer(String first, String last, int score) { 18 | this.first = first; 19 | this.last = last; 20 | this.score = score; 21 | } 22 | 23 | @Override 24 | public int compareTo(Golfer golfer) { 25 | return score - golfer.score; 26 | } 27 | 28 | public String getFirst() { 29 | return first; 30 | } 31 | 32 | public void setFirst(String first) { 33 | this.first = first; 34 | } 35 | 36 | public String getLast() { 37 | return last; 38 | } 39 | 40 | public void setLast(String last) { 41 | this.last = last; 42 | } 43 | 44 | public int getScore() { 45 | return score; 46 | } 47 | 48 | public void setScore(int score) { 49 | this.score = score; 50 | } 51 | 52 | @Override 53 | public boolean equals(Object o) { 54 | if (this == o) return true; 55 | if (o == null || getClass() != o.getClass()) return false; 56 | 57 | Golfer golfer = (Golfer) o; 58 | 59 | if (!Objects.equals(first, golfer.first)) return false; 60 | return Objects.equals(last, golfer.last); 61 | 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | int result = first != null ? first.hashCode() : 0; 67 | result = 31 * result + (last != null ? last.hashCode() : 0); 68 | return result; 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return "Golfer{" + 74 | "first='" + first + '\'' + 75 | ", last='" + last + '\'' + 76 | ", score=" + score + 77 | '}'; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/sorting/SortGolfers.java: -------------------------------------------------------------------------------- 1 | package sorting; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.stream.Collectors; 8 | 9 | public class SortGolfers { 10 | private final List golfers = Arrays.asList( 11 | new Golfer("Jack", "Nicklaus", 68), 12 | new Golfer("Tiger", "Woods", 70), 13 | new Golfer("Tom", "Watson", 70), 14 | new Golfer("Ty", "Webb", 68), 15 | new Golfer("Bubba", "Watson", 70) 16 | ); 17 | 18 | // default sort is by score 19 | public void defaultSort() { 20 | golfers.stream() 21 | .sorted() 22 | .forEach(System.out::println); 23 | } 24 | 25 | // sort by score, then equal scores by last name 26 | public void sortByScoreThenLast() { 27 | golfers.stream() 28 | .sorted(Comparator.comparingInt(Golfer::getScore) 29 | .thenComparing(Golfer::getLast)) 30 | .forEach(System.out::println); 31 | } 32 | 33 | // sort by score, then by last, then by first 34 | public void sortByScoreThenLastThenFirst() { 35 | golfers.stream() 36 | .sorted(Comparator.comparingInt(Golfer::getScore) 37 | .thenComparing(Golfer::getLast) 38 | .thenComparing(Golfer::getFirst)) 39 | .forEach(System.out::println); 40 | } 41 | 42 | public void partitionByScore() { 43 | Map> map = golfers.stream() 44 | .collect(Collectors.partitioningBy( 45 | golfer -> golfer.getScore() < 70)); 46 | 47 | map.forEach((k,v) -> { 48 | System.out.println(k); 49 | v.forEach(System.out::println); 50 | }); 51 | } 52 | 53 | public static void main(String[] args) { 54 | SortGolfers sg = new SortGolfers(); 55 | // sg.defaultSort(); 56 | // sg.sortByScoreThenLast(); 57 | sg.sortByScoreThenLastThenFirst(); 58 | // sg.partitionByScore(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/sorting/SortingMaps.java: -------------------------------------------------------------------------------- 1 | package sorting; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedHashMap; 5 | import java.util.Map; 6 | 7 | import static java.util.Comparator.reverseOrder; 8 | import static java.util.stream.Collectors.toMap; 9 | 10 | public class SortingMaps, V extends Comparable> { 11 | private Map map = new HashMap<>(); 12 | 13 | public void setMap(Map map) { 14 | this.map = map; 15 | } 16 | 17 | public Map getMap() { 18 | return map; 19 | } 20 | 21 | public Map getMapSortedByKey() { 22 | return map.entrySet().stream() 23 | .sorted(Map.Entry.comparingByKey()) 24 | .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, 25 | (e1, e2) -> e1, LinkedHashMap::new)); 26 | } 27 | 28 | public Map getMapSortedByKeyDesc() { 29 | return map.entrySet().stream() 30 | .sorted(Map.Entry.comparingByKey(reverseOrder())) 31 | .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, 32 | (e1, e2) -> e1, LinkedHashMap::new)); 33 | } 34 | 35 | public Map getMapSortedByValue() { 36 | return map.entrySet().stream() 37 | .sorted(Map.Entry.comparingByValue()) 38 | .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, 39 | (e1, e2) -> e1, LinkedHashMap::new)); 40 | } 41 | 42 | public Map getMapSortedByValueDesc() { 43 | return map.entrySet().stream() 44 | .sorted(Map.Entry.comparingByValue(reverseOrder())) 45 | .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, 46 | (e1, e2) -> e1, LinkedHashMap::new)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/streams/Book.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | public class Book { 4 | private Integer id; 5 | private String title; 6 | 7 | private Book() {} 8 | 9 | public Book(Integer id, String title) { 10 | this.id = id; 11 | this.title = title; 12 | } 13 | 14 | public Integer getId() { 15 | return id; 16 | } 17 | 18 | public void setId(Integer id) { 19 | this.id = id; 20 | } 21 | 22 | public String getTitle() { 23 | return title; 24 | } 25 | 26 | public void setTitle(String title) { 27 | this.title = title; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "Book{" + 33 | "id=" + id + 34 | ", title='" + title + '\'' + 35 | '}'; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/streams/BoxedStreams.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.IntStream; 7 | 8 | public class BoxedStreams { 9 | public static void main(String[] args) { 10 | 11 | // IntStream.rangeClosed(1, 10) 12 | // .collect(Collectors.toList()); 13 | 14 | IntStream.rangeClosed(1, 10) 15 | .mapToObj(Integer::valueOf) 16 | .collect(Collectors.toList()); 17 | 18 | List ints = IntStream.of(3, 1, 4, 1, 5, 9) 19 | // .collect(Collectors.toList()); 20 | .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); 21 | 22 | List listOfInt = IntStream.of(3, 1, 4, 1, 5, 9) 23 | .boxed() 24 | .collect(Collectors.toList()); 25 | 26 | // IntStream.of(3, 1, 4, 1, 5, 9) 27 | // .collect(Collectors.toCollection(ArrayList::new)); 28 | 29 | int[] intArray = IntStream.of(3, 1, 4, 1, 5, 9) 30 | .toArray(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/streams/ConcatStreams.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.function.Function; 4 | import java.util.stream.Stream; 5 | 6 | public class ConcatStreams { 7 | public static void main(String[] args) { 8 | Stream first = Stream.of("a", "b", "c"); 9 | Stream second = Stream.of("X", "Y", "Z"); 10 | 11 | Stream both = Stream.concat(first, second); 12 | both.forEach(System.out::println); 13 | 14 | // Need to make new ones -- first and second are now closed 15 | first = Stream.of("a", "b", "c"); 16 | second = Stream.of("X", "Y", "Z"); 17 | Stream third = Stream.of("alpha", "beta", "gamma"); 18 | 19 | Stream allThree = Stream.concat(Stream.concat(first, second), third); 20 | allThree.forEach(System.out::println); 21 | 22 | first = Stream.of("a", "b", "c"); 23 | second = Stream.of("X", "Y", "Z"); 24 | third = Stream.of("alpha", "beta", "gamma"); 25 | Stream fourth = Stream.empty(); 26 | 27 | Stream total = Stream.of(first, second, third, fourth) 28 | .reduce(Stream.empty(), Stream::concat); 29 | total.forEach(System.out::println); 30 | 31 | first = Stream.of("a", "b", "c"); 32 | second = Stream.of("X", "Y", "Z"); 33 | third = Stream.of("alpha", "beta", "gamma"); 34 | fourth = Stream.empty(); 35 | 36 | Stream.of(first, second, third, fourth) 37 | .flatMap(Function.identity()) 38 | .forEach(System.out::println); 39 | 40 | first = Stream.of("a", "b", "c").parallel(); 41 | second = Stream.of("X", "Y", "Z"); 42 | third = Stream.of("alpha", "beta", "gamma"); 43 | 44 | total = Stream.of(first, second, third) 45 | .reduce(Stream.empty(), Stream::concat); 46 | System.out.println(total.isParallel()); 47 | 48 | first = Stream.of("a", "b", "c").parallel(); 49 | second = Stream.of("X", "Y", "Z"); 50 | third = Stream.of("alpha", "beta", "gamma"); 51 | fourth = Stream.empty(); 52 | 53 | total = Stream.of(first, second, third, fourth) 54 | .flatMap(Function.identity()); 55 | System.out.println(total.isParallel()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/streams/CountingElements.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.stream.Collectors; 4 | import java.util.stream.Stream; 5 | 6 | public class CountingElements { 7 | @SuppressWarnings("SimplifyStreamApiCallChains") 8 | public static void main(String[] args) { 9 | long count = Stream.of(3, 1, 4, 1, 5, 9, 2, 6, 5) 10 | .count(); 11 | System.out.printf("There are %d elements in the stream%n", count); 12 | 13 | count = Stream.of(3, 1, 4, 1, 5, 9, 2, 6, 5) 14 | .collect(Collectors.counting()); 15 | System.out.printf("There are %d elements in the stream%n", count); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/streams/CreatingStreams.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDate; 5 | import java.util.Arrays; 6 | import java.util.DoubleSummaryStatistics; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.stream.*; 10 | 11 | public class CreatingStreams { 12 | public static void main(String[] args) { 13 | String names = String.join(",", "Gomez", "Morticia", "Wednesday", "Pugsley"); 14 | System.out.println(names); 15 | 16 | String[] munsters = {"Herman", "Lily", "Eddie", "Marilyn", "Grandpa"}; 17 | names = String.join(",", munsters); 18 | System.out.println(names); 19 | 20 | List nums = Stream.iterate(BigDecimal.ONE, n -> n.add(BigDecimal.ONE)) 21 | .limit(10) 22 | .collect(Collectors.toList()); 23 | System.out.println(nums); 24 | 25 | Stream.iterate(LocalDate.now(), d -> d.plusMonths(1)) 26 | .limit(12) 27 | .forEach(System.out::println); 28 | 29 | DoubleSummaryStatistics stats = DoubleStream.generate(Math::random) 30 | .limit(1_000_000) 31 | .summaryStatistics(); 32 | System.out.println(stats); 33 | 34 | List bradyBunch = Arrays.asList("Greg", "Marcia", "Peter", "Jan", "Bobby", "Cindy"); 35 | names = String.join(",", bradyBunch); 36 | System.out.println(names); 37 | 38 | List ints = IntStream.range(10, 15) 39 | .boxed() 40 | // .mapToObj(Integer::valueOf) 41 | .collect(Collectors.toList()); 42 | System.out.println(ints); 43 | 44 | List longs = LongStream.rangeClosed(10, 15) 45 | .boxed() 46 | .collect(Collectors.toList()); 47 | System.out.println(longs); 48 | 49 | Map map = Stream.of("this", "is", "a", "list", "of", "strings") 50 | .collect(Collectors.toMap(s -> s, String::length)); 51 | 52 | map.forEach((word, length) -> System.out.printf( 53 | "The length of %s is %d%n", word, length)); 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/streams/Employee.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.Objects; 4 | 5 | public class Employee { 6 | private String name; 7 | private Integer salary; 8 | private String department; 9 | 10 | public Employee() {} 11 | 12 | public Employee(String name, int salary, String house) { 13 | this.name = name; 14 | this.salary = salary; 15 | this.department = house; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | public Integer getSalary() { 27 | return salary; 28 | } 29 | 30 | public void setSalary(Integer salary) { 31 | this.salary = salary; 32 | } 33 | 34 | public String getDepartment() { 35 | return department; 36 | } 37 | 38 | public void setDepartment(String department) { 39 | this.department = department; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) return true; 45 | if (!(o instanceof Employee)) return false; 46 | 47 | Employee employee = (Employee) o; 48 | 49 | if (!salary.equals(employee.salary)) return false; 50 | if (!Objects.equals(name, employee.name)) return false; 51 | return Objects.equals(department, employee.department); 52 | } 53 | 54 | @Override 55 | public int hashCode() { 56 | int result = name != null ? name.hashCode() : 0; 57 | result = 31 * result + salary; 58 | result = 31 * result + (department != null ? department.hashCode() : 0); 59 | return result; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return String.format("%s of House %s(%d)", name, department, salary); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/streams/GroupingDemo.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Optional; 7 | import java.util.stream.Collectors; 8 | 9 | import static java.util.Comparator.comparingInt; 10 | import static java.util.stream.Collectors.counting; 11 | import static java.util.stream.Collectors.groupingBy; 12 | 13 | public class GroupingDemo { 14 | private static void printMap(Map map) { 15 | map.forEach((k,v) -> System.out.println(k + ": " + v)); 16 | } 17 | 18 | public static void main(String[] args) { 19 | List strings = Arrays.asList("this", "is", "a", "long", "list", "of", 20 | "strings", "to", "use", "as", "a", "demo"); 21 | 22 | Map> lengthMap = strings.stream() 23 | .collect(groupingBy(String::length)); 24 | printMap(lengthMap); 25 | 26 | Map counting = strings.stream() 27 | .collect(groupingBy(String::length, 28 | counting())); 29 | printMap(counting); 30 | 31 | Map> minBy = strings.stream() 32 | .collect(groupingBy(String::length, 33 | Collectors.minBy(comparingInt(String::length)))); 34 | printMap(minBy); 35 | 36 | Map> maxBy = strings.stream() 37 | .collect(groupingBy(String::length, 38 | Collectors.maxBy(comparingInt(String::length)))); 39 | printMap(maxBy); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/streams/LazyStreams.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | public class LazyStreams { 6 | 7 | public static int multByTwo(int n) { 8 | System.out.println("Inside multByTwo with arg n = " + n + 9 | " and thread " + Thread.currentThread().getName()); 10 | return n * 2; 11 | } 12 | 13 | public static boolean modByThree(int n) { 14 | System.out.println("Inside modByThree with n = " + n + 15 | " and thread " + Thread.currentThread().getName()); 16 | return n % 3 == 0; 17 | } 18 | 19 | public static void main(String[] args) { 20 | // Find first even double between 200 and 400 divisible by 3 21 | int firstEvenDoubleDivBy3 = IntStream.range(100, 200) 22 | .filter(n -> n % 3 == 0) 23 | .map(n -> n * 2) 24 | .findFirst().orElse(0); 25 | System.out.println(firstEvenDoubleDivBy3); 26 | 27 | // Demonstrate laziness using print statements 28 | firstEvenDoubleDivBy3 = IntStream.range(100, 2_000_000) 29 | // .parallel() 30 | .filter(LazyStreams::modByThree) 31 | .map(LazyStreams::multByTwo) 32 | .findFirst().orElse(0); 33 | System.out.printf("First even divisible by 3 is %d%n", firstEvenDoubleDivBy3); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/streams/MaxAndMin.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.*; 4 | import java.util.function.BinaryOperator; 5 | import java.util.stream.Collectors; 6 | 7 | public class MaxAndMin { 8 | public static void main(String[] args) { 9 | List employees = Arrays.asList( 10 | new Employee("Cersei", 250_000, "Lannister"), 11 | new Employee("Jamie", 150_000, "Lannister"), 12 | new Employee("Tyrion", 1_000, "Lannister"), 13 | new Employee("Tywin", 1_000_000, "Lannister"), 14 | new Employee("Jon Snow", 75_000, "Stark"), 15 | new Employee("Robb", 120_000, "Stark"), 16 | new Employee("Eddard", 125_000, "Stark"), 17 | new Employee("Sansa", 0, "Stark"), 18 | new Employee("Arya", 1_000, "Stark")); 19 | 20 | Employee defaultEmployee = new Employee("A man (or woman) has no name", 0, "Black and White"); 21 | 22 | Optional optionalEmp = employees.stream() 23 | .reduce(BinaryOperator.maxBy(Comparator.comparingInt(Employee::getSalary))); 24 | System.out.println("Emp with max salary: " + optionalEmp.orElse(defaultEmployee)); 25 | 26 | optionalEmp = employees.stream() 27 | .max(Comparator.comparingInt(Employee::getSalary)); 28 | 29 | System.out.println("Emp with max salary: " + optionalEmp.orElse(defaultEmployee)); 30 | 31 | OptionalInt maxSalary = employees.stream() 32 | .mapToInt(Employee::getSalary) 33 | .max(); 34 | System.out.println("The max salary is " + maxSalary); 35 | 36 | //noinspection SimplifyStreamApiCallChains 37 | optionalEmp = employees.stream() 38 | .collect(Collectors.maxBy(Comparator.comparingInt(Employee::getSalary))); 39 | System.out.println("Emp with max salary: " + optionalEmp.orElse(defaultEmployee)); 40 | 41 | Map> map = employees.stream() 42 | .collect(Collectors.groupingBy(Employee::getDepartment, 43 | Collectors.maxBy(Comparator.comparingInt(Employee::getSalary)))); 44 | 45 | map.forEach((house, emp) -> 46 | System.out.println(house + ": " + emp.orElse(defaultEmployee))); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/streams/PalindromeEvaluator.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.stream.Stream; 4 | 5 | public class PalindromeEvaluator { 6 | public boolean isPalindrome(String s) { 7 | String forward = s.toLowerCase().codePoints() 8 | // .parallel() // whoa. Not worth it, though -- below minimum threshold 9 | .filter(Character::isLetterOrDigit) 10 | .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) 11 | .toString(); 12 | 13 | String backward = new StringBuilder(forward).reverse().toString(); 14 | return forward.equals(backward); 15 | 16 | // StringBuilder sb = new StringBuilder(); 17 | // for (char c : s.toCharArray()) { 18 | // if (Character.isLetterOrDigit(c)) { 19 | // sb.append(c); 20 | // } 21 | // } 22 | // String forward = sb.toString().toLowerCase(); 23 | // String backward = sb.reverse().toString().toLowerCase(); 24 | // return forward.equals(backward); 25 | } 26 | 27 | public static void main(String[] args) { 28 | PalindromeEvaluator eval = new PalindromeEvaluator(); 29 | Stream.of("Madam, in Eden, I'm Adam", 30 | "Go hang a salami; I'm a lasagna hog", 31 | "A Santa pets rats as Pat taps a star step at NASA") 32 | .allMatch(eval::isPalindrome); 33 | 34 | Stream.of("This is NOT a palindrome") 35 | .noneMatch(eval::isPalindrome); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/streams/PartitionDemo.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.stream.Collectors; 7 | 8 | public class PartitionDemo { 9 | public static void main(String[] args) { 10 | List strings = Arrays.asList("this", "is", "a", "long", "list", "of", 11 | "strings", "to", "use", "as", "a", "demo"); 12 | 13 | Map> lengthMap = strings.stream() 14 | .collect(Collectors.partitioningBy(s -> s.length() % 2 == 0)); 15 | 16 | lengthMap.forEach((key,value) -> System.out.printf("%5s: %s%n", key, value)); 17 | 18 | Map numberLengthMap = strings.stream() 19 | .collect(Collectors.partitioningBy(s -> s.length() % 2 == 0, 20 | Collectors.counting())); 21 | 22 | numberLengthMap.forEach((k,v) -> System.out.printf("%5s: %d%n", k, v)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/streams/PeekDemo.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.logging.Logger; 4 | import java.util.stream.IntStream; 5 | 6 | public class PeekDemo { 7 | private final Logger logger = Logger.getLogger(PeekDemo.class.getName()); 8 | 9 | public int sumUpTo(int num) { 10 | return IntStream.rangeClosed(1, num) 11 | .sum(); 12 | } 13 | 14 | public int sumEachDoubleUpTo(int num) { 15 | return IntStream.rangeClosed(1, num) 16 | .peek(n -> System.out.println( 17 | "The value of n before doubling is " + n)) 18 | .map(n -> n * 2) 19 | .sum(); 20 | } 21 | 22 | public int sumDoublesDivisibleBy3(int start, int end) { 23 | return IntStream.rangeClosed(start, end) 24 | // .map(n -> { 25 | // System.out.println("n = " + n); 26 | // return n; 27 | // }) 28 | .peek(n -> System.out.printf("original: %d%n", n)) 29 | .map(n -> n * 2) 30 | .peek(n -> System.out.printf("doubled : %d%n", n)) 31 | .filter(n -> n % 3 == 0) 32 | .peek(n -> System.out.printf("filtered: %d%n", n)) 33 | .sum(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/streams/ProcessDictionary.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.nio.file.Files; 4 | import java.nio.file.Paths; 5 | import java.util.stream.Stream; 6 | 7 | import static java.util.Comparator.comparingInt; 8 | 9 | public class ProcessDictionary { 10 | public static void main(String[] args) throws Exception { 11 | try (Stream lines = 12 | Files.lines(Paths.get("/usr/share/dict/words"))) { 13 | lines.filter(s -> s.length() > 20) 14 | .map(String::toLowerCase) 15 | .sorted(comparingInt(String::length).reversed()) 16 | .limit(10) 17 | .forEach(w -> 18 | System.out.printf("%s (%d)%n", w, w.length())); 19 | } // Stream implements AutoCloseable 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/streams/RandomStreams.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.math.BigDecimal; 4 | import java.security.SecureRandom; 5 | import java.util.DoubleSummaryStatistics; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Random; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.Stream; 11 | 12 | public class RandomStreams { 13 | public static final int LIMIT = 5; 14 | 15 | public static void main(String[] args) { 16 | DoubleSummaryStatistics stats = 17 | Stream.iterate(BigDecimal.ONE, 18 | b -> b.add(BigDecimal.ONE)) 19 | .limit(1_000_000) 20 | .mapToDouble(BigDecimal::doubleValue) 21 | .summaryStatistics(); 22 | System.out.println(stats); 23 | 24 | BigDecimal total = Stream.iterate(BigDecimal.ONE, b -> b.add(BigDecimal.ONE)) 25 | .limit(1_000_000) 26 | .reduce(BigDecimal.ZERO, BigDecimal::add); 27 | System.out.println("Sum of 1,000,000 big decimals: " + total); 28 | 29 | Random r = new Random(); 30 | r.ints(LIMIT) 31 | .sorted() 32 | .forEach(System.out::println); 33 | 34 | r.doubles(LIMIT, 0, 0.5) 35 | .sorted() 36 | .forEach(System.out::println); 37 | 38 | List longs = r.longs(LIMIT) 39 | .boxed() 40 | .collect(Collectors.toList()); 41 | System.out.println(longs); 42 | 43 | List listOfInts = r.ints(LIMIT, 10, 20) 44 | // .collect(Collectors.toList()); 45 | .collect(LinkedList::new, LinkedList::add, LinkedList::addAll); 46 | System.out.println(listOfInts); 47 | 48 | SecureRandom sr = new SecureRandom(); 49 | List integers = sr.ints(LIMIT, 50, 100) 50 | .boxed() 51 | .collect(Collectors.toList()); 52 | System.out.println(integers); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/streams/StreamToIntStream.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.stream.IntStream; 4 | import java.util.stream.Stream; 5 | 6 | public class StreamToIntStream { 7 | public static void main(String[] args) { 8 | Stream ints = Stream.of(3, 1, 4, 1, 5, 9); 9 | 10 | IntStream intStream = ints.mapToInt(n -> n); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/streams/StreamsDemo.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.Random; 7 | import java.util.stream.Stream; 8 | 9 | import static java.util.stream.Collectors.joining; 10 | 11 | public class StreamsDemo { 12 | private final List strings = Arrays.asList("this", "is", "a", 13 | "list", "of", "strings"); 14 | 15 | public String joinStream() { 16 | return String.join(" ", strings); 17 | } 18 | 19 | public String joinUpperCase() { 20 | return strings.stream() 21 | .map(String::toUpperCase) 22 | .collect(joining(" ")); 23 | } 24 | 25 | public int getTotalLength() { 26 | return strings.stream() 27 | .mapToInt(String::length) 28 | .sum(); 29 | } 30 | 31 | public double sumFirstNBigDecimals(int num) { 32 | return Stream.iterate(BigDecimal.ONE, val -> val.add(BigDecimal.ONE)) 33 | .limit(num) 34 | .mapToDouble(BigDecimal::doubleValue) 35 | .sum(); 36 | } 37 | 38 | public BigDecimal sumFirstNBigDecimalsWithPrecision(int num) { 39 | return Stream.iterate(BigDecimal.ONE, n -> n.add(BigDecimal.ONE)) 40 | .limit(num) 41 | // .peek(x -> System.out.println("The value is " + x)) 42 | // .reduce(BigDecimal.ZERO, BigDecimal::add); 43 | .reduce(BigDecimal.ZERO, 44 | (accumulator, val) -> accumulator.add(val)); 45 | } 46 | 47 | public Double sumRandoms1(int num) { 48 | return Stream.generate(Math::random) 49 | .limit(num) 50 | .reduce(Double::sum).orElse(0.0); 51 | } 52 | 53 | public Double sumRandoms2(int num) { 54 | return Stream.generate(Math::random) 55 | .limit(num) 56 | .reduce((acc, n) -> { 57 | System.out.printf("Acc=%s, n=%s%n", acc, n); 58 | return acc + n; 59 | }).orElse(0.0); 60 | } 61 | 62 | public Double sumRandoms3(int num) { 63 | Random r = new Random(); 64 | return r.doubles(num) 65 | .peek(n -> System.out.println(Thread.currentThread().getName() + ": " + n)) 66 | .parallel() 67 | //.limit(num) 68 | .sum(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/streams/SumStringLengths.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.Arrays; 4 | import java.util.OptionalDouble; 5 | import java.util.OptionalInt; 6 | 7 | public class SumStringLengths { 8 | public static void main(String[] args) { 9 | String[] strings = "this is an array of strings".split(" "); 10 | long count = Arrays.stream(strings) 11 | .map(String::length) 12 | .count(); 13 | 14 | System.out.println("There are " + count + " strings"); 15 | 16 | int totalLength = Arrays.stream(strings) 17 | .mapToInt(String::length) 18 | .sum(); 19 | 20 | System.out.println("The total length is " + totalLength); 21 | 22 | OptionalDouble ave = Arrays.stream(strings) 23 | .mapToInt(String::length) 24 | .average(); 25 | 26 | System.out.println("The average length is " + ave); 27 | 28 | OptionalInt max = Arrays.stream(strings) 29 | .mapToInt(String::length) 30 | .max(); 31 | 32 | OptionalInt min = Arrays.stream(strings) 33 | .mapToInt(String::length) 34 | .min(); 35 | 36 | System.out.println("The max and min lengths are " + max + " and " + min); 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/streams/Team.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.text.NumberFormat; 4 | 5 | public class Team { 6 | private static final NumberFormat nf = NumberFormat.getCurrencyInstance(); 7 | 8 | private int id; 9 | private String name; 10 | private double salary; 11 | 12 | public Team(int id, String name, double salary) { 13 | this.id = id; 14 | this.name = name; 15 | this.salary = salary; 16 | } 17 | 18 | public int getId() { 19 | return id; 20 | } 21 | 22 | public void setId(int id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | 34 | public double getSalary() { 35 | return salary; 36 | } 37 | 38 | public void setSalary(double salary) { 39 | this.salary = salary; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return "Team{" + 45 | "id=" + id + 46 | ", name='" + name + '\'' + 47 | ", salary=" + nf.format(salary) + 48 | '}'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/streams/UsingCollect.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | public class UsingCollect { 9 | public static void main(String[] args) { 10 | List strings = Arrays.asList( 11 | "this", "is", "a", "list", "of", "strings"); 12 | 13 | // Side effects --> not what we want 14 | List evenLengths = new ArrayList<>(); 15 | strings.stream() 16 | .filter(s -> s.length() % 2 == 0) 17 | .forEach(evenLengths::add); 18 | System.out.println(evenLengths); 19 | 20 | // No side-effects 21 | List evens = strings.stream() 22 | .filter(s -> s.length() % 2 == 0) 23 | .collect(Collectors.toList()); 24 | System.out.println(evens); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/tasks/Task.java: -------------------------------------------------------------------------------- 1 | package tasks; 2 | 3 | public class Task { 4 | private Integer id; 5 | private boolean active; 6 | private int duration; 7 | private String name; 8 | 9 | public Task() { 10 | } 11 | 12 | public Task(Integer id, boolean active, int duration, String name) { 13 | this.id = id; 14 | this.active = active; 15 | this.duration = duration; 16 | this.name = name; 17 | } 18 | 19 | public Integer getId() { 20 | return id; 21 | } 22 | 23 | public void setId(Integer id) { 24 | this.id = id; 25 | } 26 | 27 | public boolean isActive() { 28 | return active; 29 | } 30 | 31 | public void setActive(boolean active) { 32 | this.active = active; 33 | } 34 | 35 | public int getDuration() { 36 | return duration; 37 | } 38 | 39 | public void setDuration(int duration) { 40 | this.duration = duration; 41 | } 42 | 43 | public String getName() { 44 | return name; 45 | } 46 | 47 | public void setName(String name) { 48 | this.name = name; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "tasks.Task{" + 54 | "active=" + active + 55 | ", duration=" + duration + 56 | ", name='" + name + '\'' + 57 | '}'; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/resources/dict/README: -------------------------------------------------------------------------------- 1 | Added to this project from my local macOS machine, 21 Jan 2020 2 | -- Ken Kousen 3 | 4 | # @(#)README 8.1 (Berkeley) 6/5/93 5 | # $FreeBSD$ 6 | 7 | WEB ---- (introduction provided by jaw@riacs) ------------------------- 8 | 9 | Welcome to web2 (Webster's Second International) all 234,936 words worth. 10 | The 1934 copyright has lapsed, according to the supplier. The 11 | supplemental 'web2a' list contains hyphenated terms as well as assorted 12 | noun and adverbial phrases. The wordlist makes a dandy 'grep' victim. 13 | 14 | -- James A. Woods {ihnp4,hplabs}!ames!jaw (or jaw@riacs) 15 | 16 | Country names are stored in the file /usr/share/misc/iso3166. 17 | 18 | 19 | FreeBSD Maintenance Notes --------------------------------------------- 20 | 21 | Note that FreeBSD is not maintaining a historical document, we're 22 | maintaining a list of current [American] English spellings. 23 | 24 | A few words have been removed because their spellings have depreciated. 25 | This list of words includes: 26 | corelation (and its derivatives) "correlation" is the preferred spelling 27 | freen typographical error in original file 28 | freend archaic spelling no longer in use; 29 | masks common typo in modern text 30 | 31 | -- 32 | 33 | A list of technical terms has been added in the file 'freebsd'. This 34 | word list contains FreeBSD/Unix lexicon that is used by the system 35 | documentation. It makes a great ispell(1) personal dictionary to 36 | supplement the standard English language dictionary. 37 | -------------------------------------------------------------------------------- /src/main/resources/dict/connectives: -------------------------------------------------------------------------------- 1 | the 2 | of 3 | and 4 | to 5 | a 6 | in 7 | that 8 | is 9 | was 10 | he 11 | for 12 | it 13 | with 14 | as 15 | his 16 | on 17 | be 18 | at 19 | by 20 | i 21 | this 22 | had 23 | not 24 | are 25 | but 26 | from 27 | or 28 | have 29 | an 30 | they 31 | which 32 | one 33 | you 34 | were 35 | her 36 | all 37 | she 38 | there 39 | would 40 | their 41 | we 42 | him 43 | been 44 | has 45 | when 46 | who 47 | will 48 | more 49 | no 50 | if 51 | out 52 | so 53 | said 54 | what 55 | up 56 | its 57 | about 58 | into 59 | than 60 | them 61 | can 62 | only 63 | other 64 | new 65 | some 66 | could 67 | time 68 | these 69 | two 70 | may 71 | then 72 | do 73 | first 74 | any 75 | my 76 | now 77 | such 78 | like 79 | our 80 | over 81 | man 82 | me 83 | even 84 | most 85 | made 86 | after 87 | also 88 | did 89 | many 90 | before 91 | must 92 | through 93 | back 94 | years 95 | where 96 | much 97 | your 98 | way 99 | well 100 | down 101 | should 102 | because 103 | each 104 | just 105 | those 106 | people 107 | mr 108 | how 109 | too 110 | little 111 | state 112 | good 113 | very 114 | make 115 | world 116 | still 117 | own 118 | see 119 | men 120 | work 121 | long 122 | get 123 | here 124 | between 125 | both 126 | life 127 | being 128 | under 129 | never 130 | day 131 | same 132 | another 133 | know 134 | while 135 | last 136 | might 137 | us 138 | great 139 | old 140 | year 141 | off 142 | come 143 | since 144 | against 145 | go 146 | came 147 | right 148 | used 149 | take 150 | three 151 | -------------------------------------------------------------------------------- /src/main/resources/mlb_team_salaries_2017.txt: -------------------------------------------------------------------------------- 1 | 1 Los Angeles Dodgers 26 $132,253,598 $62,688,808 $38,223,808 $15,155,000 - $245,269,535 2 | 2 Boston Red Sox 25 $166,836,396 $9,225,750 $4,581,252 $26,581,428 - $202,135,939 3 | 3 New York Yankees 25 $124,183,310 $48,978,357 $27,381,692 $4,309,625 - $202,095,552 4 | 4 Detroit Tigers 25 $144,709,140 $18,535,000 $19,500,000 $21,961,400 - $201,109,372 5 | 5 Toronto Blue Jays 25 $141,526,675 $22,131,368 $17,738,051 $4,185,700 - $182,739,336 6 | 6 Texas Rangers 25 $109,371,183 $39,874,360 $30,413,193 $4,131,740 - $181,996,701 7 | 7 San Francisco Giants 25 $161,538,337 $17,216,000 $84,767 $5,135,500 - $179,366,985 8 | 8 Chicago Cubs 25 $151,952,550 $20,760,500 $99,099 $3,210,000 - $172,867,686 9 | 9 Washington Nationals 25 $132,557,576 $33,555,428 $4,202,923 $2,677,800 - $170,755,497 10 | 10 Baltimore Orioles 25 $120,901,564 $42,388,782 $4,863,133 $4,828,500 - $168,538,646 11 | 11 Los Angeles Angels of Anaheim 25 $92,957,338 $41,898,833 $30,798,492 $5,374,500 - $166,410,941 12 | 12 Seattle Mariners 25 $93,161,660 $57,464,842 $3,565,930 $11,374,100 - $159,434,560 13 | 13 New York Mets 27 $100,333,731 $55,267,125 $5,406,335 $1,623,125 - $156,442,092 14 | 14 Kansas City Royals 25 $109,036,969 $20,185,250 $15,564,034 $7,462,600 - $149,288,806 15 | 15 St. Louis Cardinals 24 $120,714,247 $9,070,000 $17,237,427 $3,237,800 - $147,626,405 16 | 16 Colorado Rockies 25 $86,380,364 $14,452,000 $29,667,229 $3,397,000 - $131,215,815 17 | 17 Houston Astros 25 $89,699,696 $34,085,200 $2,484,900 $5,745,000 - $128,451,022 18 | 18 Atlanta Braves 25 $69,703,731 $43,551,875 $10,082,179 $4,142,500 - $125,563,332 19 | 19 Cleveland Indians 25 $100,435,194 $6,483,300 $9,884,439 $3,775,200 - $125,425,261 20 | 20 Minnesota Twins 25 $70,988,041 $29,330,000 $12,790,837 $6,607,500 - $117,257,426 21 | 21 Miami Marlins 25 $73,741,710 $33,520,000 $4,900,000 $8,962,500 - $113,581,657 22 | 22 Philadelphia Phillies 25 $71,604,648 $16,597,000 $24,192,918 $2,677,000 - $112,874,466 23 | 23 Pittsburgh Pirates 25 $80,739,468 $7,160,000 $9,737,696 $5,380,500 $3,147,540 $104,098,424 24 | 24 Chicago White Sox 25 $86,062,443 $13,193,000 $1,823,770 $3,210,000 - $101,479,664 25 | 25 Cincinnati Reds 25 $60,316,607 $20,687,000 $23,957,386 $5,887,000 - $100,629,481 26 | 26 Arizona Diamondbacks 25 $71,481,974 $21,488,200 $1,410,000 $1,618,300 - $94,549,567 27 | 27 Oakland Athletics 25 $61,582,939 $3,787,500 $15,976,174 $5,365,000 - $82,115,706 28 | 28 San Diego Padres 25 $24,445,802 $10,354,700 $37,263,858 $4,965,500 - $73,754,027 29 | 29 Tampa Bay Rays 26 $52,595,992 $20,291,966 $2,923 $3,220,600 - $73,102,766 30 | 30 Milwaukee Brewers 25 $35,309,088 $21,089,500 $2,689,571 $8,033,200 - $62,094,433 -------------------------------------------------------------------------------- /src/main/resources/simple_file.txt: -------------------------------------------------------------------------------- 1 | This is a 2 | very simple file 3 | with some text 4 | 5 | in it and this has 6 | 7 | some simple duplicates 8 | with the text -------------------------------------------------------------------------------- /src/test/java/PalindromeCheckerTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.DisplayName; 2 | import org.junit.jupiter.api.Test; 3 | import org.junit.jupiter.api.TestInstance; 4 | import org.junit.jupiter.params.ParameterizedTest; 5 | import org.junit.jupiter.params.provider.MethodSource; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | import static org.junit.jupiter.api.Assertions.*; 11 | 12 | @TestInstance(TestInstance.Lifecycle.PER_CLASS) 13 | public class PalindromeCheckerTest { 14 | private final List palindromes = Arrays.asList( 15 | "Madam, in Eden, I'm Adam", 16 | "Flee to me, remote elf!", 17 | "Go hang a salami; I'm a lasagna hog" 18 | ); 19 | 20 | @Test 21 | public void isPalidromeUsingLambda() { 22 | palindromes.forEach(s -> { 23 | StringBuilder sb = new StringBuilder(); 24 | for (char c : s.toCharArray()) { 25 | if (Character.isLetter(c)) { 26 | sb.append(c); 27 | } 28 | } 29 | String forward = sb.toString().toLowerCase(); 30 | String backward = sb.reverse().toString().toLowerCase(); 31 | assertEquals(forward, backward); 32 | } 33 | ); 34 | } 35 | 36 | @Test 37 | public void isPalidromeUsingMethodRef() { 38 | assertTrue( 39 | palindromes.stream() 40 | .allMatch(PalindromeChecker::checkPalindrome)); 41 | 42 | assertFalse( 43 | PalindromeChecker.checkPalindrome("This is NOT a palindrome")); 44 | } 45 | 46 | List palindromeProvider() { 47 | return palindromes; 48 | } 49 | 50 | @DisplayName("JUnit 5 parameterized test for palindromes") 51 | @ParameterizedTest(name = "{0} is a palindrome") 52 | @MethodSource("palindromeProvider") 53 | void palindromes(String candidate) { 54 | assertTrue(PalindromeChecker.checkPalindrome(candidate)); 55 | } 56 | } -------------------------------------------------------------------------------- /src/test/java/PrimesTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions; 2 | import org.junit.jupiter.api.Test; 3 | 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.IntStream; 8 | import java.util.stream.Stream; 9 | 10 | import static org.junit.jupiter.api.Assertions.*; 11 | 12 | public class PrimesTest { 13 | private final Primes calculator = new Primes(); 14 | 15 | @Test // Iterative 16 | public void testIsPrime() { 17 | IntStream.of(2, 3, 5, 7, 11, 13, 17, 19) 18 | .forEach(n -> Assertions.assertTrue(calculator.isPrime(n))); 19 | 20 | Assertions.assertFalse(calculator.isPrime(4)); 21 | } 22 | 23 | @Test // Functional :) 24 | public void testIsPrimeWithStreams() { 25 | Assertions.assertTrue(Stream.of(2, 3, 5, 7, 11, 13, 17, 19) 26 | .allMatch(calculator::isPrime)); 27 | } 28 | 29 | @Test 30 | public void testIsPrimeWithComposites() { 31 | Assertions.assertFalse(IntStream.of(4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20) 32 | .anyMatch(calculator::isPrime)); 33 | Assertions.assertTrue(IntStream.of(4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20) 34 | .noneMatch(calculator::isPrime)); 35 | } 36 | 37 | @Test 38 | public void testNextPrime() { 39 | Assertions.assertEquals(2, calculator.nextPrime(1)); 40 | Assertions.assertEquals(3, calculator.nextPrime(2)); 41 | Assertions.assertEquals(5, calculator.nextPrime(3)); 42 | Assertions.assertEquals(5, calculator.nextPrime(4)); 43 | Assertions.assertEquals(7, calculator.nextPrime(5)); 44 | Assertions.assertEquals(7, calculator.nextPrime(6)); 45 | } 46 | 47 | @Test 48 | public void testNextPrimeUsingMap() { 49 | List expected = Arrays.asList(2, 3, 5, 5, 7, 7); 50 | 51 | List computed = Stream.of(1, 2, 3, 4, 5, 6) 52 | .map(calculator::nextPrime) 53 | .collect(Collectors.toList()); 54 | 55 | Assertions.assertEquals(expected, computed); 56 | } 57 | 58 | @Test 59 | public void emptyStreamsDanger() { 60 | Assertions.assertTrue(Stream.empty().allMatch(e -> false)); 61 | Assertions.assertTrue(Stream.empty().noneMatch(e -> true)); 62 | Assertions.assertFalse(Stream.empty().anyMatch(e -> true)); 63 | } 64 | } -------------------------------------------------------------------------------- /src/test/java/collectors/CollectorsDemoTest.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.*; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | import static org.junit.jupiter.api.Assertions.assertTrue; 9 | 10 | public class CollectorsDemoTest { 11 | private final CollectorsDemo demo = new CollectorsDemo(); 12 | 13 | @Test 14 | public void createList() { 15 | List nameList = demo.createList(); 16 | assertEquals(7, nameList.size()); 17 | assertEquals(ArrayList.class, nameList.getClass()); 18 | } 19 | 20 | @Test 21 | public void createSet() { 22 | Set nameSet = demo.createSet(); 23 | assertEquals(6, nameSet.size()); 24 | assertEquals(HashSet.class, nameSet.getClass()); 25 | } 26 | 27 | @Test 28 | public void createDeque() { 29 | Deque nameDeque = demo.createDeque(); 30 | assertEquals(7, nameDeque.size()); 31 | assertEquals(ArrayDeque.class, nameDeque.getClass()); 32 | } 33 | 34 | @Test 35 | public void createArray() { 36 | String[] names = demo.createArray(); 37 | assertEquals(4, names.length); 38 | } 39 | 40 | @Test 41 | public void evenLengthStrings() { 42 | List evenLengthStrings = 43 | demo.evenLengthStrings("here", "are", "a", "few", "strings"); 44 | evenLengthStrings.forEach(s -> { 45 | assertEquals(0, s.length() % 2); 46 | }); 47 | } 48 | 49 | @Test 50 | public void evenLengthStringSet() { 51 | SortedSet stringSet = demo.oddLengthStringSet("here", "are", "a", "few", "strings"); 52 | System.out.println(stringSet); 53 | stringSet.forEach(s -> assertTrue(s.length() % 2 != 0)); 54 | stringSet.first().equals("a"); 55 | stringSet.last().equals("strings"); 56 | } 57 | } -------------------------------------------------------------------------------- /src/test/java/collectors/ImmutableCollectionsTest.java: -------------------------------------------------------------------------------- 1 | package collectors; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | import static org.junit.jupiter.api.Assertions.assertThrows; 11 | 12 | public class ImmutableCollectionsTest { 13 | private final ImmutableCollections demo = new ImmutableCollections(); 14 | 15 | @Test 16 | public void createImmutableList() { 17 | List list = demo.createImmutableList("this", "is", "a", "list"); 18 | assertEquals(4, list.size()); 19 | assertEquals("this", list.get(0)); 20 | assertEquals("is", list.get(1)); 21 | assertEquals("a", list.get(2)); 22 | assertEquals("list", list.get(3)); 23 | assertThrows(UnsupportedOperationException.class, () -> list.add("extra")); 24 | } 25 | 26 | @Test 27 | public void createImmutableListJava7() { 28 | List list = demo.createImmutableListJava7("this", "is", "a", "list"); 29 | assertEquals(4, list.size()); 30 | assertEquals("this", list.get(0)); 31 | assertEquals("is", list.get(1)); 32 | assertEquals("a", list.get(2)); 33 | assertEquals("list", list.get(3)); 34 | assertThrows(UnsupportedOperationException.class, () -> list.add("extra")); 35 | } 36 | 37 | @Test 38 | public void createImmutableSet() { 39 | Set set = demo.createImmutableSet("a", "b", "b", "c"); 40 | assertEquals(3, set.size()); 41 | assertTrue(set.contains("a")); 42 | assertTrue(set.contains("b")); 43 | assertTrue(set.contains("c")); 44 | assertThrows(UnsupportedOperationException.class, () -> set.add("d")); 45 | } 46 | 47 | @Test 48 | public void createImmutableSetJava7() { 49 | Set set = demo.createImmutableSetJava7("a", "b", "b", "c"); 50 | assertEquals(3, set.size()); 51 | assertTrue(set.contains("a")); 52 | assertTrue(set.contains("b")); 53 | assertTrue(set.contains("c")); 54 | assertThrows(UnsupportedOperationException.class, () -> set.add("d")); 55 | } 56 | 57 | @Test 58 | public void immutableMap() { 59 | assertThrows(UnsupportedOperationException.class, () -> demo.map.put("a", 5)); 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /src/test/java/concurrency/AwaitQuiesenceTest.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import org.junit.jupiter.api.Disabled; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.concurrent.CompletableFuture; 7 | import java.util.concurrent.ExecutionException; 8 | import java.util.concurrent.ForkJoinPool; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | import static org.junit.jupiter.api.Assertions.*; 12 | 13 | public class AwaitQuiesenceTest { 14 | private final AwaitQuiesence aq = new AwaitQuiesence(); 15 | 16 | @Test 17 | public void get() { 18 | try { 19 | CompletableFuture cf = aq.supplyThenAccept(); 20 | cf.get(); 21 | assertTrue(cf.isDone()); 22 | } catch (InterruptedException | ExecutionException e) { 23 | e.printStackTrace(); 24 | } 25 | } 26 | 27 | @Test 28 | public void join() { 29 | CompletableFuture cf = aq.supplyThenAccept(); 30 | cf.join(); 31 | assertTrue(cf.isDone()); 32 | } 33 | 34 | @Test @Disabled("Causing issues with Github Action") 35 | public void awaitQuiesence() { 36 | CompletableFuture cf = aq.supplyThenAccept(); 37 | assertFalse(cf.isDone()); 38 | 39 | ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.SECONDS); 40 | assertTrue(cf.isDone()); 41 | } 42 | } -------------------------------------------------------------------------------- /src/test/java/concurrency/CompletableFutureDemosTest.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.concurrent.ExecutionException; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | import static org.junit.jupiter.api.Assertions.fail; 9 | import static org.junit.jupiter.api.Assertions.assertThrows; 10 | 11 | public class CompletableFutureDemosTest { 12 | private final CompletableFutureDemos demo = new CompletableFutureDemos(); 13 | 14 | @Test 15 | public void testRemote() throws Exception { 16 | Product product = demo.getProduct(1).get(); 17 | assertEquals(1, product.getId()); 18 | } 19 | 20 | @Test 21 | public void testLocal() throws Exception { 22 | demo.getProduct(1).get(); 23 | Product product = demo.getProduct(1).get(); 24 | assertEquals(1, product.getId()); 25 | } 26 | 27 | @Test 28 | public void testException() { 29 | assertThrows(ExecutionException.class, () -> { 30 | try { 31 | demo.getProduct(666).get(); 32 | } catch (InterruptedException e) { 33 | throw new RuntimeException(e); 34 | } 35 | }); 36 | } 37 | 38 | @Test 39 | public void testExceptionWithCause() throws Exception { 40 | try { 41 | demo.getProduct(666).get(); 42 | fail("Houston, we have a problem..."); 43 | } catch (ExecutionException e) { 44 | assertEquals(ExecutionException.class, e.getClass()); 45 | assertEquals(RuntimeException.class, e.getCause().getClass()); 46 | } 47 | } 48 | 49 | @Test 50 | public void getProductAsync() throws Exception { 51 | Product product = demo.getProductAsync(1).get(); 52 | assertEquals(1, product.getId()); 53 | } 54 | } -------------------------------------------------------------------------------- /src/test/java/concurrency/SequentialToParallelTest.java: -------------------------------------------------------------------------------- 1 | package concurrency; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertFalse; 11 | import static org.junit.jupiter.api.Assertions.assertTrue; 12 | 13 | public class SequentialToParallelTest { 14 | @Test 15 | public void sequentialStreamOf() { 16 | assertFalse(Stream.of(3, 1, 4, 1, 5, 9).isParallel()); 17 | } 18 | 19 | @Test 20 | public void sequentialIterateStream() { 21 | assertFalse(Stream.iterate(1, n -> n + 1).isParallel()); 22 | } 23 | 24 | @Test 25 | public void sequentialGenerateStream() { 26 | assertFalse(Stream.generate(Math::random).isParallel()); 27 | } 28 | 29 | @Test 30 | public void sequentialCollectionStream() { 31 | List numbers = Arrays.asList(3, 1, 4, 1, 5, 9); 32 | assertFalse(numbers.stream().isParallel()); 33 | } 34 | 35 | @Test 36 | public void parallelMethodOnStream() { 37 | assertTrue(Stream.of(3, 1, 4, 1, 5, 9) 38 | .parallel() 39 | .isParallel()); 40 | } 41 | 42 | @Test 43 | public void parallelStreamMethodOnCollection() { 44 | List numbers = Arrays.asList(3, 1, 4, 1, 5, 9); 45 | assertTrue(numbers.parallelStream().isParallel()); 46 | } 47 | 48 | @Test 49 | public void parallelStreamThenSequential() { 50 | List numbers = Arrays.asList(3, 1, 4, 1, 5, 9); 51 | assertFalse(numbers.parallelStream() 52 | .sequential() 53 | .isParallel()); 54 | } 55 | 56 | @Test 57 | public void switchingParallelToSequentialInSameStream() { 58 | List numbers = Arrays.asList(3, 1, 4, 1, 5, 9); 59 | List nums = numbers.parallelStream() 60 | .map(n -> n * 2) 61 | .peek(n -> System.out.printf("%s processing %d%n", Thread.currentThread().getName(), n)) 62 | .sequential() 63 | .sorted() 64 | .collect(Collectors.toList()); 65 | System.out.println(nums); 66 | } 67 | } -------------------------------------------------------------------------------- /src/test/java/datetime/ConvertDateTest.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.time.LocalDate; 6 | import java.time.LocalDateTime; 7 | import java.util.Date; 8 | 9 | public class ConvertDateTest { 10 | private final ConvertDate cd = new ConvertDate(); 11 | 12 | @Test 13 | public void convertFromDateToLD() { 14 | Date now = new Date(); 15 | LocalDate localDate = cd.convertFromUtilDateToLocalDate(now); 16 | System.out.println(now + " " + localDate); 17 | } 18 | 19 | @Test 20 | public void convertFromDateToLDUsingString() { 21 | Date now = new Date(); 22 | LocalDateTime localDateTime = cd.convertFromUtilDateToLDUsingString(now); 23 | System.out.println(now + " " + localDateTime); 24 | } 25 | 26 | 27 | 28 | } -------------------------------------------------------------------------------- /src/test/java/datetime/PaydayAdjusterTest.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.time.LocalDate; 6 | import java.time.Month; 7 | import java.time.temporal.TemporalAdjuster; 8 | import java.util.stream.IntStream; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | 12 | public class PaydayAdjusterTest { 13 | @Test 14 | public void payDay() { 15 | TemporalAdjuster adjuster = new PaydayAdjuster(); 16 | IntStream.rangeClosed(1, 14) 17 | .mapToObj(day -> LocalDate.of(2017, Month.JULY, day)) 18 | .forEach(date -> 19 | assertEquals(14, date.with(adjuster).getDayOfMonth())); 20 | 21 | IntStream.rangeClosed(15, 31) 22 | .mapToObj(day -> LocalDate.of(2017, Month.JULY, day)) 23 | .forEach(date -> 24 | assertEquals(31, date.with(adjuster).getDayOfMonth())); 25 | } 26 | 27 | @Test 28 | public void payDayWithMethodRef() { 29 | IntStream.rangeClosed(1, 14) 30 | .mapToObj(day -> LocalDate.of(2017, Month.JULY, day)) 31 | .forEach(date -> 32 | assertEquals(14, date.with(Adjusters::adjustInto).getDayOfMonth())); 33 | 34 | IntStream.rangeClosed(15, 31) 35 | .mapToObj(day -> LocalDate.of(2017, Month.JULY, day)) 36 | .forEach(date -> 37 | assertEquals(31, date.with(Adjusters::adjustInto).getDayOfMonth())); 38 | } 39 | } -------------------------------------------------------------------------------- /src/test/java/datetime/RegionIdsByOffsetTest.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.time.ZoneId; 6 | import java.time.ZonedDateTime; 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | public class RegionIdsByOffsetTest { 12 | @Test 13 | public void getRegionNamesForGMT() { 14 | List names = RegionIdsByOffset.getRegionNamesForOffset(0, 0); 15 | 16 | assertTrue(names.contains("GMT")); 17 | assertTrue(names.contains("Etc/GMT")); 18 | assertTrue(names.contains("Etc/UTC")); 19 | assertTrue(names.contains("UTC")); 20 | assertTrue(names.contains("Etc/Zulu")); 21 | } 22 | 23 | @Test 24 | public void getRegionNamesForNepal() { 25 | List names = RegionIdsByOffset.getRegionNamesForOffset(5, 45); 26 | 27 | assertTrue(names.contains("Asia/Kathmandu")); 28 | assertTrue(names.contains("Asia/Katmandu")); 29 | } 30 | 31 | @Test 32 | public void getRegionNamesForNewYork() { 33 | ZoneId nyc = ZoneId.of("America/New_York"); 34 | List names = RegionIdsByOffset.getRegionNamesForZoneId(nyc); 35 | 36 | assertTrue(names.contains("America/New_York")); 37 | assertTrue(names.contains("US/Eastern")); 38 | assertTrue(names.contains("Etc/GMT+4") || names.contains("Etc/GMT+5")); 39 | assertTrue(names.contains("Canada/Eastern")); 40 | } 41 | 42 | @Test 43 | public void getRegionNamesForChicago() { 44 | ZoneId chicago = ZoneId.of("America/Chicago"); 45 | List names = RegionIdsByOffset.getRegionNamesForZoneId(chicago); 46 | 47 | assertTrue(names.contains("America/Chicago")); 48 | assertTrue(names.contains("US/Central")); 49 | assertTrue(names.contains("Canada/Central")); 50 | assertTrue(names.contains("Etc/GMT+5") || names.contains("Etc/GMT+6")); 51 | } 52 | 53 | @Test 54 | public void getRegionNamesForSystemDefault() { 55 | ZonedDateTime now = ZonedDateTime.now(); 56 | ZoneId zoneId = now.getZone(); 57 | List names = RegionIdsByOffset.getRegionNamesForZoneId(zoneId); 58 | 59 | assertTrue(names.contains(zoneId.getId())); 60 | } 61 | } -------------------------------------------------------------------------------- /src/test/java/datetime/TemporalAdjusterTests.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.time.DayOfWeek; 6 | import java.time.LocalDateTime; 7 | import java.time.Month; 8 | import java.time.temporal.TemporalAdjusters; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | 12 | public class TemporalAdjusterTests { 13 | @Test 14 | public void adjusters() { 15 | LocalDateTime start = LocalDateTime.of(2017, Month.FEBRUARY, 2, 11, 30); 16 | LocalDateTime end = start.with(TemporalAdjusters.firstDayOfNextMonth()); 17 | assertEquals("2017-03-01T11:30", end.toString()); 18 | 19 | end = start.with(TemporalAdjusters.next(DayOfWeek.THURSDAY)); 20 | assertEquals("2017-02-09T11:30", end.toString()); 21 | 22 | end = start.with(TemporalAdjusters.previousOrSame(DayOfWeek.THURSDAY)); 23 | assertEquals("2017-02-02T11:30", end.toString()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/datetime/TemporalQueriesTests.java: -------------------------------------------------------------------------------- 1 | package datetime; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.time.*; 6 | import java.time.temporal.ChronoField; 7 | import java.time.temporal.ChronoUnit; 8 | import java.time.temporal.TemporalAccessor; 9 | import java.util.stream.IntStream; 10 | 11 | import static java.time.temporal.ChronoUnit.DAYS; 12 | import static java.time.temporal.ChronoUnit.NANOS; 13 | import static java.time.temporal.TemporalQueries.*; 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | import static org.junit.jupiter.api.Assertions.assertTrue; 16 | 17 | public class TemporalQueriesTests { 18 | @Test 19 | public void queries() { 20 | assertEquals(DAYS, LocalDate.now().query(precision())); 21 | assertEquals(NANOS, LocalTime.now().query(precision())); 22 | 23 | ZoneOffset offset = ZonedDateTime.now().getOffset(); 24 | ZoneOffset query = ZonedDateTime.now().query(offset()); 25 | assertEquals(offset, query); 26 | 27 | assertEquals(ZoneId.systemDefault(), ZonedDateTime.now().query(zone())); 28 | assertEquals(ZoneId.systemDefault(), ZonedDateTime.now().query(zoneId())); 29 | } 30 | 31 | private long daysUntilPirateDay(TemporalAccessor temporal) { 32 | int day = temporal.get(ChronoField.DAY_OF_MONTH); 33 | int month = temporal.get(ChronoField.MONTH_OF_YEAR); 34 | int year = temporal.get(ChronoField.YEAR); 35 | LocalDate date = LocalDate.of(year, month, day); 36 | LocalDate tlapd = LocalDate.of(year, Month.SEPTEMBER, 19); 37 | if (date.isAfter(tlapd)) { 38 | tlapd = tlapd.plusYears(1); 39 | } 40 | return ChronoUnit.DAYS.between(date, tlapd); 41 | } 42 | 43 | @Test 44 | public void pirateDay() { 45 | IntStream.range(10, 19) 46 | .mapToObj(n -> LocalDate.of(2017, Month.SEPTEMBER, n)) 47 | .forEach(date -> 48 | assertTrue(date.query(this::daysUntilPirateDay) <= 9)); 49 | IntStream.rangeClosed(20, 30) 50 | .mapToObj(n -> LocalDate.of(2017, Month.SEPTEMBER, n)) 51 | .forEach(date -> { 52 | Long days = date.query(PirateQuery::daysUntilPirateDay); 53 | assertTrue(days >= 354 && days < 365); 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/defaults/CompanyEmployeeTest.java: -------------------------------------------------------------------------------- 1 | package defaults; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class CompanyEmployeeTest { 8 | 9 | @Test 10 | void getName() { 11 | CompanyEmployee peterGibbons = new CompanyEmployee("Peter", "Gibbons"); 12 | 13 | assertEquals("Peter Gibbons works for Initech", 14 | peterGibbons.getName()); 15 | } 16 | } -------------------------------------------------------------------------------- /src/test/java/fileio/JumbleTest.java: -------------------------------------------------------------------------------- 1 | package fileio; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.List; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | import static org.junit.jupiter.api.Assertions.assertAll; 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | 11 | class JumbleTest { 12 | private final Jumble jumble = new Jumble(); 13 | 14 | @Test 15 | void checkSolver() { 16 | assertAll( 17 | () -> assertEquals("actual", jumble.solve("cautla")), 18 | () -> assertEquals("goalie", jumble.solve("agileo")) 19 | ); 20 | } 21 | 22 | @Test 23 | void checkParallelSolve() { 24 | List strings = jumble.parallelSolve("zaaem", "rwdoc", "tlufan"); 25 | System.out.println(strings); 26 | assertThat(strings).contains("amaze", "crowd", "flaunt"); 27 | System.out.println(jumble.parallelSolve("snsaoe", "craigl", "ssevur", 28 | "lonelp", "nlahed", "ceitkl")); 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/java/fileio/ProcessDictionaryTest.java: -------------------------------------------------------------------------------- 1 | package fileio; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class ProcessDictionaryTest { 8 | 9 | @Test 10 | void maxLength() { 11 | ProcessDictionary pd = new ProcessDictionary(); 12 | assertEquals(24, pd.maxLength()); 13 | } 14 | } -------------------------------------------------------------------------------- /src/test/java/functionpackage/ImplementPredicateTest.java: -------------------------------------------------------------------------------- 1 | package functionpackage; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.stream.Stream; 7 | 8 | import static functionpackage.ImplementPredicate.LENGTH_FIVE; 9 | import static functionpackage.ImplementPredicate.STARTS_WITH_S; 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | 12 | public class ImplementPredicateTest { 13 | private final ImplementPredicate demo = new ImplementPredicate(); 14 | private String[] names; 15 | 16 | @BeforeEach 17 | public void setUp() { 18 | names = Stream.of("Mal", "Wash", "Kaylee", "Inara", "Zoë", 19 | "Jayne", "Simon", "River", "Shepherd Book") 20 | .sorted() 21 | .toArray(String[]::new); 22 | } 23 | 24 | @Test 25 | public void getNames() { 26 | String expected = "Inara, Jayne, Kaylee, Mal, River, Shepherd Book, Simon, Wash, Zoë"; 27 | assertEquals(expected, demo.getNames(names)); 28 | } 29 | 30 | @Test 31 | public void getNamesOfLength5() { 32 | assertEquals("Inara, Jayne, River, Simon", demo.getNamesOfLength(5, names)); 33 | } 34 | 35 | @Test 36 | public void getNamesStartingWithS() { 37 | assertEquals("Shepherd Book, Simon", demo.getNamesStartingWith("S", names)); 38 | } 39 | 40 | @Test 41 | public void getNamesSatisfyingCondition() { 42 | assertEquals("Inara, Jayne, River, Simon", 43 | demo.getNamesSatisfyingCondition(s -> s.length() == 5, names)); 44 | assertEquals("Shepherd Book, Simon", 45 | demo.getNamesSatisfyingCondition(s -> s.startsWith("S"), names)); 46 | assertEquals("Inara, Jayne, River, Simon", 47 | demo.getNamesSatisfyingCondition(LENGTH_FIVE, names)); 48 | assertEquals("Shepherd Book, Simon", 49 | demo.getNamesSatisfyingCondition(STARTS_WITH_S, names)); 50 | } 51 | 52 | @Test 53 | public void composedPredicate() { 54 | assertEquals("Simon", 55 | demo.getNamesSatisfyingCondition( 56 | LENGTH_FIVE.and(STARTS_WITH_S), names)); 57 | assertEquals("Inara, Jayne, River, Shepherd Book, Simon", 58 | demo.getNamesSatisfyingCondition( 59 | LENGTH_FIVE.or(STARTS_WITH_S), names)); 60 | assertEquals("Kaylee, Mal, Shepherd Book, Wash, Zoë", 61 | demo.getNamesSatisfyingCondition(LENGTH_FIVE.negate(), names)); 62 | 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /src/test/java/generics/ProcessColorsTest.java: -------------------------------------------------------------------------------- 1 | package generics; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.awt.*; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | 10 | public class ProcessColorsTest { 11 | private final ProcessColors processColors = new ProcessColors(); 12 | private final Color color = new Color(100, 50, 0); 13 | 14 | @BeforeEach 15 | public void setUp() { 16 | processColors.setColor(color); 17 | } 18 | 19 | @Test 20 | public void noProcessing() { 21 | Color c = processColors.applyFilter(color -> color); 22 | assertEquals(new Color(100, 50, 0), c); 23 | } 24 | 25 | @Test 26 | public void makeBrighter() { 27 | Color c = processColors.applyFilter(Color::brighter); 28 | assertEquals(new Color(142, 71, 0), c); 29 | } 30 | 31 | @Test 32 | public void makeDarker() { 33 | Color c = processColors.applyFilter(Color::darker); 34 | assertEquals(new Color(70, 35, 0), c); 35 | } 36 | 37 | @Test 38 | public void makeBrighterThenDarker() { 39 | Color c = processColors.applyFilters( 40 | Color::brighter, Color::darker); 41 | assertEquals(new Color(99, 49, 0), c); 42 | } 43 | } -------------------------------------------------------------------------------- /src/test/java/lambdas/AlgorithmsTest.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.params.ParameterizedTest; 5 | import org.junit.jupiter.params.provider.CsvSource; 6 | 7 | import java.math.BigInteger; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertAll; 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | 12 | public class AlgorithmsTest { 13 | @Test 14 | public void testFactorial() { 15 | assertAll( 16 | () -> assertEquals(BigInteger.ONE, Algorithms.factorial(0)), 17 | () -> assertEquals(BigInteger.ONE, Algorithms.factorial(1)), 18 | () -> assertEquals(BigInteger.valueOf(2), Algorithms.factorial(2)), 19 | () -> assertEquals(BigInteger.valueOf(6), Algorithms.factorial(3)), 20 | () -> assertEquals(BigInteger.valueOf(24), Algorithms.factorial(4)), 21 | () -> assertEquals(BigInteger.valueOf(120), Algorithms.factorial(5))); 22 | System.out.println("factorial(50000) has " + 23 | Algorithms.factorial(50000).toString().length() + " digits"); 24 | } 25 | 26 | @ParameterizedTest 27 | @CsvSource({"0, 1", "1, 1", "2, 2", 28 | "3, 6", "4, 24", "5, 120"}) 29 | public void testFactorialParameterized(long num, int expected) { 30 | assertEquals(BigInteger.valueOf(expected), Algorithms.factorial(num)); 31 | } 32 | } -------------------------------------------------------------------------------- /src/test/java/lambdas/CompositionDemoTest.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.function.IntPredicate; 6 | import java.util.stream.IntStream; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertFalse; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | public class CompositionDemoTest { 12 | 13 | @Test 14 | public void perfectSquares() { 15 | assertTrue(CompositionDemo.isPerfect(4)); 16 | assertTrue(CompositionDemo.isPerfect(9)); 17 | assertTrue(CompositionDemo.isPerfect(16)); 18 | assertTrue(CompositionDemo.isPerfect(25)); 19 | assertFalse(CompositionDemo.isPerfect(10)); 20 | System.out.println("Perfect squares:"); 21 | IntStream.rangeClosed(1, 200) 22 | .filter(CompositionDemo::isPerfect) 23 | .forEach(System.out::println); 24 | } 25 | 26 | @Test 27 | public void prime() { 28 | assertTrue(CompositionDemo.isPrime(2)); 29 | assertTrue(CompositionDemo.isPrime(3)); 30 | assertTrue(CompositionDemo.isPrime(5)); 31 | assertTrue(CompositionDemo.isPrime(7)); 32 | assertTrue(CompositionDemo.isPrime(11)); 33 | assertTrue(CompositionDemo.isPrime(13)); 34 | assertTrue(CompositionDemo.isPrime(17)); 35 | assertFalse(CompositionDemo.isPrime(15)); 36 | 37 | IntStream.rangeClosed(1, 200) 38 | .filter(CompositionDemo::isPrime) 39 | .forEach(System.out::println); 40 | } 41 | 42 | @Test 43 | public void triangular() { 44 | assertTrue(CompositionDemo.isTriangular(1)); 45 | assertTrue(CompositionDemo.isTriangular(3)); 46 | assertTrue(CompositionDemo.isTriangular(6)); 47 | assertTrue(CompositionDemo.isTriangular(10)); 48 | assertTrue(CompositionDemo.isTriangular(15)); 49 | assertTrue(CompositionDemo.isTriangular(21)); 50 | assertFalse(CompositionDemo.isTriangular(4)); 51 | 52 | System.out.println("Triangle numbers: "); 53 | IntStream.rangeClosed(1, 200) 54 | .filter(CompositionDemo::isTriangular) 55 | .forEach(System.out::println); 56 | } 57 | 58 | @Test 59 | public void triangularAndPerfect() { 60 | IntPredicate triangular = CompositionDemo::isTriangular; 61 | IntPredicate perfect = CompositionDemo::isPerfect; 62 | IntPredicate both = triangular.and(perfect); 63 | assertTrue(both.test(1)); 64 | assertTrue(both.test(36)); 65 | assertTrue(both.test(1225)); 66 | assertFalse(both.test(15)); 67 | assertFalse(both.test(25)); 68 | 69 | IntStream.rangeClosed(1, 10_000) 70 | .filter(both) 71 | .forEach(System.out::println); 72 | } 73 | } -------------------------------------------------------------------------------- /src/test/java/lambdas/SupplierTest.java: -------------------------------------------------------------------------------- 1 | package lambdas; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertTrue; 6 | 7 | public class SupplierTest { 8 | 9 | private String getErrorMessage() { 10 | System.out.println("Inside getErrorMessage()"); 11 | return "Error"; 12 | } 13 | 14 | @Test 15 | void showError() { 16 | boolean x = true; 17 | // assertTrue(x, getErrorMessage()); 18 | assertTrue(x, () -> getErrorMessage()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/mapvsflatmap/PersonConstructorTest.java: -------------------------------------------------------------------------------- 1 | package mapvsflatmap; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.stream.Stream; 6 | 7 | public class PersonConstructorTest { 8 | 9 | @Test 10 | public void personConstructors() { 11 | Stream.of("Spock", "Data") 12 | .map(Person::new) 13 | .forEach(System.out::println); 14 | 15 | Stream.of("Montgomery Scott", "Hikaru Sulu") 16 | .map(name -> name.split(" ")) 17 | .map(Person::new) 18 | .forEach(System.out::println); 19 | 20 | Stream.of("James Tiberius Kirk", "Peter Quincy Taggert") 21 | .map(name -> name.split(" ")) 22 | .map(Person::new) 23 | .forEach(System.out::println); 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/java/mapvsflatmap/WordMapTest.java: -------------------------------------------------------------------------------- 1 | package mapvsflatmap; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | public class WordMapTest { 13 | private final WordMap wordMap = new WordMap(); 14 | private final Map sample = new HashMap<>(); 15 | 16 | @BeforeEach 17 | public void setUp() { 18 | wordMap.setFileName("simple_file.txt"); 19 | sample.put("some", 2L); 20 | sample.put("this", 2L); 21 | sample.put("simple", 2L); 22 | sample.put("with", 2L); 23 | sample.put("text", 2L); 24 | sample.put("duplicates", 1L); 25 | sample.put("very", 1L); 26 | sample.put("a", 1L); 27 | sample.put("in", 1L); 28 | sample.put("is", 1L); 29 | sample.put("it", 1L); 30 | sample.put("the", 1L); 31 | sample.put("file", 1L); 32 | sample.put("and", 1L); 33 | sample.put("has", 1L); 34 | } 35 | 36 | @Test 37 | public void checkSampleFile() { 38 | Map map = this.wordMap.createMap(); 39 | assertEquals(sample.size(), map.size()); 40 | sample.forEach((word, count) -> { 41 | System.out.printf("%s: %d%n", word, count); 42 | assertTrue(map.containsKey(word)); 43 | assertEquals(count, map.get(word)); 44 | }); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/test/java/objects/ObjectsDemoTest.java: -------------------------------------------------------------------------------- 1 | package objects; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.Objects; 8 | import java.util.Random; 9 | import java.util.stream.Collectors; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertTrue; 12 | 13 | public class ObjectsDemoTest { 14 | private final ObjectsDemo demo = new ObjectsDemo(); 15 | 16 | @Test 17 | public void getStrings() { 18 | List strings = Arrays.asList("this", "is", "a", "list", "of", "strings"); 19 | assertTrue(Objects.deepEquals(strings, demo.getStrings())); 20 | } 21 | 22 | @Test 23 | public void getNonNullStrings() { 24 | List strings = Arrays.asList("this", "is", "a", null, "list", "of", null, "strings"); 25 | demo.setStrings(strings); 26 | assertTrue(Objects.deepEquals( 27 | Arrays.asList("this", "is", "a", "list", "of", "strings"), 28 | demo.getNonNullStrings())); 29 | } 30 | 31 | @Test 32 | public void getNonNullElements() { 33 | Random random = new Random(); 34 | List doubles = random.doubles() 35 | .limit(10) 36 | .mapToObj(r -> r < 0.5 ? null : r) 37 | .collect(Collectors.toList()); 38 | System.out.println(doubles); 39 | List nonNullElements = demo.getNonNullElements(doubles); 40 | System.out.println(nonNullElements); 41 | nonNullElements.forEach(r -> 42 | assertTrue(Objects.nonNull(r))); 43 | } 44 | } -------------------------------------------------------------------------------- /src/test/java/optionals/HRTest.java: -------------------------------------------------------------------------------- 1 | package optionals; 2 | 3 | import org.junit.jupiter.api.AfterEach; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | import static org.junit.jupiter.api.Assertions.*; 12 | 13 | public class HRTest { 14 | private final HR hr = HR.getInstance(); 15 | private final List sampleEmployees = Arrays.asList( 16 | new Employee("Malcolm Reynolds"), 17 | new Employee("Zoe Washburne"), 18 | new Employee("Hoban Washburne"), 19 | new Employee("Jayne Cobb"), 20 | new Employee("Kaylee Frye")); 21 | 22 | @BeforeEach 23 | public void setUp() { 24 | hr.hire(sampleEmployees); 25 | } 26 | 27 | @AfterEach 28 | public void tearDown() { 29 | hr.reset(); 30 | } 31 | 32 | @Test 33 | public void hireNotNull() { 34 | int id = hr.hire(new Employee("River Tam")); 35 | assertTrue(hr.findEmployeeById(id).isPresent()); 36 | } 37 | 38 | @Test 39 | public void hireNull() { 40 | assertThrows(NullPointerException.class, () -> hr.hire((Employee) null)); 41 | } 42 | 43 | @Test 44 | public void findEmployeeById() { 45 | sampleEmployees 46 | .forEach(e -> assertTrue(hr.findEmployeeById(e.getId()).isPresent())); 47 | } 48 | 49 | @Test 50 | public void findEmployeesByIds1() { 51 | List ids = sampleEmployees.stream() 52 | .map(Employee::getId) 53 | .collect(Collectors.toList()); 54 | 55 | ids.add(99); 56 | 57 | assertFalse(hr.findEmployeeById(99).isPresent()); 58 | 59 | List emps = hr.findEmployeesByIds1(ids); 60 | assertEquals(sampleEmployees.size(), emps.size()); 61 | sampleEmployees.forEach(e -> assertTrue(emps.contains(e))); 62 | } 63 | 64 | @Test 65 | public void findEmployeesByIds2() { 66 | List ids = sampleEmployees.stream() 67 | .map(Employee::getId) 68 | .collect(Collectors.toList()); 69 | 70 | ids.add(86); 71 | 72 | assertFalse(hr.findEmployeeById(86).isPresent()); 73 | 74 | List emps = hr.findEmployeesByIds2(ids); 75 | assertEquals(sampleEmployees.size(), emps.size()); 76 | sampleEmployees.forEach(e -> assertTrue(emps.contains(e))); 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /src/test/java/sorting/SortingMapsTest.java: -------------------------------------------------------------------------------- 1 | package sorting; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | public class SortingMapsTest { 12 | private final SortingMaps sm = new SortingMaps<>(); 13 | private final Map map = new HashMap<>(); 14 | 15 | @BeforeEach 16 | public void setUp() { 17 | map.put("a", 1); 18 | map.put("b", 2); 19 | map.put("c", 2); 20 | map.put("d", 1); 21 | map.put("e", 3); 22 | sm.setMap(map); 23 | } 24 | 25 | @Test 26 | public void getMapSortedByKey() { 27 | sm.getMapSortedByKey().keySet().stream() 28 | .reduce((prev, curr) -> { 29 | assertTrue(prev.compareTo(curr) <= 0); 30 | return curr; 31 | }); 32 | } 33 | 34 | @Test 35 | public void getMapSortedByKeyDesc() { 36 | sm.getMapSortedByKeyDesc().keySet().stream() 37 | .reduce((prev, curr) -> { 38 | assertTrue(prev.compareTo(curr) >= 0); 39 | return curr; 40 | }); 41 | } 42 | 43 | @Test 44 | public void getMapSortedByValue() { 45 | sm.getMapSortedByValue().values().stream() 46 | .reduce((prev, curr) -> { 47 | assertTrue(prev.compareTo(curr) <= 0); 48 | return curr; 49 | }); 50 | } 51 | 52 | @Test 53 | public void getMapSortedByValueDesc() { 54 | Map result = sm.getMapSortedByValueDesc(); 55 | result.values().stream() 56 | .reduce((prev, curr) -> { 57 | assertTrue(prev.compareTo(curr) >= 0); 58 | return curr; 59 | }); 60 | } 61 | 62 | private void printMap(Map m) { 63 | m.forEach((k,v) -> System.out.println(k + ": " + v)); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /src/test/java/streams/PalindromeEvaluatorTest.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.stream.Stream; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertTrue; 9 | 10 | public class PalindromeEvaluatorTest { 11 | private final PalindromeEvaluator demo = new PalindromeEvaluator(); 12 | 13 | @Test 14 | public void isPalindrome() { 15 | assertTrue( 16 | Stream.of("Madam, in Eden, I'm Adam", 17 | "Go hang a salami; I'm a lasagna hog", 18 | "Flee to me, remote elf!", 19 | "A Santa pets rats as Pat taps a star step at NASA") 20 | .allMatch(demo::isPalindrome)); 21 | 22 | assertFalse(demo.isPalindrome("This is NOT a palindrome")); 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/java/streams/PeekDemoTest.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | public class PeekDemoTest { 8 | private final PeekDemo demo = new PeekDemo(); 9 | 10 | @Test 11 | public void sumUpTo() { 12 | assertEquals(55, demo.sumUpTo(10)); 13 | assertEquals(5050, demo.sumUpTo(100)); 14 | } 15 | 16 | @Test 17 | public void sumEachDoubleUpTo() { 18 | assertEquals(2 * 55, demo.sumEachDoubleUpTo(10)); 19 | assertEquals(2 * 5050, demo.sumEachDoubleUpTo(100)); 20 | } 21 | 22 | @Test 23 | public void sumDoublesDivisibleBy3() { 24 | assertEquals(1554, demo.sumDoublesDivisibleBy3(100, 120)); 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/java/streams/StreamsDemoTest.java: -------------------------------------------------------------------------------- 1 | package streams; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | import static org.assertj.core.api.Assertions.within; 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | public class StreamsDemoTest { 10 | private final StreamsDemo demo = new StreamsDemo(); 11 | 12 | @Test 13 | public void testJoinStream() { 14 | assertEquals("this is a list of strings", demo.joinStream()); 15 | } 16 | 17 | @Test 18 | public void testJoinUpperCase() { 19 | assertEquals("THIS IS A LIST OF STRINGS", demo.joinUpperCase()); 20 | } 21 | 22 | @Test 23 | public void testGetTotalLength() { 24 | assertEquals(20, demo.getTotalLength()); 25 | } 26 | 27 | @Test 28 | public void testSumFirstNBigDecimals() { 29 | assertThat(demo.sumFirstNBigDecimals(10)).isEqualTo(55, within(0.0001)); 30 | } 31 | 32 | @Test 33 | public void testSumFirstNBigDecimalsWithPrecision() { 34 | System.out.println(demo.sumFirstNBigDecimalsWithPrecision(10)); 35 | } 36 | 37 | @Test 38 | public void testSumRandoms1() { 39 | int num = 1000; 40 | double err = num * 0.05; 41 | assertThat(demo.sumRandoms1(num)).isEqualTo(num / 2.0, within(err)); 42 | } 43 | 44 | @Test 45 | public void testSumRandoms2() { 46 | int num = 1000; 47 | double err = num * 0.05; 48 | assertThat(demo.sumRandoms2(num)).isEqualTo(num / 2.0, within(err)); 49 | } 50 | 51 | @Test 52 | public void demoReduceWithAccumulator() { 53 | demo.sumRandoms2(10); 54 | } 55 | 56 | @Test 57 | public void testSumRandoms3() { 58 | int num = 1000; 59 | double err = num * 0.05; 60 | assertThat(demo.sumRandoms3(num)).isEqualTo(num / 2.0, within(err)); 61 | } 62 | } --------------------------------------------------------------------------------