├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── java8-best-practice └── pom.xml ├── java8-completablefuture ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── biezhi │ └── java8 │ └── completablefuture │ ├── CompletableFuture1.java │ ├── CompletableFuture10.java │ ├── CompletableFuture2.java │ ├── CompletableFuture3.java │ ├── CompletableFuture4.java │ ├── CompletableFuture5.java │ ├── CompletableFuture6.java │ ├── CompletableFuture7.java │ ├── CompletableFuture8.java │ ├── CompletableFuture9.java │ └── Future1.java ├── java8-concurrent ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── biezhi │ └── java8 │ └── concurrent │ ├── Atomic1.java │ ├── ConcurrentHashMap1.java │ ├── ConcurrentUtils.java │ ├── Executors1.java │ ├── Executors2.java │ ├── Executors3.java │ ├── Lock1.java │ ├── Lock2.java │ ├── Lock3.java │ ├── Lock4.java │ ├── Lock5.java │ ├── Lock6.java │ ├── LongAccumulator1.java │ ├── LongAdder1.java │ ├── Semaphore1.java │ ├── Semaphore2.java │ ├── Synchronized1.java │ ├── Synchronized2.java │ └── Threads1.java ├── java8-datetime-api ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── biezhi │ └── datetime │ ├── ClockExample.java │ ├── ConvertExample.java │ ├── DateTimeFormatExample.java │ ├── DurationExample.java │ ├── InstantExample.java │ ├── LocalDateExample.java │ ├── LocalDateTimeExample.java │ ├── LocalTimeExample.java │ ├── ZoneIdExample.java │ └── ZonedDateTimeExample.java ├── java8-default-methods ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── biezhi │ └── java8 │ └── defaultmethods │ ├── BasicCalculator.java │ ├── Calculator.java │ ├── CalculatorFactory.java │ ├── Collection.java │ ├── UseCalc.java │ └── conflict │ ├── A.java │ ├── App.java │ ├── App2.java │ ├── App3.java │ ├── B.java │ └── C.java ├── java8-growing ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── github │ │ └── biezhi │ │ └── java8 │ │ └── growing │ │ ├── jdk5 │ │ ├── AutoBoxing.java │ │ ├── Concurrent.java │ │ ├── EnumDemo.java │ │ ├── ForEach.java │ │ ├── Generic.java │ │ ├── StaticImport.java │ │ └── VarArgs.java │ │ ├── jdk6 │ │ ├── CompilerAPI.java │ │ ├── Console.java │ │ ├── DesktopTray.java │ │ ├── HttpServerAPI.java │ │ └── ScriptEngineDemo.java │ │ ├── jdk7 │ │ ├── CatchMultiException.java │ │ ├── NumericUnderline.java │ │ ├── SwitchString.java │ │ ├── TryWithResource.java │ │ └── TypeInference.java │ │ └── jdk8 │ │ ├── Base64Demo.java │ │ ├── DateTimeAPI.java │ │ ├── DefaulableFactory.java │ │ ├── Functional.java │ │ ├── FunctionalDefaultMethods.java │ │ ├── Lambda.java │ │ ├── NashornDemo.java │ │ ├── OptionalDemo.java │ │ ├── ParallelArrays.java │ │ ├── Streams.java │ │ └── TypeInference.java │ └── resources │ └── test.js ├── java8-lambda ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── biezhi │ └── java8 │ └── lambda │ ├── lesson1 │ ├── FilterProjects.java │ ├── Project.java │ ├── ProjectPredicate.java │ └── predicate │ │ ├── ProjectLanguagePredicate.java │ │ └── ProjectStarPredicate.java │ ├── lesson2 │ └── FunctionalDemo.java │ └── lesson3 │ ├── ConstructorReference.java │ ├── DoneByYou.java │ ├── LambdaException.java │ ├── Lambdas.java │ ├── MethodReference.java │ └── OtherReference.java ├── java8-nashorn ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── github │ │ └── biezhi │ │ └── java8 │ │ └── nashorn │ │ ├── Nashorn1.java │ │ ├── Nashorn10.java │ │ ├── Nashorn11.java │ │ ├── Nashorn2.java │ │ ├── Nashorn3.java │ │ ├── Nashorn4.java │ │ ├── Nashorn5.java │ │ ├── Nashorn6.java │ │ ├── Nashorn7.java │ │ ├── Nashorn8.java │ │ ├── Nashorn9.java │ │ ├── Person.java │ │ ├── Product.java │ │ └── SuperRunner.java │ └── resources │ ├── nashorn1.js │ ├── nashorn10.js │ ├── nashorn2.js │ ├── nashorn3.js │ ├── nashorn4.js │ ├── nashorn5.js │ ├── nashorn6.js │ ├── nashorn7.js │ ├── nashorn8.js │ └── nashorn9.js ├── java8-optional ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── biezhi │ └── java8 │ └── optional │ ├── Address.java │ ├── BeforeJava8.java │ ├── OptionalDemo.java │ └── User.java ├── java8-proper └── pom.xml ├── java8-stream ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── biezhi │ └── java8 │ └── stream │ ├── Project.java │ ├── lesson1 │ ├── Java7.java │ └── Java8.java │ ├── lesson2 │ ├── Example1.java │ ├── Example2.java │ ├── Example3.java │ ├── Example4.java │ ├── Example5.java │ ├── Example6.java │ ├── Example7.java │ ├── Quiz1.java │ ├── Quiz2.java │ ├── Quiz3.java │ ├── Quiz4.java │ └── QuizEnd.java │ └── lesson3 │ ├── Example1.java │ ├── Example2.java │ ├── Example3.java │ ├── Example4.java │ ├── Example5.java │ └── Example6.java └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### VisualStudioCode template 3 | .vscode/* 4 | !.vscode/settings.json 5 | !.vscode/tasks.json 6 | !.vscode/launch.json 7 | !.vscode/extensions.json 8 | .project 9 | *.iml 10 | .idea/ 11 | .vscode/ 12 | .classpath 13 | ### Eclipse template 14 | 15 | .metadata 16 | bin/ 17 | tmp/ 18 | *.tmp 19 | *.bak 20 | *.swp 21 | *~.nib 22 | local.properties 23 | .settings/ 24 | .loadpath 25 | .recommenders 26 | 27 | # External tool builders 28 | .externalToolBuilders/ 29 | 30 | # Locally stored "Eclipse launch configurations" 31 | *.launch 32 | 33 | # PyDev specific (Python IDE for Eclipse) 34 | *.pydevproject 35 | 36 | # CDT-specific (C/C++ Development Tooling) 37 | .cproject 38 | 39 | # CDT- autotools 40 | .autotools 41 | 42 | # Java annotation processor (APT) 43 | .factorypath 44 | 45 | # PDT-specific (PHP Development Tools) 46 | .buildpath 47 | 48 | # sbteclipse plugin 49 | .target 50 | 51 | # Tern plugin 52 | .tern-project 53 | 54 | # TeXlipse plugin 55 | .texlipse 56 | 57 | # STS (Spring Tool Suite) 58 | .springBeans 59 | 60 | # Code Recommenders 61 | .recommenders/ 62 | 63 | # Scala IDE specific (Scala & Java development for Eclipse) 64 | .cache-main 65 | .scala_dependencies 66 | .worksheet 67 | ### JetBrains template 68 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 69 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 70 | 71 | # User-specific stuff: 72 | .idea/**/workspace.xml 73 | .idea/**/tasks.xml 74 | .idea/dictionaries 75 | 76 | # Sensitive or high-churn files: 77 | .idea/**/dataSources/ 78 | .idea/**/dataSources.ids 79 | .idea/**/dataSources.xml 80 | .idea/**/dataSources.local.xml 81 | .idea/**/sqlDataSources.xml 82 | .idea/**/dynamic.xml 83 | .idea/**/uiDesigner.xml 84 | 85 | # Gradle: 86 | .idea/**/gradle.xml 87 | .idea/**/libraries 88 | 89 | # CMake 90 | cmake-build-debug/ 91 | cmake-build-release/ 92 | 93 | # Mongo Explorer plugin: 94 | .idea/**/mongoSettings.xml 95 | 96 | ## File-based project format: 97 | *.iws 98 | 99 | ## Plugin-specific files: 100 | 101 | # IntelliJ 102 | out/ 103 | 104 | # mpeltonen/sbt-idea plugin 105 | .idea_modules/ 106 | 107 | # JIRA plugin 108 | atlassian-ide-plugin.xml 109 | 110 | # Cursive Clojure plugin 111 | .idea/replstate.xml 112 | 113 | # Crashlytics plugin (for Android Studio and IntelliJ) 114 | com_crashlytics_export_strings.xml 115 | crashlytics.properties 116 | crashlytics-build.properties 117 | fabric.properties 118 | ### Maven template 119 | target/ 120 | pom.xml.tag 121 | pom.xml.releaseBackup 122 | pom.xml.versionsBackup 123 | pom.xml.next 124 | release.properties 125 | dependency-reduced-pom.xml 126 | buildNumber.properties 127 | .mvn/timing.properties 128 | 129 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 130 | !/.mvn/wrapper/maven-wrapper.jar 131 | ### Java template 132 | # Compiled class file 133 | *.class 134 | 135 | # Log file 136 | *.log 137 | 138 | # BlueJ files 139 | *.ctxt 140 | 141 | # Mobile Tools for Java (J2ME) 142 | .mtj.tmp/ 143 | 144 | # Package Files # 145 | *.jar 146 | *.war 147 | *.ear 148 | *.zip 149 | *.tar.gz 150 | *.rar 151 | 152 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 153 | hs_err_pid* 154 | 155 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 5 | 6 | notifications: 7 | email: false 8 | 9 | sudo: false 10 | 11 | before_install: 12 | - export TZ='Asia/Shanghai' -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 王爵nice (biezhi.me@gmail.com) 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 跟上 Java 8 教程 2 | 3 | 这个仓库存储了『跟上Java 8』视频课程源码。 4 | 5 | Java8 改变了我们思考和编码的方式,在这里你可以学习到 Java8 中的核心特性以及使用场景,跟我学习 Java8,让你的编程更轻松! 6 | 7 | [![Travis Build](https://travis-ci.org/biezhi/learn-java8.svg?branch=master)](https://travis-ci.org/biezhi/learn-java8) 8 | [![License](https://img.shields.io/badge/license-BSD--3-blue.svg)](https://github.com/biezhi/learn-java8/blob/master/LICENSE) 9 | [![@biezhi on zhihu](https://img.shields.io/badge/zhihu-%40biezhi-red.svg)](https://www.zhihu.com/people/biezhi) 10 | [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/biezhii.svg?style=social&label=Follow%20Twitter)](https://twitter.com/biezhii) 11 | [![](https://img.shields.io/github/followers/biezhi.svg?style=social&label=Follow%20Github)](https://github.com/biezhi) 12 | 13 | 课程的讲授方式原则是:**What**、**Why**、**How** 14 | 15 | 我们会说清楚每个技能是什么,为什么是这样,以及编码演示他们的使用方法以及场景, 16 | 最后会讲解 Java 8 中的最佳实践以及正确的函数式编程姿势。 17 | 18 | ## 课程大纲 19 | 20 | | 课时数 | 课时标题 | 在线播放 | 源码位置 | 21 | |:-----:|:--------|:-------|:-------| 22 | |第 1 课 | [课程介绍](https://github.com/biezhi/learn-java8) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051513399&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_1.html#page=1) ¦ [Youtube](https://youtu.be/A733pQxiEDk) | 无 | 23 | |第 2 课 | [Java 8 的发展](https://github.com/biezhi/learn-java8/blob/master/java8-growing/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051508577&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_2.html#page=2) ¦ [Youtube](https://youtu.be/fHhgm1AZzhs) | [java8-growing](https://github.com/biezhi/learn-java8/tree/master/java8-growing/src/main/java/io/github/biezhi/java8/growing) | 24 | |第 3 课 | [理解 lambda](https://github.com/biezhi/learn-java8/blob/master/java8-lambda/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051516241&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_3.html#page=3) ¦ [Youtube](https://youtu.be/VkdMeFEGDH8) | [lambda1](https://github.com/biezhi/learn-java8/tree/master/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1) | 25 | |第 4 课 | [初尝 lambda](https://github.com/biezhi/learn-java8/blob/master/java8-lambda/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051511463&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_4.html#page=4) ¦ [Youtube](https://youtu.be/X7Zv5vygjTc) | [lambda2](https://github.com/biezhi/learn-java8/tree/master/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson2) | 26 | |第 5 课 | [lambda 进阶](https://github.com/biezhi/learn-java8/blob/master/java8-lambda/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051518174&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_5.html#page=5) ¦ [Youtube](https://youtu.be/3G83it4IASc) | [lambda3](https://github.com/biezhi/learn-java8/tree/master/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3) | 27 | |第 6 课 | [默认方法的妙用](https://github.com/biezhi/learn-java8/blob/master/java8-default-methods/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051518175&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_6.html#page=6) ¦ [Youtube](https://youtu.be/sAuEnkWezDM) | [default-method](https://github.com/biezhi/learn-java8/tree/master/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods) | 28 | |第 7 课 | [干掉空指针之 Optional](https://github.com/biezhi/learn-java8/blob/master/java8-optional/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051511464&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_7.html#page=7) ¦ [Youtube](https://youtu.be/br4kqCXPB9A) | [optional](https://github.com/biezhi/learn-java8/tree/master/java8-default-methods/src/main/java/io/github/biezhi/java8/optional) | 29 | |第 8 课 | [理解 Stream](https://github.com/biezhi/learn-java8/blob/master/java8-stream/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051555343&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_8.html#page=8) ¦ [Youtube](https://youtu.be/NB9mGlNMl-w) | [stream](https://github.com/biezhi/learn-java8/tree/master/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson1) | 30 | |第 9 课 | [Stream API(上)](https://github.com/biezhi/learn-java8/blob/master/java8-stream/README.md#%E4%BD%BF%E7%94%A8%E6%B5%81) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051566020&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_9.html#page=9) ¦ [Youtube](https://youtu.be/mGwFJERNzmY) | [stream](https://github.com/biezhi/learn-java8/blob/master/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2) | 31 | |第 10 课 | [Stream API(下)](https://github.com/biezhi/learn-java8/blob/master/java8-stream/README.md#collector-%E6%94%B6%E9%9B%86) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051571684&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_10.html#page=10) ¦ [Youtube](https://youtu.be/iubE0ezu-xI) | [stream](https://github.com/biezhi/learn-java8/tree/master/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson3) | 32 | |第 11 课 | [新的日期时间 API](https://github.com/biezhi/learn-java8/blob/master/java8-datetime-api/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051571688&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_11.html#page=11) ¦ [Youtube](https://youtu.be/hKXJvh-id1E) | [datetime](https://github.com/biezhi/learn-java8/tree/master/java8-datetime-api/src/main/java/io/github/biezhi/datetime) | 33 | |第 12 课 | [并发增强](https://github.com/biezhi/learn-java8/blob/master/java8-concurrent/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051682806&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_12.html#page=12) ¦ [Youtube](https://youtu.be/OYkToWIDEEI) | [concurrent](https://github.com/biezhi/learn-java8/tree/master/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent) | 34 | |第 13 课 | [CompletableFuture](https://github.com/biezhi/learn-java8/blob/master/java8-completablefuture/README.md) | [网易云课堂](http://study.163.com/course/courseLearn.htm?courseId=1005047049&utm_campaign=commission&utm_source=cp-400000000397038&utm_medium=share#/learn/video?lessonId=1051908792&courseId=1005047049) ¦ [哔哩哔哩](https://www.bilibili.com/video/av19287893/index_13.html#page=13) ¦ [Youtube](https://youtu.be/4reRygD1dGo) | [completablefuture](https://github.com/biezhi/learn-java8/tree/master/java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture) | 35 | |第 14 课 | Nashorn 引擎 | 网易云课堂 ¦ 哔哩哔哩 ¦ Youtube | | 36 | |第 15 课| Java 8 最佳实践 | 网易云课堂 ¦ 哔哩哔哩 ¦ Youtube | | 37 | |第 16 课| 函数式编程的正确姿势 | 网易云课堂 ¦ 哔哩哔哩 ¦ Youtube | | 38 | 39 | > 💡 点击课时标题即可查看课程大纲 40 | > 41 | > 💊 建议课程食用方式: x1.25倍速效果更佳 42 | 43 | ## 相关资源 44 | 45 | - 本套课程的所有源码存储在 [Github](https://github.com/biezhi/learn-java8) 上 46 | - 欢迎关注知乎专栏 [《跟上 Java 8》](https://zhuanlan.zhihu.com/java8) 学习更多优质内容 47 | 48 | ## 交流 49 | 50 | 在学习 Java8 过程中有疑问可以在QQ群:**663887729** 交流或者在视频的评论区留言。 51 | 你也可以在 Github 上发起一个 [issue](https://github.com/biezhi/learn-java8/issues/new) 提问。 52 | 53 | ## 捐赠作者 54 | 55 | 我们提供的所有视频和源码都是免费的,如果你在这个过程中学习到了技能可以扫描下方二维码赞赏作者。 56 | 57 | 58 | 59 | ## 授权许可 60 | 61 | 除特别声明外,本套教程中的内容使用 [CC BY-SA 3.0 License](https://creativecommons.org/licenses/by-sa/3.0/deed.zh)(创作共用 署名-相同方式共享 3.0 许可协议)授权, 62 | 代码遵循 [BSD 3-Clause](https://opensource.org/licenses/BSD-3-Clause) License(3 项条款的 BSD 许可协议)。 63 | -------------------------------------------------------------------------------- /java8-best-practice/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-best-practice 13 | 14 | -------------------------------------------------------------------------------- /java8-completablefuture/README.md: -------------------------------------------------------------------------------- 1 | # CompletableFuture 2 | 3 | ## 为什么要引入 CompletableFuture 4 | 5 | - Future.get() 方法会阻塞线程,一直阻塞,直到其所对应的任务完成或因为异常退出。在不恰当的地方调用此方法会因为线程阻塞而降低系统响应度。就像文中提到的。 6 | - Future.get(long, TimeUnit) 可以一定的时间内超时退出,而不会像前一个方法那样一直阻塞线程。但是这对系统响应性的改进是治标不治本。 7 | - Java 8 引入了 CompletableFuture,可用通过 CompletableFuture thenAccept(Consumer action) 方法异步触发 send(Response) 方法。这时 serve() 方法会很快结束。而当 responseFuture 所对应的任务完成时,send(Response) 方法便会被调用,其执行线程同 responseFuture 所对应的任务的执行线程相同。 8 | - 对于上一点,有人会问,何必这么麻烦?直接在 responseFuture 所对应任务 (Runnable or Callable) 里面调用 send(Response) 方法。各种在实际工作中可能会遇到的问题暂且不说。只说两点: 9 | 1. responseFuture 所对应任务是不可修改的,比如调用自第三方模块 10 | 2. 即便代码可修改,但在 responseFuture 所对应的任务中去调用 send(Response) 方法表明的含义是后者的功能从属于前者。这可能从业务角度上看是不合理的。即在本例中,responseFuture 所对应的任务和 send(Response) 方法在业务角度讲是属于同一级的。违反这一点会对代码可读性和可维护性不利。 11 | 12 | ## 创建 CompletableFuture 13 | 14 | 以下四个静态方法用来为一段异步执行的代码创建 `CompletableFuture` 对象: 15 | 16 | ```java 17 | static CompletableFuture runAsync(Runnable runnable) 18 | static CompletableFuture runAsync(Runnable runnable, Executor executor) 19 | static CompletableFuture supplyAsync(Supplier supplier) 20 | static CompletableFuture supplyAsync(Supplier supplier, Executor executor) 21 | ``` 22 | 23 | 以 `Async` 结尾并且没有指定 `Executor` 的方法会使用 `ForkJoinPool.commonPool()` 作为它的线程池执行异步代码。 24 | 25 | ## 计算结果完成时的处理 26 | 27 | 当 `CompletableFuture` 的计算结果完成,或者抛出异常的时候,我们可以执行特定的 `Action`。 28 | 29 | ```javap 30 | CompletableFuture whenComplete(BiConsumer action) 31 | CompletableFuture whenCompleteAsync(BiConsumer action) 32 | CompletableFuture whenCompleteAsync(BiConsumer action, Executor executor) 33 | CompletableFuture exceptionally(Function fn) 34 | ``` 35 | 36 | 同时进行计算和转换 37 | 38 | ```java 39 | CompletableFuture handle(BiFunction fn) 40 | CompletableFuture handleAsync(BiFunction fn) 41 | CompletableFuture handleAsync(BiFunction fn, Executor executor) 42 | ``` 43 | 44 | ## 结果转换(map) 45 | 46 | ```java 47 | CompletableFuture thenApply(Function fn) 48 | CompletableFuture thenApplyAsync(Function fn) 49 | CompletableFuture thenApplyAsync(Function fn, Executor executor) 50 | ``` 51 | 52 | ## flatMap 53 | 54 | ```java 55 | CompletableFuture thenCompose(Function> fn) 56 | CompletableFuture thenComposeAsync(Function> fn) 57 | CompletableFuture thenComposeAsync(Function> fn, Executor executor) 58 | ``` 59 | 60 | ## 消耗型 61 | 62 | ```java 63 | CompletableFuture thenAccept(Consumer action) 64 | CompletableFuture thenAcceptAsync(Consumer action) 65 | CompletableFuture thenAcceptAsync(Consumer action, Executor executor) 66 | ``` 67 | 68 | `thenAccept(Consumer action)` 这个方法的命名采用了类似 Promise 的命名风格。 69 | 如果把这个方法命名为 addListener 会更容易理解,但是命名为 addListener 不能体现出 thenAccept 能返回 CompletableFuture 从而形成链式调用的特点。 70 | 71 | 当两个 `CompletionStage` 都正常完成计算的时候,执行一个 `Runnable` 72 | 73 | ```java 74 | CompletableFuture thenAcceptBoth(CompletionStage other, BiConsumer action) 75 | CompletableFuture thenAcceptBothAsync(CompletionStage other, BiConsumer action) 76 | CompletableFuture thenAcceptBothAsync(CompletionStage other, BiConsumer action, Executor executor) 77 | CompletableFuture runAfterBoth(CompletionStage other, Runnable action) 78 | ``` 79 | 80 | 对上一步的计算结果不关心,执行下一个操作 81 | 82 | ```java 83 | CompletableFuture thenRun(Runnable action) 84 | CompletableFuture thenRunAsync(Runnable action) 85 | CompletableFuture thenRunAsync(Runnable action, Executor executor) 86 | ``` 87 | 88 | ## 组合 89 | 90 | ```java 91 | CompletableFuture thenCombine(CompletionStage other, BiFunction fn) 92 | CompletableFuture thenCombineAsync(CompletionStage other, BiFunction fn) 93 | CompletableFuture thenCombineAsync(CompletionStage other, BiFunction fn, Executor executor) 94 | ``` 95 | 96 | ## Either 97 | 98 | ```java 99 | CompletableFuture acceptEither(CompletionStage other, Consumer action) 100 | CompletableFuture acceptEitherAsync(CompletionStage other, Consumer action) 101 | CompletableFuture acceptEitherAsync(CompletionStage other, Consumer action, Executor executor) 102 | CompletableFuture applyToEither(CompletionStage other, Function fn) 103 | CompletableFuture applyToEitherAsync(CompletionStage other, Function fn) 104 | CompletableFuture applyToEitherAsync(CompletionStage other, Function fn, Executor executor) 105 | ``` 106 | 107 | ## allOf、anyOf 108 | 109 | ```java 110 | static CompletableFuture allOf(CompletableFuture... cfs) 111 | static CompletableFuture anyOf(CompletableFuture... cfs) 112 | ``` 113 | 114 | [CompletableFuture 的 20 个例子](https://zhuanlan.zhihu.com/p/34921166) 115 | -------------------------------------------------------------------------------- /java8-completablefuture/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-completablefuture 13 | 14 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | 5 | /** 6 | * 创建 CompletableFuture 7 | * 8 | * @author biezhi 9 | * @date 2018/3/25 10 | */ 11 | public class CompletableFuture1 { 12 | 13 | public static void main(String[] args) { 14 | CompletableFuture helloFuture = CompletableFuture.runAsync(() -> System.out.println("hello future")); 15 | 16 | CompletableFuture integerCompletableFuture = CompletableFuture.supplyAsync(() -> 2333); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture10.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * @author biezhi 9 | * @date 2018/3/25 10 | */ 11 | public class CompletableFuture10 { 12 | 13 | private static CompletableFuture m1(){ 14 | return CompletableFuture.supplyAsync(() -> { 15 | try { 16 | TimeUnit.SECONDS.sleep(1); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | return 2333; 21 | }); 22 | } 23 | private static CompletableFuture m2(){ 24 | return CompletableFuture.supplyAsync(() -> { 25 | try { 26 | TimeUnit.SECONDS.sleep(2); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | return 8877; 31 | }); 32 | } 33 | 34 | public static void main(String[] args) throws ExecutionException, InterruptedException { 35 | long start = System.currentTimeMillis(); 36 | CompletableFuture.anyOf(m1(), m2()) 37 | .thenRun(() -> { 38 | System.out.println(System.currentTimeMillis() - start); 39 | }).get() 40 | ; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * 处理计算结果 9 | * 10 | * @author biezhi 11 | * @date 2018/3/25 12 | */ 13 | public class CompletableFuture2 { 14 | 15 | public static void main(String[] args) { 16 | CompletableFuture uCompletableFuture = CompletableFuture.supplyAsync(() -> { 17 | System.out.println("开始执行运算"); 18 | try { 19 | TimeUnit.SECONDS.sleep(3); 20 | } catch (InterruptedException e) { 21 | e.printStackTrace(); 22 | } 23 | int a = 1/0; 24 | System.out.println("执行结束"); 25 | return 2333; 26 | }); 27 | 28 | try { 29 | Integer result = uCompletableFuture.whenComplete((a, b) -> { 30 | System.out.println("Result: " + a); 31 | System.out.println("Exception: " + b); 32 | }).exceptionally(e -> { 33 | System.out.println(e.getMessage()); 34 | return 666; 35 | }).get(); 36 | System.out.println(result); 37 | } catch (InterruptedException e) { 38 | e.printStackTrace(); 39 | } catch (ExecutionException e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture3.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.TimeUnit; 6 | import java.util.function.BiFunction; 7 | 8 | /** 9 | * 结果转换 10 | * 11 | * @author biezhi 12 | * @date 2018/3/25 13 | */ 14 | public class CompletableFuture3 { 15 | 16 | public static void main(String[] args) { 17 | try { 18 | String result = CompletableFuture.supplyAsync(() -> 2333) 19 | .thenApply(String::valueOf).get(); 20 | System.out.println(result); 21 | } catch (InterruptedException | ExecutionException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture4.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | 6 | /** 7 | * 扁平转换 8 | * 9 | * @author biezhi 10 | * @date 2018/3/25 11 | */ 12 | public class CompletableFuture4 { 13 | 14 | public static void main(String[] args) { 15 | try { 16 | String s = CompletableFuture.supplyAsync(() -> 23333) 17 | .thenCompose(t -> CompletableFuture.supplyAsync(() -> t + "ddd")) 18 | .get(); 19 | System.out.println(s); 20 | } catch (InterruptedException | ExecutionException e) { 21 | e.printStackTrace(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture5.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | 6 | /** 7 | * 消费结果 8 | * 9 | * @author biezhi 10 | * @date 2018/3/25 11 | */ 12 | public class CompletableFuture5 { 13 | 14 | public static void main(String[] args) throws ExecutionException, InterruptedException { 15 | CompletableFuture.supplyAsync(() -> 9999) 16 | .thenAccept(System.out::println).get(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture6.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2018/3/25 9 | */ 10 | public class CompletableFuture6 { 11 | 12 | public static void main(String[] args) throws ExecutionException, InterruptedException { 13 | CompletableFuture.supplyAsync(() -> 9999) 14 | .thenAcceptBoth(CompletableFuture.supplyAsync(() -> "7878"), (a, b) -> { 15 | System.out.println("a = " + a); 16 | System.out.println("b = " + b); 17 | }).get(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture7.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * @author biezhi 9 | * @date 2018/3/25 10 | */ 11 | public class CompletableFuture7 { 12 | 13 | public static void main(String[] args) throws ExecutionException, InterruptedException { 14 | CompletableFuture.supplyAsync(() -> { 15 | try { 16 | System.out.println("开始执行了"); 17 | TimeUnit.SECONDS.sleep(3); 18 | } catch (InterruptedException e) { 19 | e.printStackTrace(); 20 | } 21 | return 9999; 22 | }).thenRun(() -> { 23 | System.out.println("执行结束了"); 24 | }).get(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture8.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2018/3/25 9 | */ 10 | public class CompletableFuture8 { 11 | 12 | public static void main(String[] args) { 13 | try { 14 | String s = CompletableFuture.supplyAsync(() -> 23333) 15 | .thenCombine(CompletableFuture.supplyAsync( () -> "8898" ), (a, b) -> { 16 | System.out.println("a =" + a); 17 | System.out.println("b =" + b); 18 | return a + b; 19 | }) 20 | .get(); 21 | System.out.println(s); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } catch (ExecutionException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/CompletableFuture9.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * @author biezhi 9 | * @date 2018/3/25 10 | */ 11 | public class CompletableFuture9 { 12 | 13 | private static CompletableFuture m1(){ 14 | return CompletableFuture.supplyAsync(() -> { 15 | try { 16 | TimeUnit.SECONDS.sleep(1); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | return 2333; 21 | }); 22 | } 23 | private static CompletableFuture m2(){ 24 | return CompletableFuture.supplyAsync(() -> { 25 | try { 26 | TimeUnit.SECONDS.sleep(2); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | return 8877; 31 | }); 32 | } 33 | 34 | public static void main(String[] args) throws ExecutionException, InterruptedException { 35 | m1().acceptEither(m2(), t -> { 36 | System.out.println("t = " + t); 37 | }).get(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /java8-completablefuture/src/main/java/io/github/biezhi/java8/completablefuture/Future1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.completablefuture; 2 | 3 | import java.util.concurrent.*; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2018/3/25 8 | */ 9 | public class Future1 { 10 | 11 | public static void main(String[] args) throws ExecutionException, InterruptedException { 12 | ExecutorService executorService = Executors.newFixedThreadPool(2); 13 | 14 | Future submit = executorService.submit(() -> { 15 | TimeUnit.SECONDS.sleep(3); 16 | return 100; 17 | }); 18 | 19 | // try { 20 | // Integer result = submit.get(); 21 | // System.out.println(result); 22 | // } catch (InterruptedException e) { 23 | // e.printStackTrace(); 24 | // } catch (ExecutionException e) { 25 | // e.printStackTrace(); 26 | // } 27 | 28 | while(!submit.isDone()){ 29 | try { 30 | TimeUnit.MILLISECONDS.sleep(100); 31 | } catch (InterruptedException e) { 32 | e.printStackTrace(); 33 | } 34 | } 35 | Integer result = submit.get(); 36 | System.out.println(result); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /java8-concurrent/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-concurrent 13 | 14 | -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Atomic1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | import java.util.stream.IntStream; 7 | 8 | /** 9 | * 原子变量 10 | *

11 | * AtomicInteger 12 | * LongAdder 13 | * LongAccumulator 14 | * 15 | * @author biezhi 16 | * @date 2018/3/5 17 | */ 18 | public class Atomic1 { 19 | 20 | private static final int NUM_INCREMENTS = 1000; 21 | 22 | private static AtomicInteger atomicInt = new AtomicInteger(0); 23 | 24 | public static void main(String[] args) { 25 | testIncrement(); 26 | // testAccumulate(); 27 | // testUpdate(); 28 | } 29 | 30 | private static void testUpdate() { 31 | atomicInt.set(0); 32 | 33 | ExecutorService executor = Executors.newFixedThreadPool(2); 34 | 35 | IntStream.range(0, NUM_INCREMENTS) 36 | .forEach(i -> { 37 | Runnable task = () -> 38 | atomicInt.updateAndGet(n -> n + 2); 39 | executor.submit(task); 40 | }); 41 | 42 | ConcurrentUtils.stop(executor); 43 | 44 | System.out.format("Update: %d\n", atomicInt.get()); 45 | } 46 | 47 | private static void testAccumulate() { 48 | atomicInt.set(0); 49 | 50 | ExecutorService executor = Executors.newFixedThreadPool(2); 51 | 52 | IntStream.range(0, NUM_INCREMENTS) 53 | .forEach(i -> { 54 | Runnable task = () -> 55 | atomicInt.accumulateAndGet(i, (n, m) -> n + m); 56 | executor.submit(task); 57 | }); 58 | 59 | ConcurrentUtils.stop(executor); 60 | 61 | System.out.format("Accumulate: %d\n", atomicInt.get()); 62 | } 63 | 64 | private static void testIncrement() { 65 | atomicInt.set(0); 66 | 67 | ExecutorService executor = Executors.newFixedThreadPool(2); 68 | 69 | IntStream.range(0, NUM_INCREMENTS) 70 | .forEach(i -> executor.submit(atomicInt::incrementAndGet)); 71 | 72 | ConcurrentUtils.stop(executor); 73 | 74 | System.out.format("Increment: Expected=%d; Is=%d\n", NUM_INCREMENTS, atomicInt.get()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/ConcurrentHashMap1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | import java.util.concurrent.ForkJoinPool; 5 | 6 | public class ConcurrentHashMap1 { 7 | 8 | public static void main(String[] args) { 9 | System.out.println("Parallelism: " + ForkJoinPool.getCommonPoolParallelism()); 10 | 11 | testForEach(); 12 | // testSearch(); 13 | // testReduce(); 14 | } 15 | 16 | private static void testReduce() { 17 | ConcurrentHashMap map = new ConcurrentHashMap<>(); 18 | map.putIfAbsent("foo", "bar"); 19 | map.putIfAbsent("han", "solo"); 20 | map.putIfAbsent("r2", "d2"); 21 | map.putIfAbsent("c3", "p0"); 22 | 23 | String reduced = map.reduce(1, (key, value) -> key + "=" + value, 24 | (s1, s2) -> s1 + ", " + s2); 25 | 26 | System.out.println(reduced); 27 | } 28 | 29 | private static void testSearch() { 30 | ConcurrentHashMap map = new ConcurrentHashMap<>(); 31 | map.putIfAbsent("foo", "bar"); 32 | map.putIfAbsent("han", "solo"); 33 | map.putIfAbsent("r2", "d2"); 34 | map.putIfAbsent("c3", "p0"); 35 | 36 | System.out.println("\nsearch()\n"); 37 | 38 | String result1 = map.search(1, (key, value) -> { 39 | System.out.println(Thread.currentThread().getName()); 40 | if (key.equals("foo") && value.equals("bar")) { 41 | return "foobar"; 42 | } 43 | return null; 44 | }); 45 | 46 | System.out.println(result1); 47 | 48 | System.out.println("\nsearchValues()\n"); 49 | 50 | String result2 = map.searchValues(1, value -> { 51 | System.out.println(Thread.currentThread().getName()); 52 | if (value.length() > 3) { 53 | return value; 54 | } 55 | return null; 56 | }); 57 | 58 | System.out.println(result2); 59 | } 60 | 61 | private static void testForEach() { 62 | ConcurrentHashMap map = new ConcurrentHashMap<>(); 63 | map.putIfAbsent("foo", "bar"); 64 | map.putIfAbsent("han", "solo"); 65 | map.putIfAbsent("r2", "d2"); 66 | map.putIfAbsent("c3", "p0"); 67 | 68 | map.forEach(1, (key, value) -> System.out.printf("key: %s; value: %s; thread: %s\n", key, value, Thread.currentThread().getName())); 69 | // map.forEach(5, (key, value) -> System.out.printf("key: %s; value: %s; thread: %s\n", key, value, Thread.currentThread().getName())); 70 | 71 | System.out.println(map.mappingCount()); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/ConcurrentUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 并发工具类 8 | * 9 | * @author biezhi 10 | * @date 2018/3/11 11 | */ 12 | public class ConcurrentUtils { 13 | 14 | public static void stop(ExecutorService executor) { 15 | try { 16 | executor.shutdown(); 17 | executor.awaitTermination(60, TimeUnit.SECONDS); 18 | } 19 | catch (InterruptedException e) { 20 | System.err.println("termination interrupted"); 21 | } 22 | finally { 23 | if (!executor.isTerminated()) { 24 | System.err.println("killing non-finished tasks"); 25 | } 26 | executor.shutdownNow(); 27 | } 28 | } 29 | 30 | public static void sleep(int seconds) { 31 | try { 32 | TimeUnit.SECONDS.sleep(seconds); 33 | } catch (InterruptedException e) { 34 | throw new IllegalStateException(e); 35 | } 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Executors1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class Executors1 { 8 | 9 | public static void main(String[] args) { 10 | test1(3); 11 | // test1(7); 12 | } 13 | 14 | private static void test1(long seconds) { 15 | ExecutorService executor = Executors.newSingleThreadExecutor(); 16 | executor.submit(() -> { 17 | try { 18 | TimeUnit.SECONDS.sleep(seconds); 19 | String name = Thread.currentThread().getName(); 20 | System.out.println("task finished: " + name); 21 | } catch (InterruptedException e) { 22 | System.err.println("task interrupted"); 23 | } 24 | }); 25 | stop(executor); 26 | } 27 | 28 | static void stop(ExecutorService executor) { 29 | try { 30 | System.out.println("attempt to shutdown executor"); 31 | executor.shutdown(); 32 | executor.awaitTermination(5, TimeUnit.SECONDS); 33 | } catch (InterruptedException e) { 34 | System.err.println("termination interrupted"); 35 | } finally { 36 | if (!executor.isTerminated()) { 37 | System.err.println("killing non-finished tasks"); 38 | } 39 | executor.shutdownNow(); 40 | System.out.println("shutdown finished"); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Executors2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.*; 4 | 5 | public class Executors2 { 6 | 7 | public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException { 8 | test1(); 9 | // test2(); 10 | // test3(); 11 | } 12 | 13 | private static void test3() throws InterruptedException, ExecutionException, TimeoutException { 14 | ExecutorService executor = Executors.newFixedThreadPool(1); 15 | 16 | Future future = executor.submit(() -> { 17 | try { 18 | TimeUnit.SECONDS.sleep(2); 19 | return 123; 20 | } catch (InterruptedException e) { 21 | throw new IllegalStateException("task interrupted", e); 22 | } 23 | }); 24 | 25 | future.get(1, TimeUnit.SECONDS); 26 | } 27 | 28 | private static void test2() throws InterruptedException, ExecutionException { 29 | ExecutorService executor = Executors.newFixedThreadPool(1); 30 | 31 | Future future = executor.submit(() -> { 32 | try { 33 | TimeUnit.SECONDS.sleep(1); 34 | return 123; 35 | } catch (InterruptedException e) { 36 | throw new IllegalStateException("task interrupted", e); 37 | } 38 | }); 39 | 40 | executor.shutdownNow(); 41 | future.get(); 42 | } 43 | 44 | private static void test1() throws InterruptedException, ExecutionException { 45 | ExecutorService executor = Executors.newFixedThreadPool(1); 46 | 47 | Future future = executor.submit(() -> { 48 | try { 49 | TimeUnit.SECONDS.sleep(1); 50 | return 123; 51 | } catch (InterruptedException e) { 52 | throw new IllegalStateException("task interrupted", e); 53 | } 54 | }); 55 | 56 | System.out.println("future done: " + future.isDone()); 57 | 58 | Integer result = future.get(); 59 | 60 | System.out.println("future done: " + future.isDone()); 61 | System.out.print("result: " + result); 62 | 63 | executor.shutdownNow(); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Executors3.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.concurrent.*; 6 | 7 | public class Executors3 { 8 | 9 | public static void main(String[] args) throws InterruptedException, ExecutionException { 10 | test1(); 11 | // test2(); 12 | // test3(); 13 | 14 | // test4(); 15 | // test5(); 16 | } 17 | 18 | private static void test5() throws InterruptedException, ExecutionException { 19 | ExecutorService executor = Executors.newWorkStealingPool(); 20 | 21 | List> callables = Arrays.asList( 22 | callable("task1", 2), 23 | callable("task2", 1), 24 | callable("task3", 3)); 25 | 26 | String result = executor.invokeAny(callables); 27 | System.out.println(result); 28 | 29 | executor.shutdown(); 30 | } 31 | 32 | private static Callable callable(String result, long sleepSeconds) { 33 | return () -> { 34 | TimeUnit.SECONDS.sleep(sleepSeconds); 35 | return result; 36 | }; 37 | } 38 | 39 | private static void test4() throws InterruptedException { 40 | ExecutorService executor = Executors.newWorkStealingPool(); 41 | 42 | List> callables = Arrays.asList( 43 | () -> "task1", 44 | () -> "task2", 45 | () -> "task3"); 46 | 47 | executor.invokeAll(callables) 48 | .stream() 49 | .map(future -> { 50 | try { 51 | return future.get(); 52 | } catch (Exception e) { 53 | throw new IllegalStateException(e); 54 | } 55 | }) 56 | .forEach(System.out::println); 57 | 58 | executor.shutdown(); 59 | } 60 | 61 | private static void test3() { 62 | ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 63 | 64 | Runnable task = () -> { 65 | try { 66 | TimeUnit.SECONDS.sleep(2); 67 | System.out.println("Scheduling: " + System.nanoTime()); 68 | } catch (InterruptedException e) { 69 | System.err.println("task interrupted"); 70 | } 71 | }; 72 | 73 | executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS); 74 | } 75 | 76 | private static void test2() { 77 | ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 78 | Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime()); 79 | int initialDelay = 0; 80 | int period = 1; 81 | executor.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS); 82 | } 83 | 84 | private static void test1() throws InterruptedException { 85 | ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 86 | 87 | Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime()); 88 | int delay = 3; 89 | ScheduledFuture future = executor.schedule(task, delay, TimeUnit.SECONDS); 90 | 91 | TimeUnit.MILLISECONDS.sleep(1337); 92 | 93 | long remainingDelay = future.getDelay(TimeUnit.MILLISECONDS); 94 | System.out.printf("Remaining Delay: %sms\n", remainingDelay); 95 | } 96 | 97 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | import java.util.stream.IntStream; 7 | 8 | public class Lock1 { 9 | 10 | private static final int NUM_INCREMENTS = 10000; 11 | 12 | private static ReentrantLock lock = new ReentrantLock(); 13 | 14 | private static int count = 0; 15 | 16 | private static void increment() { 17 | lock.lock(); 18 | try { 19 | count++; 20 | } finally { 21 | lock.unlock(); 22 | } 23 | } 24 | 25 | public static void main(String[] args) { 26 | testLock(); 27 | } 28 | 29 | private static void testLock() { 30 | count = 0; 31 | 32 | ExecutorService executor = Executors.newFixedThreadPool(2); 33 | 34 | IntStream.range(0, NUM_INCREMENTS) 35 | .forEach(i -> executor.submit(Lock1::increment)); 36 | 37 | ConcurrentUtils.stop(executor); 38 | 39 | System.out.println(count); 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | public class Lock2 { 8 | 9 | public static void main(String[] args) { 10 | ExecutorService executor = Executors.newFixedThreadPool(2); 11 | 12 | ReentrantLock lock = new ReentrantLock(); 13 | 14 | executor.submit(() -> { 15 | lock.lock(); 16 | try { 17 | ConcurrentUtils.sleep(1); 18 | } finally { 19 | lock.unlock(); 20 | } 21 | }); 22 | 23 | executor.submit(() -> { 24 | System.out.println("Locked: " + lock.isLocked()); 25 | System.out.println("Held by me: " + lock.isHeldByCurrentThread()); 26 | boolean locked = lock.tryLock(); 27 | System.out.println("Lock acquired: " + locked); 28 | }); 29 | 30 | ConcurrentUtils.stop(executor); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock3.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.concurrent.ExecutorService; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.locks.ReadWriteLock; 8 | import java.util.concurrent.locks.ReentrantReadWriteLock; 9 | 10 | public class Lock3 { 11 | 12 | public static void main(String[] args) { 13 | ExecutorService executor = Executors.newFixedThreadPool(2); 14 | 15 | Map map = new HashMap<>(); 16 | 17 | ReadWriteLock lock = new ReentrantReadWriteLock(); 18 | 19 | executor.submit(() -> { 20 | lock.writeLock().lock(); 21 | try { 22 | ConcurrentUtils.sleep(1); 23 | map.put("foo", "bar"); 24 | } finally { 25 | lock.writeLock().unlock(); 26 | } 27 | }); 28 | 29 | Runnable readTask = () -> { 30 | lock.readLock().lock(); 31 | try { 32 | System.out.println(map.get("foo")); 33 | ConcurrentUtils.sleep(1); 34 | } finally { 35 | lock.readLock().unlock(); 36 | } 37 | }; 38 | executor.submit(readTask); 39 | executor.submit(readTask); 40 | 41 | ConcurrentUtils.stop(executor); 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock4.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.concurrent.ExecutorService; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.locks.StampedLock; 8 | 9 | public class Lock4 { 10 | 11 | public static void main(String[] args) { 12 | ExecutorService executor = Executors.newFixedThreadPool(2); 13 | 14 | Map map = new HashMap<>(); 15 | 16 | StampedLock lock = new StampedLock(); 17 | 18 | executor.submit(() -> { 19 | long stamp = lock.writeLock(); 20 | try { 21 | ConcurrentUtils.sleep(1); 22 | map.put("foo", "bar"); 23 | } finally { 24 | lock.unlockWrite(stamp); 25 | } 26 | }); 27 | 28 | Runnable readTask = () -> { 29 | long stamp = lock.readLock(); 30 | try { 31 | System.out.println(map.get("foo")); 32 | ConcurrentUtils.sleep(1); 33 | } finally { 34 | lock.unlockRead(stamp); 35 | } 36 | }; 37 | executor.submit(readTask); 38 | executor.submit(readTask); 39 | 40 | ConcurrentUtils.stop(executor); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock5.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.locks.StampedLock; 6 | 7 | public class Lock5 { 8 | 9 | public static void main(String[] args) { 10 | ExecutorService executor = Executors.newFixedThreadPool(2); 11 | 12 | StampedLock lock = new StampedLock(); 13 | 14 | executor.submit(() -> { 15 | long stamp = lock.tryOptimisticRead(); 16 | try { 17 | System.out.println("Optimistic Lock Valid: " + lock.validate(stamp)); 18 | ConcurrentUtils.sleep(1); 19 | System.out.println("Optimistic Lock Valid: " + lock.validate(stamp)); 20 | ConcurrentUtils.sleep(2); 21 | System.out.println("Optimistic Lock Valid: " + lock.validate(stamp)); 22 | } finally { 23 | lock.unlock(stamp); 24 | } 25 | }); 26 | 27 | executor.submit(() -> { 28 | long stamp = lock.writeLock(); 29 | try { 30 | System.out.println("Write Lock acquired"); 31 | ConcurrentUtils.sleep(2); 32 | } finally { 33 | lock.unlock(stamp); 34 | System.out.println("Write done"); 35 | } 36 | }); 37 | 38 | ConcurrentUtils.stop(executor); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock6.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.locks.StampedLock; 6 | 7 | public class Lock6 { 8 | 9 | private static int count = 0; 10 | 11 | public static void main(String[] args) { 12 | ExecutorService executor = Executors.newFixedThreadPool(2); 13 | 14 | StampedLock lock = new StampedLock(); 15 | 16 | executor.submit(() -> { 17 | long stamp = lock.readLock(); 18 | try { 19 | if (count == 0) { 20 | stamp = lock.tryConvertToWriteLock(stamp); 21 | if (stamp == 0L) { 22 | System.out.println("Could not convert to write lock"); 23 | stamp = lock.writeLock(); 24 | } 25 | count = 23; 26 | } 27 | System.out.println(count); 28 | } finally { 29 | lock.unlock(stamp); 30 | } 31 | }); 32 | 33 | ConcurrentUtils.stop(executor); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/LongAccumulator1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.atomic.LongAccumulator; 6 | import java.util.function.LongBinaryOperator; 7 | import java.util.stream.IntStream; 8 | 9 | public class LongAccumulator1 { 10 | 11 | public static void main(String[] args) { 12 | testAccumulate(); 13 | } 14 | 15 | private static void testAccumulate() { 16 | LongBinaryOperator op = (x, y) -> 2 * x + y; 17 | LongAccumulator accumulator = new LongAccumulator(op, 1L); 18 | 19 | ExecutorService executor = Executors.newFixedThreadPool(2); 20 | 21 | IntStream.range(0, 10) 22 | .forEach(i -> executor.submit(() -> accumulator.accumulate(i))); 23 | 24 | ConcurrentUtils.stop(executor); 25 | 26 | System.out.format("Add: %d\n", accumulator.getThenReset()); 27 | } 28 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/LongAdder1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.atomic.LongAdder; 6 | import java.util.stream.IntStream; 7 | 8 | public class LongAdder1 { 9 | 10 | private static final int NUM_INCREMENTS = 10000; 11 | 12 | private static LongAdder adder = new LongAdder(); 13 | 14 | public static void main(String[] args) { 15 | testIncrement(); 16 | testAdd(); 17 | } 18 | 19 | private static void testAdd() { 20 | ExecutorService executor = Executors.newFixedThreadPool(2); 21 | 22 | IntStream.range(0, NUM_INCREMENTS) 23 | .forEach(i -> executor.submit(() -> adder.add(2))); 24 | 25 | ConcurrentUtils.stop(executor); 26 | 27 | System.out.format("Add: %d\n", adder.sumThenReset()); 28 | } 29 | 30 | private static void testIncrement() { 31 | ExecutorService executor = Executors.newFixedThreadPool(2); 32 | 33 | IntStream.range(0, NUM_INCREMENTS) 34 | .forEach(i -> executor.submit(adder::increment)); 35 | 36 | ConcurrentUtils.stop(executor); 37 | 38 | System.out.format("Increment: Expected=%d; Is=%d\n", NUM_INCREMENTS, adder.sumThenReset()); 39 | } 40 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Semaphore1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.Semaphore; 6 | import java.util.concurrent.TimeUnit; 7 | import java.util.stream.IntStream; 8 | 9 | public class Semaphore1 { 10 | 11 | private static final int NUM_INCREMENTS = 10000; 12 | 13 | private static Semaphore semaphore = new Semaphore(1); 14 | 15 | private static int count = 0; 16 | 17 | public static void main(String[] args) { 18 | testIncrement(); 19 | } 20 | 21 | private static void testIncrement() { 22 | ExecutorService executor = Executors.newFixedThreadPool(2); 23 | 24 | IntStream.range(0, NUM_INCREMENTS) 25 | .forEach(i -> executor.submit(Semaphore1::increment)); 26 | 27 | ConcurrentUtils.stop(executor); 28 | 29 | System.out.println("Increment: " + count); 30 | } 31 | 32 | private static void increment() { 33 | boolean permit = false; 34 | try { 35 | permit = semaphore.tryAcquire(5, TimeUnit.SECONDS); 36 | count++; 37 | } catch (InterruptedException e) { 38 | throw new RuntimeException("could not increment"); 39 | } finally { 40 | if (permit) { 41 | semaphore.release(); 42 | } 43 | } 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Semaphore2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.Semaphore; 6 | import java.util.concurrent.TimeUnit; 7 | import java.util.stream.IntStream; 8 | 9 | public class Semaphore2 { 10 | 11 | private static Semaphore semaphore = new Semaphore(5); 12 | 13 | public static void main(String[] args) { 14 | ExecutorService executor = Executors.newFixedThreadPool(10); 15 | 16 | IntStream.range(0, 10) 17 | .forEach(i -> executor.submit(Semaphore2::doWork)); 18 | 19 | ConcurrentUtils.stop(executor); 20 | } 21 | 22 | private static void doWork() { 23 | boolean permit = false; 24 | try { 25 | permit = semaphore.tryAcquire(1, TimeUnit.SECONDS); 26 | if (permit) { 27 | System.out.println("Semaphore acquired"); 28 | ConcurrentUtils.sleep(5); 29 | } else { 30 | System.out.println("Could not acquire semaphore"); 31 | } 32 | } catch (InterruptedException e) { 33 | throw new IllegalStateException(e); 34 | } finally { 35 | if (permit) { 36 | semaphore.release(); 37 | } 38 | } 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Synchronized1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.stream.IntStream; 6 | 7 | public class Synchronized1 { 8 | 9 | private static final int NUM_INCREMENTS = 10000; 10 | 11 | private static int count = 0; 12 | 13 | public static void main(String[] args) { 14 | testSyncIncrement(); 15 | testNonSyncIncrement(); 16 | } 17 | 18 | private static void testSyncIncrement() { 19 | count = 0; 20 | 21 | ExecutorService executor = Executors.newFixedThreadPool(2); 22 | 23 | IntStream.range(0, NUM_INCREMENTS) 24 | .forEach(i -> executor.submit(Synchronized1::incrementSync)); 25 | 26 | ConcurrentUtils.stop(executor); 27 | 28 | System.out.println(" Sync: " + count); 29 | } 30 | 31 | private static void testNonSyncIncrement() { 32 | count = 0; 33 | 34 | ExecutorService executor = Executors.newFixedThreadPool(2); 35 | 36 | IntStream.range(0, NUM_INCREMENTS) 37 | .forEach(i -> executor.submit(Synchronized1::increment)); 38 | 39 | ConcurrentUtils.stop(executor); 40 | 41 | System.out.println("NonSync: " + count); 42 | } 43 | 44 | private static synchronized void incrementSync() { 45 | count = count + 1; 46 | } 47 | 48 | private static void increment() { 49 | count = count + 1; 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Synchronized2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.stream.IntStream; 6 | 7 | public class Synchronized2 { 8 | 9 | private static final int NUM_INCREMENTS = 10000; 10 | 11 | private static int count = 0; 12 | 13 | public static void main(String[] args) { 14 | testSyncIncrement(); 15 | } 16 | 17 | private static void testSyncIncrement() { 18 | count = 0; 19 | 20 | ExecutorService executor = Executors.newFixedThreadPool(2); 21 | 22 | IntStream.range(0, NUM_INCREMENTS) 23 | .forEach(i -> executor.submit(Synchronized2::incrementSync)); 24 | 25 | ConcurrentUtils.stop(executor); 26 | 27 | System.out.println(count); 28 | } 29 | 30 | private static void incrementSync() { 31 | synchronized (Synchronized2.class) { 32 | count = count + 1; 33 | } 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Threads1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.concurrent; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class Threads1 { 6 | 7 | public static void main(String[] args) { 8 | test1(); 9 | // test2(); 10 | // test3(); 11 | } 12 | 13 | private static void test3() { 14 | Runnable runnable = () -> { 15 | try { 16 | System.out.println("Foo " + Thread.currentThread().getName()); 17 | TimeUnit.SECONDS.sleep(1); 18 | System.out.println("Bar " + Thread.currentThread().getName()); 19 | } 20 | catch (InterruptedException e) { 21 | e.printStackTrace(); 22 | } 23 | }; 24 | 25 | Thread thread = new Thread(runnable); 26 | thread.start(); 27 | } 28 | 29 | private static void test2() { 30 | Runnable runnable = () -> { 31 | try { 32 | System.out.println("Foo " + Thread.currentThread().getName()); 33 | Thread.sleep(1000); 34 | System.out.println("Bar " + Thread.currentThread().getName()); 35 | } 36 | catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | }; 40 | 41 | Thread thread = new Thread(runnable); 42 | thread.start(); 43 | } 44 | 45 | private static void test1() { 46 | Runnable runnable = () -> { 47 | String threadName = Thread.currentThread().getName(); 48 | System.out.println("Hello " + threadName); 49 | }; 50 | 51 | runnable.run(); 52 | 53 | Thread thread = new Thread(runnable); 54 | thread.start(); 55 | 56 | System.out.println("Done!"); 57 | } 58 | } -------------------------------------------------------------------------------- /java8-datetime-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-datetime-api 13 | 14 | 15 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/ClockExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.Clock; 4 | import java.time.Instant; 5 | import java.util.Date; 6 | 7 | /** 8 | * Clock 示例 9 | * 10 | * @author biezhi 11 | * @date 2018/3/3 12 | */ 13 | public class ClockExample { 14 | 15 | public static void main(String[] args) { 16 | Clock clock = Clock.systemDefaultZone(); 17 | long millis = clock.millis(); 18 | Instant instant = clock.instant(); 19 | Date legacyDate = Date.from(instant); // legacy java.util.Date 20 | System.out.println(millis); 21 | System.out.println(legacyDate); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/ConvertExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.*; 4 | import java.util.Date; 5 | 6 | /** 7 | * 日期转换示例 8 | * 9 | * @author biezhi 10 | * @date 2018/3/3 11 | */ 12 | public class ConvertExample { 13 | 14 | /** 15 | * LocalDate -> Date 16 | * 17 | * @param localDate 18 | * @return 19 | */ 20 | public static Date toDate(LocalDate localDate) { 21 | ZoneId zone = ZoneId.systemDefault(); 22 | Instant instant = localDate.atStartOfDay().atZone(zone).toInstant(); 23 | return Date.from(instant); 24 | } 25 | 26 | /** 27 | * LocalDateTime -> Date 28 | * 29 | * @param localDateTime 30 | * @return 31 | */ 32 | public static Date toDate(LocalDateTime localDateTime) { 33 | ZoneId zone = ZoneId.systemDefault(); 34 | Instant instant = localDateTime.atZone(zone).toInstant(); 35 | return Date.from(instant); 36 | } 37 | 38 | /** 39 | * LocalTime -> Date 40 | * 41 | * @param localTime 42 | * @return 43 | */ 44 | public static Date toDate(LocalTime localTime) { 45 | LocalDate localDate = LocalDate.now(); 46 | LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); 47 | ZoneId zone = ZoneId.systemDefault(); 48 | Instant instant = localDateTime.atZone(zone).toInstant(); 49 | return Date.from(instant); 50 | } 51 | 52 | /** 53 | * Date -> LocalDate 54 | * 55 | * @param date 56 | * @return 57 | */ 58 | public static LocalDate toLocalDate(Date date) { 59 | Instant instant = date.toInstant(); 60 | ZoneId zone = ZoneId.systemDefault(); 61 | LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); 62 | return localDateTime.toLocalDate(); 63 | } 64 | 65 | /** 66 | * Date -> LocalDateTime 67 | * 68 | * @param date 69 | * @return 70 | */ 71 | public static LocalDateTime toLocalDateTime(Date date) { 72 | Instant instant = date.toInstant(); 73 | ZoneId zone = ZoneId.systemDefault(); 74 | return LocalDateTime.ofInstant(instant, zone); 75 | } 76 | 77 | /** 78 | * Date -> LocalTime 79 | * 80 | * @param date 81 | * @return 82 | */ 83 | public static LocalTime toLocalTime(Date date) { 84 | Instant instant = date.toInstant(); 85 | ZoneId zone = ZoneId.systemDefault(); 86 | LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); 87 | return localDateTime.toLocalTime(); 88 | } 89 | 90 | 91 | } 92 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/DateTimeFormatExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.LocalDate; 4 | import java.time.LocalDateTime; 5 | import java.time.ZonedDateTime; 6 | import java.time.format.DateTimeFormatter; 7 | import java.util.Locale; 8 | 9 | /** 10 | * DateTimeFormatter 示例 11 | * 12 | * @author biezhi 13 | * @date 2018/3/2 14 | */ 15 | public class DateTimeFormatExample { 16 | 17 | public static void main(String[] args) { 18 | DateTimeFormatter formatter = DateTimeFormatter.BASIC_ISO_DATE; 19 | String formattedDate = formatter.format(LocalDate.now()); 20 | String formattedZonedDate = formatter.format(ZonedDateTime.now()); 21 | 22 | System.out.println("LocalDate : " + formattedDate); 23 | System.out.println("formattedZonedDate : " + formattedZonedDate); 24 | 25 | LocalDateTime dateTime = LocalDateTime.now(); 26 | String strDate1 = dateTime.format(DateTimeFormatter.BASIC_ISO_DATE); // 20180303 27 | String strDate2 = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE); // 2013-03-03 28 | String strDate3 = dateTime.format(DateTimeFormatter.ISO_LOCAL_TIME); // 当前时间 29 | String strDate4 = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 2018-03-03 30 | // 今天是:2018年 三月 03日 星期六 31 | String strDate5 = dateTime.format(DateTimeFormatter.ofPattern("今天是:YYYY年 MMMM dd日 E", Locale.CHINESE)); 32 | 33 | System.out.println(strDate1); 34 | System.out.println(strDate2); 35 | System.out.println(strDate3); 36 | System.out.println(strDate4); 37 | System.out.println(strDate5); 38 | 39 | // 将一个字符串解析成一个日期对象 40 | String strDate6 = "2018-03-03"; 41 | String strDate7 = "2017-03-03 15:30:05"; 42 | 43 | LocalDate date = LocalDate.parse(strDate6, DateTimeFormatter.ofPattern("yyyy-MM-dd")); 44 | LocalDateTime dateTime1 = LocalDateTime.parse(strDate7, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 45 | 46 | System.out.println(date); 47 | System.out.println(dateTime1); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/DurationExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.Duration; 4 | import java.time.Instant; 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * Duration 示例 9 | * 10 | * @author biezhi 11 | * @date 2018/3/3 12 | */ 13 | public class DurationExample { 14 | 15 | public static void main(String[] args) throws InterruptedException { 16 | 17 | // 创建Duration实例 18 | Instant first = Instant.now(); 19 | Thread.sleep(3000); 20 | Instant second = Instant.now(); 21 | Duration duration = Duration.between(first, second); 22 | 23 | // 访问Duration的时间 24 | long seconds = duration.getSeconds(); 25 | 26 | System.out.println("相差 : " + seconds + " 秒"); 27 | 28 | LocalDateTime from = LocalDateTime.now(); 29 | LocalDateTime to = from.plusDays(5); 30 | Duration duration2 = Duration.between(from, to); 31 | 32 | System.out.println("从 from 到 to 相差 : " + duration2.toDays() + " 天"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/InstantExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.Instant; 4 | 5 | /** 6 | * Instant 示例 7 | * 8 | * @author biezhi 9 | * @date 2018/3/2 10 | */ 11 | public class InstantExample { 12 | 13 | public static void main(String[] args) { 14 | 15 | // 创建一个Instant实例 16 | Instant now = Instant.now(); 17 | 18 | // 访问Instant的时间 19 | long seconds = now.getEpochSecond(); 20 | int nanos = now.getNano(); 21 | System.out.println("seconds : " + seconds); 22 | System.out.println("nanos : " + nanos); 23 | 24 | // 3秒后 25 | Instant later = now.plusSeconds(3); 26 | // 3秒前 27 | Instant earlier = now.minusSeconds(3); 28 | 29 | System.out.println("current : " + now.toString()); 30 | System.out.println("later : " + later); 31 | System.out.println("earlier : " + earlier); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/LocalDateExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.DayOfWeek; 4 | import java.time.LocalDate; 5 | import java.time.Month; 6 | 7 | /** 8 | * LocalDate 示例 9 | * 10 | * @author biezhi 11 | * @date 2018/3/2 12 | */ 13 | public class LocalDateExample { 14 | 15 | public static void main(String[] args) { 16 | 17 | // 创建一个LocalDate实例 18 | LocalDate localDate = LocalDate.now(); 19 | 20 | // 使用年月日信息构造出LocalDate对象 21 | LocalDate localDate2 = LocalDate.of(2018, 3, 3); 22 | 23 | int year = localDate.getYear(); 24 | Month month = localDate.getMonth(); 25 | int dayOfMonth = localDate.getDayOfMonth(); 26 | int dayOfYear = localDate.getDayOfYear(); 27 | DayOfWeek dayOfWeek = localDate.getDayOfWeek(); 28 | 29 | System.out.println("year : " + year); 30 | System.out.println("month : " + month.getValue()); 31 | System.out.println("dayOfMonth : " + dayOfMonth); 32 | System.out.println("dayOfYear : " + dayOfYear); 33 | System.out.println("dayOfWeek : " + dayOfWeek.getValue()); 34 | 35 | // 3年后 36 | LocalDate d1 = localDate2.plusYears(3); 37 | // 3年前 38 | LocalDate d2 = localDate2.minusYears(3); 39 | System.out.println("plusYears : " + d1); 40 | System.out.println("minusYears : " + d2); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/LocalDateTimeExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | /** 6 | * LocalDateTime 示例 7 | * 8 | * @author biezhi 9 | * @date 2018/3/2 10 | */ 11 | public class LocalDateTimeExample { 12 | 13 | public static void main(String[] args) { 14 | 15 | // 创建一个LocalDateTime实例 16 | LocalDateTime localDateTime = LocalDateTime.now(); 17 | 18 | // 使用指定的年月日、时分秒、纳秒来新建对象 19 | LocalDateTime localDateTime2 = LocalDateTime.of(2018, 11, 26, 13, 55, 36, 123); 20 | 21 | // 3年后的现在 22 | LocalDateTime dt1 = localDateTime.plusYears(3); 23 | // 3年前的现在 24 | LocalDateTime dt2 = localDateTime.minusYears(3); 25 | 26 | System.out.println("localDateTime : " + localDateTime); 27 | System.out.println("localDateTime2 : " + localDateTime2); 28 | System.out.println("dt1 : " + dt1); 29 | System.out.println("dt2 : " + dt2); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/LocalTimeExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.DayOfWeek; 4 | import java.time.LocalDate; 5 | import java.time.LocalTime; 6 | import java.time.Month; 7 | 8 | /** 9 | * LocalTime 示例 10 | * 11 | * @author biezhi 12 | * @date 2018/3/2 13 | */ 14 | public class LocalTimeExample { 15 | 16 | public static void main(String[] args) { 17 | 18 | // 创建一个LocalTime实例 19 | LocalTime localTime = LocalTime.now(); 20 | 21 | // 使用指定的时分秒和纳秒来新建对象 22 | LocalTime localTime2 = LocalTime.of(21, 30, 59, 11001); 23 | 24 | // 3小时后 25 | LocalTime localTimeLater = localTime.plusHours(3); 26 | // 3小时前 27 | LocalTime localTimeEarlier = localTime.minusHours(3); 28 | 29 | System.out.println("localTime : " + localTime); 30 | System.out.println("localTime2 : " + localTime2); 31 | System.out.println("localTimeLater : " + localTimeLater); 32 | System.out.println("localTimeEarlier: " + localTimeEarlier); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/ZoneIdExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.ZoneId; 4 | import java.util.TimeZone; 5 | 6 | /** 7 | * ZoneId 示例 8 | * 9 | * @author biezhi 10 | * @date 2018/3/3 11 | */ 12 | public class ZoneIdExample { 13 | 14 | public static void main(String[] args) { 15 | 16 | // 获取系统默认时区 17 | ZoneId defaultZoneId = ZoneId.systemDefault(); 18 | ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai"); 19 | 20 | // TimeZone 转换为 ZoneId 21 | ZoneId oldToNewZoneId = TimeZone.getDefault().toZoneId(); 22 | 23 | System.out.println(defaultZoneId); 24 | System.out.println(shanghaiZoneId); 25 | System.out.println(oldToNewZoneId); 26 | 27 | System.out.println(ZoneId.getAvailableZoneIds()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java8-datetime-api/src/main/java/io/github/biezhi/datetime/ZonedDateTimeExample.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.datetime; 2 | 3 | import java.time.Period; 4 | import java.time.ZoneId; 5 | import java.time.ZonedDateTime; 6 | 7 | /** 8 | * ZonedDateTime 示例 9 | * 10 | * @author biezhi 11 | * @date 2018/3/2 12 | */ 13 | public class ZonedDateTimeExample { 14 | 15 | public static void main(String[] args) { 16 | // 创建一个ZonedDateTime实例 17 | ZonedDateTime dateTime = ZonedDateTime.now(); 18 | 19 | // 使用指定的年月日、时分秒、纳秒以及时区ID来新建对象 20 | ZoneId zoneId = ZoneId.of("UTC+8"); 21 | ZonedDateTime dateTime2 = ZonedDateTime.of(2018, 3, 8, 23, 45, 59, 1234, zoneId); 22 | 23 | // 3天后 24 | ZonedDateTime zoneDateTime = dateTime2.plus(Period.ofDays(3)); 25 | 26 | ZoneId zoneId2 = ZoneId.of("Europe/Copenhagen"); 27 | ZoneId zoneId3 = ZoneId.of("Europe/Paris"); 28 | 29 | System.out.println("dateTime : " + dateTime); 30 | System.out.println("zoneDateTime : " + zoneDateTime); 31 | System.out.println("zoneId2 : " + zoneId2); 32 | System.out.println("zoneId3 : " + zoneId3); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java8-default-methods/README.md: -------------------------------------------------------------------------------- 1 | # Java 8 默认方法和静态方法 2 | 3 | -------------------------------------------------------------------------------- /java8-default-methods/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-default-methods 13 | 14 | 15 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/BasicCalculator.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods; 2 | 3 | public class BasicCalculator implements Calculator { 4 | 5 | @Override 6 | public int add(int first, int second) { 7 | return first + second; 8 | } 9 | 10 | @Override 11 | public int subtract(int first, int second) { 12 | return first - second; 13 | } 14 | 15 | @Override 16 | public int divide(int number, int divisor) { 17 | if (divisor == 0) { 18 | throw new IllegalArgumentException("divisor can't be zero."); 19 | } 20 | return number / divisor; 21 | } 22 | 23 | @Override 24 | public int multiply(int first, int second) { 25 | return first * second; 26 | } 27 | } -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/Calculator.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods; 2 | 3 | /** 4 | * 计算器接口 5 | * 6 | * @author biezhi 7 | * @date 2018/2/11 8 | */ 9 | public interface Calculator { 10 | 11 | int add(int first, int second); 12 | 13 | int subtract(int first, int second); 14 | 15 | int multiply(int first, int second); 16 | 17 | int divide(int number, int divisor); 18 | 19 | default int mod(int first, int second){ 20 | return first % second; 21 | } 22 | 23 | static Calculator getInstance(){ 24 | return new BasicCalculator(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/CalculatorFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public class CalculatorFactory { 8 | 9 | public static Calculator getInstance(){ 10 | return new BasicCalculator(); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/Collection.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods; 2 | 3 | import java.util.Iterator; 4 | import java.util.function.Predicate; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2018/2/11 9 | */ 10 | public interface Collection extends java.util.Collection { 11 | 12 | default boolean removeIf2(Predicate predicate){ 13 | boolean isRemoved = false; 14 | Iterator iterator = iterator(); 15 | while(iterator.hasNext()){ 16 | if(predicate.test(iterator.next())){ 17 | iterator.remove(); 18 | isRemoved = true; 19 | } 20 | } 21 | return isRemoved; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/UseCalc.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public class UseCalc { 8 | 9 | public static void main(String[] args) { 10 | 11 | Calculator calculator = new BasicCalculator(); 12 | int sum = calculator.add(1, 2); 13 | System.out.println(sum); 14 | 15 | Calculator cal = Calculator.getInstance(); 16 | int difference = cal.subtract(3, 2); 17 | System.out.println(difference); 18 | 19 | System.out.println(cal.mod(3, 2)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/A.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods.conflict; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public interface A { 8 | 9 | default void sayHello(){ 10 | System.out.println("你好,我是 Java 8"); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/App.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods.conflict; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public class App implements A { 8 | 9 | @Override 10 | public void sayHello(){ 11 | System.out.println("你好,我是 APP"); 12 | } 13 | 14 | public static void main(String[] args) { 15 | new App().sayHello(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/App2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods.conflict; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public class App2 implements A, B, C { 8 | 9 | public static void main(String[] args) { 10 | new App2().sayHello(); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/App3.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods.conflict; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public class App3 implements A, B { 8 | 9 | @Override 10 | public void sayHello() { 11 | System.out.println("大家好,我系古天乐。探晚懒月,里没有晚过的传奇。" + 12 | "点一下,晚一连,撞贝不花一份钱。机要晚过了传骑,里就系我的凶第。"); 13 | } 14 | 15 | public static void main(String[] args) { 16 | new App3().sayHello(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/B.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods.conflict; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public interface B { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/C.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.defaultmethods.conflict; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public interface C extends A { 8 | 9 | default void sayHello(){ 10 | System.out.println("你好,我是 渣渣辉"); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java8-growing/README.md: -------------------------------------------------------------------------------- 1 | # Java 8 的发展 2 | 3 | ## JDK 5 4 | 5 | **自动装箱与拆箱** 6 | 7 | JDK1.5为每一个基本数据类型定义了一个封装类。使java中的基本数据类型也有自己的对象 8 | 9 | ```bash 10 | int -->Integer 11 | double --> Double 12 | long --> Long 13 | char --> Character 14 | float --> Float 15 | boolean --> Boolean 16 | short --> Short 17 | byte -- > Byte 18 | ``` 19 | 20 | - 自动装包:将基本类型转换成为对象,例如:`int --> Integer` 21 | - 自动拆包:将对象转换成为基本数据类型,例如:`Integer --> int` 22 | 23 | 对于 JDK1.5 之前集合总不能存放基本数据类型的问题,现在也能够解决。 24 | 25 | **枚举** 26 | 27 | 枚举是 JDK1.5 推出的一个比较重要的特性。其关键字为 `enum` 28 | 例如:定义代表交通灯的枚举 29 | 30 | ```java 31 | public enum MyEnum{ 32 | RED,GREEN,YELLOW 33 | } 34 | ``` 35 | 36 | **静态导入** 37 | 38 | - 优点:使用静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。 39 | - 缺点:过度使用会降低代码的可读性 40 | 41 | **变长参数** 42 | 43 | 在JDK1.5以前,当我们要为一个方法传递多个类型相同的参数时, 44 | 我们有两种方法解决 45 | 46 | 1. 直接传递一个数组过去 47 | 2. 有多少个参数就传递多少个参数。 48 | 49 | 例如: 50 | 51 | ```java 52 | public void printColor(String red,String green,String yellow){ 53 | } 54 | ``` 55 | 56 | 或者 57 | 58 | ```java 59 | public void printColor(String[] colors){ 60 | 61 | } 62 | ``` 63 | 64 | 这样编写方法参数虽然能够实现我们想要的效果,但是,这样是不是有点麻烦呢? 65 | 再者,如果参数个数不确定,我们怎么办呢?Java JDK1.5为我们提供的可变参数就能够完美的解决这个问题. 66 | 67 | 例如: 68 | 69 | ```java 70 | public void printColor(String... colors){ 71 | 72 | } 73 | ``` 74 | 75 | 如果参数的类型相同,那么可以使用 `类型+三个点` ,后面跟一个参数名称的形式。 76 | 这样的好处就是,只要参数类型相同,无论传递几个参数都没有限制 77 | 注意:可变参数必须是参数列表的最后一项(该特性对对象和基本数据类型都适用) 78 | 79 | **泛型** 80 | 81 | ```java 82 | //给集合指定存入类型,上面这个集合在存入数据的时候必须存入String类型的数据,否则编译器会报错 83 | List strs = new ArrayList(); 84 | ``` 85 | 86 | “泛型” 意味着编写的代码可以被不同类型的对象所重用。 87 | 可见泛型的提出是为了编写重用性更好的代码。 88 | 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。 89 | 90 | 比如常见的集合类 `LinkedList`,其实现的接口名后有个特殊的部分 `<>`,而且它的成员的类型 Link 也包含一个 `<>`,这个符号的就是类型参数, 91 | 它使得在运行中,创建一个 LinkedList 时可以传入不同的类型,比如 `new LinkedList`,这样它的成员存放的类型也是 `String`。 92 | 93 | **For-Each循环** 94 | 95 | 例如上面这个集合我们可以通过for-each遍历,这样更加简单清晰 96 | 97 | ```java 98 | for(String s : strs){ 99 | System.out.println(s); 100 | } 101 | ``` 102 | 103 | > 注意:使用for-each遍历集合时,要遍历的集合必须实现了Iterator接口 104 | 105 | **线程并发库** 106 | 107 | 线程并发库是 Java1.5 提出的关于多线程处理的高级功能,所在包:`java.util.concurrent` 包括 108 | 109 | 1. 线程互斥工具类:Lock,ReadWriteLock 110 | 2. 线程通信:Condition 111 | 3. 线程池:ExecutorService 112 | 3. 同步队列:ArrayBlockingQueue 113 | 4. 同步集合:ConcurrentHashMap,CopyOnWriteArrayList 114 | 5. 线程同步工具:Semaphore 115 | 116 | ## JDK 6 117 | 118 | **Desktop类和SystemTray类** 119 | 120 | 前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定的邮箱发邮件, 121 | 用默认应用程序打开或编辑文件(比如,用记事本打开以 txt 为后缀名的文件), 122 | 用系统默认的打印机打印文档;后者可以用来在系统托盘区创建一个托盘程序。 123 | 124 | **使用Compiler API** 125 | 126 | 现在我们可以用JDK1.6 的Compiler API(JSR 199)去动态编译Java源文件, 127 | Compiler API结合反射功能就可以实现动态的产生Java代码并编译执行这些代码,有点动态语言的特征。 128 | 129 | 这个特性对于某些需要用到动态编译的应用程序相当有用,比如JSP Web Server,当我们手动修改JSP后, 130 | 是不希望需要重启Web Server才可以看到效果的,这时候我们就可以用Compiler API来实现动态编译JSP文件。 131 | 当然,现在的JSP Web Server也是支持JSP热部署的,现在的JSP Web Server通过在运行期间通过Runtime.exec或ProcessBuilder来调用javac来编译代码, 132 | 这种方式需要我们产生另一个进程去做编译工作,不够优雅而且容易使代码依赖与特定的操作系统; 133 | Compiler API通过一套易用的标准的API提供了更加丰富的方式去做动态编译,而且是跨平台的。 134 | 135 | **轻量级Http Server API** 136 | 137 | JDK1.6 提供了一个简单的 Http Server API,据此我们可以构建自己的嵌入式 Http Server, 138 | 它支持Http和Https协议,提供了HTTP1.1的部分实现,没有被实现的那部分可以通过扩展已有的 Http Server API来实现, 139 | 程序员必须自己实现 HttpHandler 接口,HttpServer 会调用 `HttpHandler` 实现类的回调方法来处理客户端请求, 140 | 在这里,我们把一个 Http 请求和它的响应称为一个交换,包装成 `HttpExchange` 类,`HttpServer` 负责将 `HttpExchange` 传给 `HttpHandler` 实现类的回调方法。 141 | 142 | **用Console开发控制台程序** 143 | 144 | JDK1.6 中提供了 `java.io.Console` 类专用来访问基于字符的控制台设备。 145 | 你的程序如果要与 Windows 下的 cmd 或者 Linux 下的 Terminal 交互,就可以用 `Console` 类代劳。 146 | 但我们不总是能得到可用的 Console,一个JVM是否有可用的 Console 依赖于底层平台和 JVM 如何被调用。 147 | 如果JVM是在交互式命令行(比如 Windows 的 cmd)中启动的,并且输入输出没有重定向到另外的地方,那么就可以得到一个可用的 Console 实例。 148 | 149 | **对脚本语言的支持** 150 | 151 | 如:ruby,groovy,javascript。 152 | 153 | ## JDK 7 154 | 155 | **数字变量对下滑线的支持** 156 | 157 | JDK1.7可以在数值类型的变量里添加下滑线,但是有几个地方是不能添加的 158 | 159 | 1. 数字的开头和结尾 160 | 2. 小数点前后 161 | 3. F或者L前 162 | 163 | 例如: 164 | 165 | ```java 166 | int num = 1234_5678_9; 167 | float num2 = 222_33F; 168 | long num3 = 123_000_111L; 169 | ``` 170 | 171 | **switch对String的支持** 172 | 173 | ```java 174 | String status = "orderState"; 175 | switch (status) { 176 | case "ordercancel": 177 | System.out.println("订单取消"); 178 | break; 179 | case "orderSuccess": 180 | System.out.println("预订成功"); 181 | break; 182 | default: 183 | System.out.println("状态未知"); 184 | } 185 | ``` 186 | 187 | **try-with-resource** 188 | 189 | - `try-with-resources` 是一个定义了一个或多个资源的 try 声明,这个资源是指程序处理完它之后需要关闭它的对象。 190 | - `try-with-resources` 确保每一个资源在处理完成后都会被关闭。 191 | 192 | 可以使用try-with-resources的资源有: 任何实现了 `java.lang.AutoCloseable` 接口 `java.io.Closeable` 接口的对象。 193 | 194 | 例如: 195 | 196 | ```java 197 | public static String readFirstLineFromFile(String path) throws IOException { 198 | 199 | try (BufferedReader br = new BufferedReader(new FileReader(path))) { 200 | return br.readLine(); 201 | } 202 | } 203 | ``` 204 | 205 | 在 java 7 以及以后的版本里,`BufferedReader` 实现了 `java.lang.AutoCloseable` 接口。 206 | 由于 `BufferedReader` 定义在 `try-with-resources` 声明里,无论 `try` 语句正常还是异常的结束, 207 | 它都会自动的关掉。而在 java7 以前,你需要使用 `finally` 块来关掉这个对象。 208 | 209 | **捕获多种异常并用改进后的类型检查来重新抛出异常** 210 | 211 | ```java 212 | public static void first(){ 213 | try { 214 | BufferedReader reader = new BufferedReader(new FileReader("")); 215 | Connection con = null; 216 | Statement stmt = con.createStatement(); 217 | } catch (IOException | SQLException e) { 218 | //捕获多个异常,e就是final类型的 219 | e.printStackTrace(); 220 | } 221 | } 222 | ``` 223 | 224 | 优点:用一个 `catch` 处理多个异常,比用多个 `catch` 每个处理一个异常生成的字节码要更小更高效。 225 | 226 | **创建泛型时类型推断** 227 | 228 | 只要编译器可以从上下文中推断出类型参数,你就可以用一对空着的尖括号 `<>` 来代替泛型参数。 229 | 这对括号私下被称为菱形(diamond)。 在Java SE 7之前,你声明泛型对象时要这样 230 | 231 | ```java 232 | List list = new ArrayList(); 233 | ``` 234 | 235 | 而在Java SE7以后,你可以这样 236 | 237 | ```java 238 | List list = new ArrayList<>(); 239 | ``` 240 | 241 | 因为编译器可以从前面(List)推断出推断出类型参数,所以后面的 `ArrayList` 之后可以不用写泛型参数了,只用一对空着的尖括号就行。 242 | 当然,你必须带着菱形 `<>`,否则会有警告的。 243 | Java SE7 只支持有限的类型推断:只有构造器的参数化类型在上下文中被显著的声明了,你才可以使用类型推断,否则不行。 244 | 245 | ```java 246 | List list = new ArrayList<>();l 247 | list.add("A"); 248 | //这个不行 249 | list.addAll(new ArrayList<>()); 250 | // 这个可以 251 | List list2 = new ArrayList<>(); 252 | list.addAll(list2); 253 | ``` 254 | 255 | ## JDK 8 256 | 257 | **Lambda表达式和函数式接口** 258 | 259 | Lambda表达式(也称为闭包)是Java 8中最大和最令人期待的语言改变。它允许我们将函数当成参数传递给某个方法, 260 | 或者把代码本身当作数据处理:函数式开发者非常熟悉这些概念。很多JVM平台上的语言(Groovy、Scala等)从诞生之日就支持Lambda表达式,但是Java开发者没有选择,只能使用匿名内部类代替Lambda表达式。 261 | Lambda的设计耗费了很多时间和很大的社区力量,最终找到一种折中的实现方案,可以实现简洁而紧凑的语言结构。最简单的Lambda表达式可由逗号分隔的参数列表、->符号和语句块组成。 262 | 263 | Lambda的设计者们为了让现有的功能与Lambda表达式良好兼容,考虑了很多方法,于是产生了函数接口这个概念。函数接口指的是只有一个函数的接口,这样的接口可以隐式转换为Lambda表达式。java.lang.Runnable和java.util.concurrent.Callable是函数式接口的最佳例子。在实践中,函数式接口非常脆弱:只要某个开发者在该接口中添加一个函数,则该接口就不再是函数式接口进而导致编译失败。为了克服这种代码层面的脆弱性,并显式说明某个接口是函数式接口,Java 8 提供了一个特殊的注解@FunctionalInterface(Java 库中的所有相关接口都已经带有这个注解了),举个简单的函数式接口的定义 264 | 265 | **接口的默认方法和静态方法** 266 | 267 | Java 8使用两个新概念扩展了接口的含义:默认方法和静态方法。默认方法使得接口有点类似traits,不过要实现的目标不一样。默认方法使得开发者可以在 不破坏二进制兼容性的前提下,往现存接口中添加新的方法,即不强制那些实现了该接口的类也同时实现这个新加的方法。 268 | 默认方法和抽象方法之间的区别在于抽象方法需要实现,而默认方法不需要。接口提供的默认方法会被接口的实现类继承或者覆写 269 | 由于JVM上的默认方法的实现在字节码层面提供了支持,因此效率非常高。默认方法允许在不打破现有继承体系的基础上改进接口。该特性在官方库中的应用是:给java.util.Collection接口添加新方法,如stream()、parallelStream()、forEach()和removeIf()等等。 270 | 尽管默认方法有这么多好处,但在实际开发中应该谨慎使用:在复杂的继承体系中,默认方法可能引起歧义和编译错误。如果你想了解更多细节,可以参考官方文档。 271 | 272 | **更好的类型推断** 273 | 274 | Java 8 编译器在类型推断方面有很大的提升,在很多场景下编译器可以推导出某个参数的数据类型,从而使得代码更为简洁。 275 | 276 | 参数 `Value.defaultValue()` 的类型由编译器推导得出,不需要显式指明。在Java 7中这段代码会有编译错误,除非使用 `Value.defaultValue()`。 277 | 278 | **Optional** 279 | 280 | Java应用中最常见的bug就是空值异常。在Java 8之前,Google Guava引入了 `Optionals` 类来解决 `NullPointerException`, 281 | 从而避免源码被各种 `null` 检查污染,以便开发者写出更加整洁的代码。Java 8也将Optional加入了官方库。 282 | `Optional` 仅仅是一个容易存放T类型的值或者null。它提供了一些有用的接口来避免显式的null检查,可以参考Java 8官方文档了解更多细节。 283 | 284 | 如果Optional实例持有一个非空值,则 `isPresent()` 方法返回true,否则返回false;`orElseGet()` 方法,Optional实例持有null, 285 | 则可以接受一个lambda表达式生成的默认值;map()方法可以将现有的 `Optional` 实例的值转换成新的值;orElse()方法与orElseGet()方法类似, 286 | 但是在持有null的时候返回传入的默认值。 287 | 288 | **Streams** 289 | 290 | 新增的Stream API(java.util.stream)将生成环境的函数式编程引入了Java库中。 291 | 这是目前为止最大的一次对Java库的完善,以便开发者能够写出更加有效、更加简洁和紧凑的代码。 292 | 293 | Task 类有一个分数(或伪复杂度)的概念,另外还有两种状态:OPEN 或者 CLOSED。现在假设有一个task集合, 294 | 首先看一个问题:在这个task集合中一共有多少个OPEN状态的点?在Java 8之前,要解决这个问题,则需要使用foreach循环遍历task集合; 295 | 但是在Java 8中可以利用steams解决:包括一系列元素的列表,并且支持顺序和并行处理。 296 | 297 | ```java 298 | final Collection tasks = Arrays.asList( 299 | new Task(Status.OPEN, 5), 300 | new Task(Status.OPEN, 13), 301 | new Task(Status.CLOSED, 8) 302 | ); 303 | 304 | // Calculate total points of all active tasks using sum() 305 | final long totalPointsOfOpenTasks = tasks 306 | .stream() 307 | .filter(task -> task.getStatus() == Status.OPEN) 308 | .mapToInt(Task::getPoints) 309 | .sum(); 310 | 311 | System.out.println("Total points: " + totalPointsOfOpenTasks); 312 | ``` 313 | 314 | 这里有很多知识点值得说。首先,tasks集合被转换成steam表示;其次,在steam上的filter操作会过滤掉所有CLOSED的task; 315 | 第三,mapToInt操作基于每个task实例的Task::getPoints方法将task流转换成Integer集合;最后,通过sum方法计算总和,得出最后的结果。 316 | 317 | **新的日期时间 API** 318 | 319 | Java 8引入了新的Date-Time API(JSR 310)来改进时间、日期的处理。时间和日期的管理一直是最令Java开发者痛苦的问题。 320 | java.util.Date 和后来的 java.util.Calendar 一直没有解决这个问题(甚至令开发者更加迷茫)。 321 | 322 | 因为上面这些原因,诞生了第三方库Joda-Time,可以替代Java的时间管理API。 323 | Java 8中新的时间和日期管理API深受Joda-Time影响,并吸收了很多Joda-Time的精华。 324 | 新的java.time包包含了所有关于日期、时间、时区、Instant(跟日期类似但是精确到纳秒)、duration(持续时间)和时钟操作的类。 325 | 新设计的API认真考虑了这些类的不变性(从java.util.Calendar吸取的教训),如果某个实例需要修改,则返回一个新的对象。 326 | 327 | 第二,关注下LocalDate和LocalTime类。LocalDate仅仅包含ISO-8601日历系统中的日期部分;LocalTime则仅仅包含该日历系统中的时间部分。这两个类的对象都可以使用Clock对象构建得到。 328 | LocalDateTime类包含了LocalDate和LocalTime的信息,但是不包含ISO-8601日历系统中的时区信息。这里有一些关于LocalDate和LocalTime的例子: 329 | 如果你需要特定时区的data/time信息,则可以使用ZoneDateTime,它保存有ISO-8601日期系统的日期和时间,而且有时区信息。 330 | 331 | **Nashorn JavaScript引擎** 332 | 333 | Java 8提供了新的Nashorn JavaScript引擎,使得我们可以在JVM上开发和运行JS应用。 334 | Nashorn JavaScript引擎是javax.script.ScriptEngine的另一个实现版本,这类Script引擎遵循相同的规则,允许Java和JavaScript交互使用,例子代码如下: 335 | 336 | **Base64** 337 | 338 | 对 Base64 编码的支持已经被加入到Java 8官方库中,这样不需要使用第三方库就可以进行Base64编码,例子代码如下: 339 | 340 | ```java 341 | final String text = "Lets Learn Java 8!"; 342 | 343 | final String encoded = Base64 344 | .getEncoder() 345 | .encodeToString(text.getBytes(StandardCharsets.UTF_8)); 346 | System.out.println(encoded); 347 | 348 | final String decoded = new String( 349 | Base64.getDecoder().decode(encoded), 350 | StandardCharsets.UTF_8); 351 | System.out.println(decoded); 352 | ``` 353 | 354 | 新的Base64API也支持URL和MINE的编码解码。 355 | -------------------------------------------------------------------------------- /java8-growing/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-growing 13 | 14 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/AutoBoxing.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk5; 2 | 3 | /** 4 | * 自动装箱、拆箱 5 | * 6 | * @author biezhi 7 | * @date 2018/2/8 8 | */ 9 | public class AutoBoxing { 10 | 11 | public static void main(String[] args) { 12 | int a = new Integer(66); 13 | Integer b = 18; 14 | 15 | Boolean flag = true; 16 | boolean isBug = Boolean.FALSE; 17 | 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/Concurrent.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk5; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.Queue; 6 | import java.util.concurrent.*; 7 | import java.util.concurrent.locks.Condition; 8 | import java.util.concurrent.locks.Lock; 9 | import java.util.concurrent.locks.ReentrantLock; 10 | 11 | /** 12 | * 并发库 13 | * 14 | * @author biezhi 15 | * @date 2018/2/8 16 | */ 17 | public class Concurrent { 18 | 19 | public void lock() { 20 | Lock lock = new ReentrantLock(); 21 | lock.lock(); 22 | try { 23 | System.out.println("hello world"); 24 | } finally { 25 | lock.unlock(); 26 | } 27 | } 28 | 29 | public void condition() throws InterruptedException { 30 | Lock lock = new ReentrantLock(); 31 | Condition condition = lock.newCondition(); 32 | // do something 33 | condition.await(10, TimeUnit.SECONDS); 34 | System.out.println("Get result."); 35 | } 36 | 37 | public void executorService() { 38 | ExecutorService executorService = Executors.newFixedThreadPool(3); 39 | executorService.submit(new Runnable() { 40 | @Override 41 | public void run() { 42 | System.out.println("Task is running."); 43 | } 44 | }); 45 | } 46 | 47 | public void blockingDeque() { 48 | Queue blockingDeque = new ArrayBlockingQueue<>(20); 49 | blockingDeque.add(1); 50 | blockingDeque.add(2); 51 | blockingDeque.add(3); 52 | 53 | blockingDeque.peek(); 54 | } 55 | 56 | public void concurrentHashMap() { 57 | Map concurrentHashMap = new ConcurrentHashMap<>(); 58 | concurrentHashMap.put("Hello", 1); 59 | concurrentHashMap.put("World", 2); 60 | 61 | System.out.println(concurrentHashMap.get("Hello")); 62 | } 63 | 64 | public void copyOnWriteList() { 65 | List copyOnWriteList = new CopyOnWriteArrayList<>(); 66 | copyOnWriteList.add("a"); 67 | copyOnWriteList.add("b"); 68 | copyOnWriteList.add("c"); 69 | 70 | System.out.println(copyOnWriteList.size()); 71 | } 72 | 73 | public void semaphore() { 74 | Semaphore semaphore = new Semaphore(3); 75 | try { 76 | semaphore.acquire(); 77 | System.out.println(Thread.currentThread().getName() + " is working"); 78 | Thread.sleep(1000); 79 | semaphore.release(); 80 | System.out.println(Thread.currentThread().getName() + " is over"); 81 | } catch (InterruptedException e) { 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/EnumDemo.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk5; 2 | 3 | /** 4 | * 枚举 5 | * 6 | * @author biezhi 7 | * @date 2018/2/8 8 | */ 9 | public enum EnumDemo { 10 | 11 | RED, GREEN, YELLOW 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/ForEach.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk5; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * for each 8 | * 9 | * @author biezhi 10 | * @date 2018/2/8 11 | */ 12 | public class ForEach { 13 | 14 | public static void main(String[] args) { 15 | 16 | int[] arr = {1, 4, 5, 7}; 17 | 18 | for (int i : arr) { 19 | System.out.println(i); 20 | } 21 | 22 | List names = Arrays.asList("王爵nice", "Gay冰", "A*熊"); 23 | for (String name : names) { 24 | System.out.println(name); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/Generic.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk5; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 泛型 8 | * 9 | * @author biezhi 10 | * @date 2018/2/8 11 | */ 12 | public class Generic { 13 | 14 | public T getById(Integer id){ 15 | return null; 16 | } 17 | 18 | public static void main(String[] args) { 19 | 20 | Map map = new HashMap<>(); 21 | 22 | Generic generic = new Generic<>(); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/StaticImport.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk5; 2 | 3 | import static java.lang.System.out; 4 | 5 | /** 6 | * 静态导入 7 | * 8 | * @author biezhi 9 | * @date 2018/2/8 10 | */ 11 | public class StaticImport { 12 | 13 | public static void main(String[] args) { 14 | out.println("Hi let learn java 8."); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/VarArgs.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk5; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * 变长参数 8 | * 9 | * @author biezhi 10 | * @date 2018/2/8 11 | */ 12 | public class VarArgs { 13 | 14 | public static List asList(String[] names){ 15 | return Arrays.asList(names); 16 | } 17 | 18 | public static void main(String[] args) { 19 | List hello = Arrays.asList("王爵nice", "Gay冰", "A*熊"); 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/CompilerAPI.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk6; 2 | 3 | import javax.tools.*; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | import java.io.OutputStream; 7 | import java.lang.reflect.Method; 8 | import java.net.URI; 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.Iterator; 12 | import java.util.List; 13 | 14 | /** 15 | * 使用Compiler API 16 | * 17 | * @author biezhi 18 | * @date 2018/2/8 19 | */ 20 | public class CompilerAPI { 21 | 22 | public static void main(String[] args) throws Exception { 23 | String program = "" + 24 | "public class LearnJava6 {\n" + 25 | " public static void main(String[] args) {\n" + 26 | " System.out.println(\"欢迎你学习跟上 Java 8 之 CompilerAPI!\");\n" + 27 | " }\n" + 28 | "}\n"; 29 | 30 | JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 31 | 32 | JavaFileObject compilationUnit = 33 | new StringJavaFileObject("LearnJava6", program); 34 | 35 | SimpleJavaFileManager fileManager = 36 | new SimpleJavaFileManager(compiler.getStandardFileManager(null, null, null)); 37 | 38 | JavaCompiler.CompilationTask compilationTask = compiler.getTask( 39 | null, fileManager, null, null, null, Arrays.asList(compilationUnit)); 40 | 41 | compilationTask.call(); 42 | 43 | CompiledClassLoader classLoader = 44 | new CompiledClassLoader(fileManager.getGeneratedOutputFiles()); 45 | 46 | Class codeGenTest = classLoader.loadClass("LearnJava6"); 47 | Method main = codeGenTest.getMethod("main", String[].class); 48 | main.invoke(null, new Object[]{null}); 49 | } 50 | 51 | private static class StringJavaFileObject extends SimpleJavaFileObject { 52 | private final String code; 53 | 54 | public StringJavaFileObject(String name, String code) { 55 | super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), 56 | Kind.SOURCE); 57 | this.code = code; 58 | } 59 | 60 | @Override 61 | public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { 62 | return code; 63 | } 64 | } 65 | 66 | private static class ClassJavaFileObject extends SimpleJavaFileObject { 67 | private final ByteArrayOutputStream outputStream; 68 | private final String className; 69 | 70 | protected ClassJavaFileObject(String className, Kind kind) { 71 | super(URI.create("mem:///" + className.replace('.', '/') + kind.extension), kind); 72 | this.className = className; 73 | outputStream = new ByteArrayOutputStream(); 74 | } 75 | 76 | @Override 77 | public OutputStream openOutputStream() throws IOException { 78 | return outputStream; 79 | } 80 | 81 | public byte[] getBytes() { 82 | return outputStream.toByteArray(); 83 | } 84 | 85 | public String getClassName() { 86 | return className; 87 | } 88 | } 89 | 90 | private static class SimpleJavaFileManager extends ForwardingJavaFileManager { 91 | private final List outputFiles; 92 | 93 | protected SimpleJavaFileManager(JavaFileManager fileManager) { 94 | super(fileManager); 95 | outputFiles = new ArrayList(); 96 | } 97 | 98 | @Override 99 | public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException { 100 | ClassJavaFileObject file = new ClassJavaFileObject(className, kind); 101 | outputFiles.add(file); 102 | return file; 103 | } 104 | 105 | public List getGeneratedOutputFiles() { 106 | return outputFiles; 107 | } 108 | } 109 | 110 | private static class CompiledClassLoader extends ClassLoader { 111 | private final List files; 112 | 113 | private CompiledClassLoader(List files) { 114 | this.files = files; 115 | } 116 | 117 | @Override 118 | protected Class findClass(String name) throws ClassNotFoundException { 119 | Iterator itr = files.iterator(); 120 | while (itr.hasNext()) { 121 | ClassJavaFileObject file = itr.next(); 122 | if (file.getClassName().equals(name)) { 123 | itr.remove(); 124 | byte[] bytes = file.getBytes(); 125 | return super.defineClass(name, bytes, 0, bytes.length); 126 | } 127 | } 128 | return super.findClass(name); 129 | } 130 | } 131 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/Console.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk6; 2 | 3 | /** 4 | * 用Console开发控制台程序 5 | * 6 | * @author biezhi 7 | * @date 2018/2/8 8 | */ 9 | public class Console { 10 | 11 | public static void main(String[] args) { 12 | 13 | java.io.Console console = System.console(); 14 | 15 | if (console != null) { 16 | String user = new String(console.readLine(" Enter User: ", new Object[0])); 17 | String pwd = new String(console.readPassword(" Enter Password: ", new Object[0])); 18 | console.printf(" User name is:%s ", new Object[]{user}); 19 | console.printf(" Password is:%s ", new Object[]{pwd}); 20 | } else { 21 | System.out.println(" No Console! "); 22 | } 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/DesktopTray.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk6; 2 | 3 | /** 4 | * Desktop类和SystemTray类 5 | * 6 | * https://www.programcreek.com/java-api-examples/java.awt.Desktop 7 | * 8 | * @author biezhi 9 | * @date 2018/2/8 10 | */ 11 | public class DesktopTray { 12 | 13 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/HttpServerAPI.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk6; 2 | 3 | import com.sun.net.httpserver.HttpExchange; 4 | import com.sun.net.httpserver.HttpHandler; 5 | import com.sun.net.httpserver.HttpServer; 6 | 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | import java.net.InetSocketAddress; 11 | 12 | /** 13 | * Http Server 14 | * 15 | * @author biezhi 16 | * @date 2018/2/8 17 | */ 18 | public class HttpServerAPI { 19 | 20 | private static int count = 0; 21 | 22 | static class MyHandler implements HttpHandler { 23 | @Override 24 | public void handle(HttpExchange he) throws IOException { 25 | System.out.println("Request " + count++); 26 | System.out.println(he.getHttpContext().getPath()); 27 | 28 | InputStream is = he.getRequestBody(); 29 | String response = "Lets Learn Java8."; 30 | he.sendResponseHeaders(200, response.length()); 31 | OutputStream os = he.getResponseBody(); 32 | os.write(response.getBytes()); 33 | os.close(); 34 | } 35 | } 36 | 37 | public static void main(String[] args) { 38 | try { 39 | HttpServer hs = HttpServer.create(new InetSocketAddress(8080), 0); 40 | hs.createContext("/", new MyHandler()); 41 | hs.createContext("/java", new MyHandler()); 42 | hs.setExecutor(null); 43 | hs.start(); 44 | System.out.println("---begin---"); 45 | System.out.println("Listening on " + hs.getAddress()); 46 | } catch (IOException ioe) { 47 | ioe.printStackTrace(); 48 | } 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/ScriptEngineDemo.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk6; 2 | 3 | import javax.script.Invocable; 4 | import javax.script.ScriptEngine; 5 | import javax.script.ScriptEngineManager; 6 | import java.io.FileReader; 7 | 8 | /** 9 | * 对脚本语言的支持 10 | * 11 | * @author biezhi 12 | * @date 2018/2/8 13 | */ 14 | public class ScriptEngineDemo { 15 | 16 | public static void main(String[] args) { 17 | 18 | ScriptEngineManager manager = new ScriptEngineManager(); 19 | ScriptEngine engine = manager.getEngineByName("ECMAScript"); 20 | try { 21 | String jsPath = ScriptEngineDemo.class.getResource("/test.js").getPath(); 22 | 23 | engine.eval(new FileReader(jsPath)); 24 | 25 | Invocable invokableEngine = (Invocable) engine; 26 | 27 | Object ret = invokableEngine.invokeFunction("test", null); 28 | 29 | System.out.println("The result is : " + ret); 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/CatchMultiException.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk7; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileReader; 5 | import java.io.IOException; 6 | import java.sql.Connection; 7 | import java.sql.SQLException; 8 | import java.sql.Statement; 9 | 10 | /** 11 | * 捕获多异常 12 | * 13 | * @author biezhi 14 | * @date 2018/2/8 15 | */ 16 | public class CatchMultiException { 17 | 18 | public static void main(String[] args) { 19 | try { 20 | BufferedReader reader = new BufferedReader(new FileReader("")); 21 | Connection con = null; 22 | Statement stmt = con.createStatement(); 23 | } catch (IOException | SQLException e) { 24 | //捕获多个异常,e就是final类型的 25 | e.printStackTrace(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/NumericUnderline.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk7; 2 | 3 | /** 4 | * 数字下划线支持 5 | * 6 | * @author biezhi 7 | * @date 2018/2/8 8 | */ 9 | public class NumericUnderline { 10 | 11 | public static void main(String[] args) { 12 | int num = 1234_5678_9; 13 | float num2 = 222_33F; 14 | long num3 = 123_000_111L; 15 | long tenSenconds = 10_000L; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/SwitchString.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk7; 2 | 3 | import io.github.biezhi.java8.growing.jdk5.EnumDemo; 4 | 5 | /** 6 | * switch对String的支持 7 | * 8 | * @author biezhi 9 | * @date 2018/2/8 10 | */ 11 | public class SwitchString { 12 | 13 | public static void main(String[] args) { 14 | String bis = "java"; 15 | switch (bis) { 16 | case "java": 17 | break; 18 | case "python": 19 | break; 20 | case "ruby": 21 | break; 22 | default: 23 | break; 24 | } 25 | 26 | EnumDemo enumDemo = EnumDemo.GREEN; 27 | 28 | switch (enumDemo) { 29 | case RED: 30 | break; 31 | case YELLOW: 32 | break; 33 | default: 34 | break; 35 | } 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/TryWithResource.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk7; 2 | 3 | import io.github.biezhi.java8.growing.jdk6.ScriptEngineDemo; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.FileReader; 7 | import java.io.IOException; 8 | 9 | /** 10 | * try-with-resource 11 | * 12 | * @author biezhi 13 | * @date 2018/2/8 14 | */ 15 | public class TryWithResource { 16 | 17 | public static void main(String[] args) { 18 | String path = ScriptEngineDemo.class.getResource("/test.js").getPath(); 19 | 20 | try (BufferedReader br = new BufferedReader(new FileReader(path))) { 21 | String str = br.readLine(); 22 | while (null != str) { 23 | System.out.println(str); 24 | str = br.readLine(); 25 | } 26 | } catch (IOException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/TypeInference.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk7; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 类型推断 8 | * 9 | * @author biezhi 10 | * @date 2018/2/8 11 | */ 12 | public class TypeInference { 13 | 14 | public static void main(String[] args) { 15 | List list = new ArrayList<>(); 16 | list.add("A"); 17 | 18 | List list2 = new ArrayList<>(); 19 | list.addAll(list2); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/Base64Demo.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | import java.util.Base64; 5 | 6 | /** 7 | * Base64 增强 8 | * 9 | * @author biezhi 10 | * @date 2018/2/8 11 | */ 12 | public class Base64Demo { 13 | 14 | public static void main(String[] args) { 15 | final String text = "Lets Learn Java 8!"; 16 | 17 | final String encoded = Base64 18 | .getEncoder() 19 | .encodeToString(text.getBytes(StandardCharsets.UTF_8)); 20 | System.out.println(encoded); 21 | 22 | final String decoded = new String( 23 | Base64.getDecoder().decode(encoded), 24 | StandardCharsets.UTF_8); 25 | System.out.println(decoded); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/DateTimeAPI.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | import java.time.*; 4 | 5 | /** 6 | * 新的日期时间 API 7 | * 8 | * @author biezhi 9 | * @date 2018/2/8 10 | */ 11 | public class DateTimeAPI { 12 | 13 | public static void main(String[] args) { 14 | // Get the system clock as UTC offset 15 | final Clock clock = Clock.systemUTC(); 16 | System.out.println(clock.instant()); 17 | System.out.println(clock.millis()); 18 | 19 | // Get the local date and local time 20 | final LocalDate date = LocalDate.now(); 21 | final LocalDate dateFromClock = LocalDate.now(clock); 22 | 23 | System.out.println(date); 24 | System.out.println(dateFromClock); 25 | 26 | // Get the local date and local time 27 | final LocalTime time = LocalTime.now(); 28 | final LocalTime timeFromClock = LocalTime.now(clock); 29 | 30 | System.out.println(time); 31 | System.out.println(timeFromClock); 32 | 33 | // Get the local date/time 34 | final LocalDateTime datetime = LocalDateTime.now(); 35 | final LocalDateTime datetimeFromClock = LocalDateTime.now(clock); 36 | 37 | System.out.println(datetime); 38 | System.out.println(datetimeFromClock); 39 | 40 | // Get the zoned date/time 41 | final ZonedDateTime zonedDatetime = ZonedDateTime.now(); 42 | final ZonedDateTime zonedDatetimeFromClock = ZonedDateTime.now(clock); 43 | final ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now(ZoneId.of("America/Los_Angeles")); 44 | 45 | System.out.println(zonedDatetime); 46 | System.out.println(zonedDatetimeFromClock); 47 | System.out.println(zonedDatetimeFromZone); 48 | 49 | // Get duration between two dates 50 | final LocalDateTime from = LocalDateTime.of(2014, Month.APRIL, 16, 0, 0, 0); 51 | final LocalDateTime to = LocalDateTime.of(2015, Month.APRIL, 16, 23, 59, 59); 52 | 53 | final Duration duration = Duration.between(from, to); 54 | System.out.println("Duration in days: " + duration.toDays()); 55 | System.out.println("Duration in hours: " + duration.toHours()); 56 | 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/DefaulableFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | import java.util.function.Supplier; 4 | 5 | public interface DefaulableFactory { 6 | // Interfaces now allow static methods 7 | static Integer create(Supplier supplier) { 8 | return supplier.get(); 9 | } 10 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/Functional.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | /** 4 | * 函数式接口 5 | * 6 | * @author biezhi 7 | * @date 2018/2/8 8 | */ 9 | @FunctionalInterface 10 | public interface Functional { 11 | 12 | void method(); 13 | 14 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/FunctionalDefaultMethods.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | /** 4 | * 默认方法 5 | * 6 | * @author biezhi 7 | * @date 2018/2/8 8 | */ 9 | @FunctionalInterface 10 | public interface FunctionalDefaultMethods { 11 | 12 | void method(); 13 | 14 | default void defaultMethod() { 15 | } 16 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/Lambda.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Lambda 表达式 7 | * 8 | * @author biezhi 9 | * @date 2018/2/8 10 | */ 11 | public class Lambda { 12 | 13 | public static void main(String[] args) { 14 | Arrays.asList("a", "b", "d").forEach(System.out::println); 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/NashornDemo.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | import javax.script.ScriptEngine; 4 | import javax.script.ScriptEngineManager; 5 | import javax.script.ScriptException; 6 | 7 | /** 8 | * Nashorn JavaScript引擎 9 | * 10 | * @author biezhi 11 | * @date 2018/2/8 12 | */ 13 | public class NashornDemo { 14 | 15 | public static void main(String[] args) throws ScriptException { 16 | ScriptEngineManager manager = new ScriptEngineManager(); 17 | ScriptEngine engine = manager.getEngineByName("JavaScript"); 18 | 19 | System.out.println(engine.getClass().getName()); 20 | System.out.println("Result:" + engine.eval("function f() { return 1; }; f() + 1;")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/OptionalDemo.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | import java.util.Optional; 4 | 5 | /** 6 | * Optional 7 | * 8 | * @author biezhi 9 | * @date 2018/2/8 10 | */ 11 | public class OptionalDemo { 12 | 13 | public static void main(String[] args) { 14 | Optional fullName = Optional.ofNullable(null); 15 | System.out.println("Full Name is set? " + fullName.isPresent()); 16 | System.out.println("Full Name: " + fullName.orElse("[none]")); 17 | System.out.println(fullName.map(s -> "Hey " + s + "!").orElse("Hey Stranger!")); 18 | 19 | Optional firstName = Optional.of("Tom"); 20 | System.out.println("First Name is set? " + firstName.isPresent()); 21 | System.out.println("First Name: " + firstName.orElseGet(() -> "[none]")); 22 | System.out.println(firstName.map(s -> "Hey " + s + "!").orElse("Hey Stranger!")); 23 | System.out.println(); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/ParallelArrays.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | import java.util.Arrays; 4 | import java.util.concurrent.ThreadLocalRandom; 5 | 6 | /** 7 | * 并行数组 8 | * 9 | * @author biezhi 10 | * @date 2018/2/8 11 | */ 12 | public class ParallelArrays { 13 | 14 | public static void main(String[] args) { 15 | long[] arrayOfLong = new long[20000]; 16 | 17 | Arrays.parallelSetAll(arrayOfLong, 18 | index -> ThreadLocalRandom.current().nextInt(1000000)); 19 | Arrays.stream(arrayOfLong).limit(10).forEach( 20 | i -> System.out.print(i + " ")); 21 | System.out.println(); 22 | 23 | Arrays.parallelSort(arrayOfLong); 24 | Arrays.stream(arrayOfLong).limit(10).forEach( 25 | i -> System.out.print(i + " ")); 26 | System.out.println(); 27 | } 28 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/Streams.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collection; 5 | 6 | public class Streams { 7 | 8 | private enum Status { 9 | OPEN, CLOSED 10 | } 11 | 12 | private static final class Task { 13 | private final Status status; 14 | private final Integer points; 15 | 16 | Task(final Status status, final Integer points) { 17 | this.status = status; 18 | this.points = points; 19 | } 20 | 21 | public Integer getPoints() { 22 | return points; 23 | } 24 | 25 | public Status getStatus() { 26 | return status; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return String.format("[%s, %d]", status, points); 32 | } 33 | } 34 | 35 | public static void main(String[] args) { 36 | final Collection tasks = Arrays.asList( 37 | new Task(Status.OPEN, 5), 38 | new Task(Status.OPEN, 13), 39 | new Task(Status.CLOSED, 8) 40 | ); 41 | 42 | // Calculate total points of all active tasks using sum() 43 | final long totalPointsOfOpenTasks = tasks 44 | .stream() 45 | .filter(task -> task.getStatus() == Status.OPEN) 46 | .mapToInt(Task::getPoints) 47 | .sum(); 48 | 49 | System.out.println("Total points: " + totalPointsOfOpenTasks); 50 | } 51 | } -------------------------------------------------------------------------------- /java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/TypeInference.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.growing.jdk8; 2 | 3 | /** 4 | * 更好的类型推断 5 | * 6 | * @author biezhi 7 | * @date 2018/2/8 8 | */ 9 | public class TypeInference { 10 | 11 | public static T defaultValue() { 12 | return null; 13 | } 14 | 15 | public T getOrDefault(T value, T defaultValue) { 16 | return (value != null) ? value : defaultValue; 17 | } 18 | 19 | public static void main(String[] args) { 20 | final TypeInference typeInference = new TypeInference<>(); 21 | typeInference.getOrDefault("22", TypeInference.defaultValue()); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /java8-growing/src/main/resources/test.js: -------------------------------------------------------------------------------- 1 | function test(){ 2 | return Math.round( 11.2 ); 3 | } -------------------------------------------------------------------------------- /java8-lambda/README.md: -------------------------------------------------------------------------------- 1 | # lambda 表达式 2 | 3 | ## 命令式和函数式 4 | 5 | **命令式编程**:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。 6 | **声明式编程**:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。 7 | 8 | ## 什么是函数式编程? 9 | 10 | 每个人对函数式编程的理解不尽相同。 我的理解是:**在完成一个编程任务时,通过使用不可变的值或函数,对他们进行处理,然后得到另一个值的过程。** 11 | 不同的语言社区往往对各自语言中的特性孤芳自赏。现在谈 Java 程序员如何定义函数式编程还为时尚早,但是,这根本不重要! 12 | 我们关心的是如何写出好代码,而不是符合函数式编程风格的代码。 13 | 14 | ## 行为参数化 15 | 16 | 把算法的策略(行为)作为一个参数传递给函数。 17 | 18 | ## lambda 管中窥豹 19 | 20 | * 匿名:它不像普通的方法那样有一个明确的名称:写得少而想得多! 21 | * 函数:Lambda函数不像方法那样属于某个特定的类。但和方法一样,Lambda有参数列表、函数主体、返回类型,还可能有可以抛出的异常列表。 22 | * 传递:Lambda表达式可以作为参数传递给方法或存储在变量中。 23 | * 简洁:无需像匿名类那样写很多模板代码。 24 | 25 | ## 函数描述符 26 | 27 | 函数式接口的抽象方法的签名基本上就是Lambda表达式的签名,这种抽象方法叫作函数描述符。 28 | 29 | ## 函数式接口,类型推断 30 | 31 | 函数式接口定义且只定义了一个抽象方法,因为抽象方法的签名可以描述Lambda表达式的签名。 32 | 函数式接口的抽象方法的签名称为函数描述符。 33 | 所以为了应用不同的Lambda表达式,你需要一套能够描述常见函数描述符的函数式接口。 34 | 35 | ## Java 8中的常用函数式接口 36 | 37 | | 函数式接口 | 函数描述符 | 原始类型特化 | 38 | |:-----:|:--------|:-------| 39 | | `Predicate` | `T->boolean` | `IntPredicate,LongPredicate, DoublePredicate` | 40 | | `Consumer` | `T->void` | `IntConsumer,LongConsumer, DoubleConsumer` | 41 | | `Function` | `T->R` | `IntFunction, IntToDoubleFunction,`
`IntToLongFunction, LongFunction,`
`LongToDoubleFunction, LongToIntFunction, `
`DoubleFunction, ToIntFunction, `
`ToDoubleFunction, ToLongFunction` | 42 | | `Supplier` | `()->T` | `BooleanSupplier,IntSupplier, LongSupplier, DoubleSupplier` | 43 | | `UnaryOperator` | `T->T` | `IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator` | 44 | | `BinaryOperator` | `(T,T)->T` | `IntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator` | 45 | | `BiPredicate` | `(L,R)->boolean` | | 46 | | `BiConsumer` | `(T,U)->void` | `ObjIntConsumer, ObjLongConsumer, ObjDoubleConsumer` | 47 | | `BiFunction` | `(T,U)->R` | `ToIntBiFunction, ToLongBiFunction, ToDoubleBiFunction` | 48 | 49 | 50 | ## Lambdas及函数式接口的例子 51 | 52 | | 使用案例 | Lambda 的例子 | 对应的函数式接口 | 53 | |:-----:|:--------|:-------| 54 | | 布尔表达式 | `(List list) -> list.isEmpty()` | `Predicate>` | 55 | | 创建对象 | `() -> new Project()` | `Supplier` | 56 | | 消费一个对象 | `(Project p) -> System.out.println(p.getStars())` | `Consumer` | 57 | | 从一个对象中选择/提取 | `(int a, int b) -> a * b` | `IntBinaryOperator` | 58 | | 比较两个对象 | `(Project p1, Project p2) -> p1.getStars().compareTo(p2.getStars())` | `Comparator 或 BiFunction `Project, Integer> 或 ToIntBiFunction` | 59 | 60 | ## 方法引用 61 | 62 | 方法引用让你可以重复使用现有的方法定义,并像Lambda一样传递它们。 63 | 64 | ## 本节课小结 65 | 66 | - lambda 表达式可以理解为一种匿名函数:它没有名称,但有参数列表、函数主体、返回 类型,可能还有一个可以抛出的异常的列表。 67 | - lambda 表达式让你可以简洁地传递代码。 68 | - 函数式接口就是仅仅声明了一个抽象方法的接口。 69 | - 只有在接受函数式接口的地方才可以使用 lambda 表达式。 70 | - lambda 表达式允许你直接内联,为函数式接口的抽象方法提供实现,并且将整个表达式作为函数式接口的一个实例。 71 | - Java 8自带一些常用的函数式接口,放在 `java.util.function` 包里,包括 `Predicate`、`Function`、`Supplier`、`Consumer` 和 `BinaryOperator`。 72 | - Lambda表达式所需要代表的类型称为目标类型。 73 | - 方法引用让你重复使用现有的方法实现并直接传递它们。 74 | - `Comparator``、`Predicate` 和 `Function` 等函数式接口都有几个可以用来结合 lambda 表达式的默认方法。 -------------------------------------------------------------------------------- /java8-lambda/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-lambda 13 | 14 | 15 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/FilterProjects.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson1; 2 | 3 | import io.github.biezhi.java8.lambda.lesson1.predicate.ProjectLanguagePredicate; 4 | import io.github.biezhi.java8.lambda.lesson1.predicate.ProjectStarPredicate; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Comparator; 8 | import java.util.List; 9 | import java.util.function.Predicate; 10 | 11 | /** 12 | * 过滤 Project 13 | * 14 | * @author biezhi 15 | * @date 2018/2/9 16 | */ 17 | public class FilterProjects { 18 | 19 | /** 20 | * 过滤 Java 项目 21 | * 22 | * @param projects 23 | * @return 24 | */ 25 | public static List filterJavaProjects(List projects) { 26 | List result = new ArrayList<>(); 27 | for (Project project : projects) { 28 | if ("java".equals(project.getLanguage())) { 29 | result.add(project); 30 | } 31 | } 32 | return result; 33 | } 34 | 35 | /** 36 | * 按语言过滤 37 | * 38 | * @param projects 39 | * @param language 40 | * @return 41 | */ 42 | public static List filterLanguageProjects(List projects, String language) { 43 | List result = new ArrayList<>(); 44 | for (Project project : projects) { 45 | if (language.equals(project.getLanguage())) { 46 | result.add(project); 47 | } 48 | } 49 | return result; 50 | } 51 | 52 | /** 53 | * 按语言和 star 数过滤 54 | * 55 | * @param projects 56 | * @param language 57 | * @param stars 58 | * @return 59 | */ 60 | public static List filterLanguageAndStarProjects(List projects, String language, int stars) { 61 | List result = new ArrayList<>(); 62 | for (Project project : projects) { 63 | if (language.equals(project.getLanguage()) && project.getStars() > stars) { 64 | result.add(project); 65 | } 66 | } 67 | return result; 68 | } 69 | 70 | /** 71 | * 按照断言条件过滤 72 | * 73 | * @param projects 74 | * @param projectPredicate 75 | * @return 76 | */ 77 | public static List filterProjects(List projects, ProjectPredicate projectPredicate) { 78 | List result = new ArrayList<>(); 79 | for (Project project : projects) { 80 | if (projectPredicate.test(project)) { 81 | result.add(project); 82 | } 83 | } 84 | return result; 85 | } 86 | 87 | public static List filter(List list, Predicate predicate){ 88 | List result = new ArrayList<>(); 89 | for (T t : list) { 90 | if(predicate.test(t)){ 91 | result.add(t); 92 | } 93 | } 94 | return result; 95 | } 96 | 97 | public static void main(String[] args) { 98 | List data = new ArrayList<>(); 99 | 100 | data.add(Project.builder().name("Blade").language("java").author("biezhi") 101 | .stars(3500).description("Lightning fast and elegant mvc framework for Java8").build()); 102 | 103 | data.add(Project.builder().name("Tale").language("java").author("biezhi") 104 | .stars(2600).description("Best beautiful java blog, worth a try").build()); 105 | 106 | data.add(Project.builder().name("Vue.js").language("js").author("yyx990803") 107 | .stars(83000).description("A progressive, incrementally-adoptable JavaScript framework for building UI on the web.").build()); 108 | 109 | data.add(Project.builder().name("Flask").language("python").author("pallets") 110 | .stars(10500).description("The Python micro framework for building web applications").build()); 111 | 112 | data.add(Project.builder().name("Elves").language("java").author("biezhi") 113 | .stars(200).description("Spider").build()); 114 | 115 | List projects = filterJavaProjects(data); 116 | 117 | projects = filterLanguageProjects(data, "python"); 118 | 119 | projects = filterLanguageAndStarProjects(data, "js", 1000); 120 | 121 | projects = filterProjects(data, new ProjectLanguagePredicate("python")); 122 | 123 | projects = filterProjects(data, new ProjectStarPredicate(1000)); 124 | 125 | System.out.println(projects.size()); 126 | 127 | // JButton jButton = null; 128 | // jButton.addActionListener(e -> System.out.println("按钮被按下了")); 129 | 130 | // 1. 值参数化:啰嗦、死板 131 | // 2. 行为参数化:简洁、灵活 132 | 133 | 134 | List filter = filter(data, project -> project.getStars() > 1000); 135 | 136 | data.sort(Comparator.comparing(Project::getStars)); 137 | 138 | System.out.println(data); 139 | 140 | Runnable task = () -> System.out.println("Hello World"); 141 | 142 | Thread t = new Thread(task); 143 | t.start(); 144 | 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/Project.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson1; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | /** 7 | * 项目 8 | * 9 | * @author biezhi 10 | * @date 2018/2/9 11 | */ 12 | @Data 13 | @Builder 14 | public class Project { 15 | 16 | /** 17 | * 项目名称 18 | */ 19 | private String name; 20 | 21 | /** 22 | * 编程语言 23 | */ 24 | private String language; 25 | 26 | /** 27 | * star 数 28 | */ 29 | private Integer stars; 30 | 31 | /** 32 | * 描述 33 | */ 34 | private String description; 35 | 36 | /** 37 | * 作者 38 | */ 39 | private String author; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/ProjectPredicate.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson1; 2 | 3 | /** 4 | * 项目过滤接口 5 | * 6 | * @author biezhi 7 | * @date 2018/2/9 8 | */ 9 | public interface ProjectPredicate { 10 | 11 | boolean test(Project project); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/predicate/ProjectLanguagePredicate.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson1.predicate; 2 | 3 | import io.github.biezhi.java8.lambda.lesson1.Project; 4 | import io.github.biezhi.java8.lambda.lesson1.ProjectPredicate; 5 | 6 | /** 7 | * 按编程语言过滤 8 | * 9 | * @author biezhi 10 | * @date 2018/2/9 11 | */ 12 | public class ProjectLanguagePredicate implements ProjectPredicate { 13 | 14 | private String language; 15 | 16 | public ProjectLanguagePredicate(String language) { 17 | this.language = language; 18 | } 19 | 20 | @Override 21 | public boolean test(Project project) { 22 | return language.equals(project.getLanguage()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/predicate/ProjectStarPredicate.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson1.predicate; 2 | 3 | import io.github.biezhi.java8.lambda.lesson1.Project; 4 | import io.github.biezhi.java8.lambda.lesson1.ProjectPredicate; 5 | 6 | /** 7 | * 按 star 数过滤 8 | * 9 | * @author biezhi 10 | * @date 2018/2/9 11 | */ 12 | public class ProjectStarPredicate implements ProjectPredicate { 13 | 14 | private Integer stars; 15 | 16 | public ProjectStarPredicate(Integer stars) { 17 | this.stars = stars; 18 | } 19 | 20 | @Override 21 | public boolean test(Project project) { 22 | return project.getStars() > stars; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson2/FunctionalDemo.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson2; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.UUID; 6 | import java.util.function.*; 7 | 8 | /** 9 | * 函数式接口示例 10 | * 11 | * @author biezhi 12 | * @date 2018/2/10 13 | */ 14 | public class FunctionalDemo { 15 | 16 | /** 17 | * 断言 18 | */ 19 | public void predicate() { 20 | Predicate namesStartingWithS = name -> name.startsWith("s"); 21 | boolean hello = namesStartingWithS.test("Hello"); 22 | // false 23 | } 24 | 25 | /** 26 | * 消费数据 27 | */ 28 | public void consumer() { 29 | Consumer messageConsumer = message -> System.out.println(message); 30 | messageConsumer.accept("Learn Java8"); // Learn Java8" 31 | 32 | } 33 | 34 | /** 35 | * 转换 36 | */ 37 | public void function() { 38 | Function toUpperCase = name -> name.toUpperCase(); 39 | toUpperCase.apply("Java"); // Java 40 | } 41 | 42 | /** 43 | * 提供数据 44 | */ 45 | public void supplier() { 46 | Supplier uuidGenerator = () -> UUID.randomUUID().toString(); 47 | System.out.println(uuidGenerator.get()); 48 | 49 | } 50 | 51 | public static void main(String[] args) { 52 | 53 | List list = new ArrayList<>(); 54 | for (int i = 300; i < 400; i++) { 55 | list.add(i); 56 | } 57 | 58 | IntPredicate evenNumbers = (int i) -> i % 2 == 0; 59 | evenNumbers.test(1000); 60 | 61 | Predicate oddNumbers = (Integer i) -> i % 2 == 1; 62 | oddNumbers.test(1000); 63 | 64 | Function add1 = x -> x + 1; 65 | Function concat = x -> x + 1; 66 | 67 | Integer two = add1.apply(1); //yields 2 68 | String answer = concat.apply("0 + 1 = "); // "0 + 1 = 1" 69 | 70 | BinaryOperator sum = (a, b) -> a + b; 71 | Integer res = sum.apply(1, 2); // 3 72 | 73 | BinaryOperator> compose = (f, g) -> x -> g.apply(f.apply(x)); 74 | 75 | UnaryOperator add2 = n -> n + 1; 76 | UnaryOperator concat1 = s -> s + 1; 77 | Function> sum2 = x -> y -> x + y; 78 | UnaryOperator sum10 = sum2.apply(10); 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/ConstructorReference.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson3; 2 | 3 | import java.util.function.Supplier; 4 | 5 | /** 6 | * 构造器引用 7 | *

8 | * 对于一个现有构造函数, 你可以利用它的名称和关键字 new 来创建它的一个引用: ClassName::new。 9 | * 它的功能与指向静态方法的引用类似。 10 | * 11 | * @author biezhi 12 | * @date 2018/2/10 13 | */ 14 | public class ConstructorReference { 15 | 16 | public static void main(String[] args) { 17 | //构造器引用 18 | //根据参数列表自动匹配构造器 19 | Supplier sup = ConstructorReference::new; 20 | ConstructorReference constructorReference = sup.get(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/DoneByYou.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson3; 2 | 3 | import java.util.List; 4 | import java.util.function.BiPredicate; 5 | import java.util.function.Function; 6 | 7 | /** 8 | * 由你完成的 9 | *

10 | * 下列Lambda表达式的等效方法引用是什么 11 | * 12 | * @author biezhi 13 | * @date 2018/2/10 14 | */ 15 | public class DoneByYou { 16 | 17 | public static void main(String[] args) { 18 | Function stringToInteger = (String s) -> Integer.parseInt(s); 19 | BiPredicate, String> contains = (list, element) -> list.contains(element); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/LambdaException.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson3; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.util.function.Function; 6 | 7 | /** 8 | * lambda 中有异常 9 | *

10 | * 任何函数式接口都不允许抛出受检异常 11 | *

12 | * sf上这个问题的一些讨论:https://stackoverflow.com/questions/18198176/java-8-lambda-function-that-throws-exception 13 | * 14 | * @author biezhi 15 | * @date 2018/2/10 16 | */ 17 | public class LambdaException { 18 | 19 | public static void main(String[] args) { 20 | Function f = (BufferedReader b) -> { 21 | try { 22 | return b.readLine(); 23 | } catch (IOException e) { 24 | throw new RuntimeException(e); 25 | } 26 | }; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/Lambdas.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson3; 2 | 3 | import io.github.biezhi.java8.lambda.lesson1.Project; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.function.Function; 8 | import java.util.function.Predicate; 9 | 10 | /** 11 | * lambdas 12 | * 13 | * @author biezhi 14 | * @date 2018/2/10 15 | */ 16 | public class Lambdas { 17 | 18 | public static List buildData() { 19 | List data = new ArrayList<>(); 20 | 21 | data.add(Project.builder().name("Blade").language("java").author("biezhi") 22 | .stars(3500).description("Lightning fast and elegant mvc framework for Java8").build()); 23 | 24 | data.add(Project.builder().name("Tale").language("java").author("biezhi") 25 | .stars(2600).description("Best beautiful java blog, worth a try").build()); 26 | 27 | data.add(Project.builder().name("Vue.js").language("js").author("yyx990803") 28 | .stars(83000).description("A progressive, incrementally-adoptable JavaScript framework for building UI on the web.").build()); 29 | 30 | data.add(Project.builder().name("Flask").language("python").author("pallets") 31 | .stars(10500).description("The Python micro framework for building web applications").build()); 32 | 33 | data.add(Project.builder().name("Elves").language("java").author("biezhi") 34 | .stars(200).description("Spider").build()); 35 | 36 | return data; 37 | } 38 | 39 | public static void main(String[] args) { 40 | List projects = buildData(); 41 | // List names = getNames(projects); 42 | // List names = getNames(projects, project -> project.getStars() > 1000); 43 | List names = getNames(projects, project -> project.getStars() > 1000, project -> project.getDescription()); 44 | List stars = getNames(projects, project -> project.getStars() > 1000, ProjectFunction.buildStarFunction()); 45 | System.out.println(stars); 46 | // names.forEach(name -> System.out.println(name)); 47 | } 48 | 49 | public static List getNames(List projects) { 50 | List names = new ArrayList<>(); 51 | for (Project project : projects) { 52 | names.add(project.getName()); 53 | } 54 | return names; 55 | } 56 | 57 | public static List getNames(List projects, Predicate predicate) { 58 | List names = new ArrayList<>(); 59 | for (Project project : projects) { 60 | if (predicate.test(project)) { 61 | names.add(project.getName()); 62 | } 63 | } 64 | return names; 65 | } 66 | 67 | public static List getNames(List projects, Predicate predicate, Function function) { 68 | List names = new ArrayList<>(); 69 | for (Project project : projects) { 70 | if (predicate.test(project)) { 71 | names.add(function.apply(project)); 72 | } 73 | } 74 | return names; 75 | } 76 | 77 | } 78 | 79 | interface ProjectFunction extends Function { 80 | 81 | static ProjectFunction buildStarFunction() { 82 | return Project::getStars; 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/MethodReference.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson3; 2 | 3 | import io.github.biezhi.java8.lambda.lesson1.Project; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.function.Predicate; 8 | 9 | import static java.util.stream.Collectors.toList; 10 | 11 | /** 12 | * 方法引用 13 | *

14 | * 1. 指向静态方法的方法引用 15 | * 2. 指向现有对象的实例方法的方法引用 16 | * 17 | * @author biezhi 18 | * @date 2018/2/10 19 | */ 20 | public class MethodReference { 21 | 22 | public static List findNumbers(List numbers, Predicate filter) { 23 | List numbersFound = numbers 24 | .stream() 25 | .filter(filter) 26 | .collect(toList()); 27 | 28 | return numbersFound; 29 | } 30 | 31 | public static boolean multipleOf3(Integer number) { 32 | return (number % 3) == 0; 33 | } 34 | 35 | public static void main(String[] args) { 36 | List numbers = Arrays.asList(1, 3, 6, 8, 9, 12, 14, 15); 37 | 38 | List multiplesOf3 = findNumbers(numbers, MethodReference::multipleOf3); 39 | System.out.println(multiplesOf3.contains(3)); 40 | 41 | Project project = Project.builder().name("Blade").build(); 42 | Arrays.asList(project).stream() 43 | .map(Project::getName) 44 | .count(); 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/OtherReference.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.lambda.lesson3; 2 | 3 | import java.util.function.Function; 4 | 5 | /** 6 | * 数组引用 7 | * 8 | * @author biezhi 9 | * @date 2018/2/10 10 | */ 11 | public class OtherReference { 12 | 13 | public static void main(String[] args) { 14 | Function fun = x -> new String[x]; 15 | String[] strs = fun.apply(10); 16 | System.out.println(strs.length); 17 | 18 | Function fun1 = String[]::new; 19 | strs = fun1.apply(20); 20 | System.out.println(strs.length); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /java8-nashorn/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-nashorn 13 | 14 | 15 | -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import javax.script.Invocable; 4 | import javax.script.ScriptEngine; 5 | import javax.script.ScriptEngineManager; 6 | import java.io.FileReader; 7 | import java.time.LocalDateTime; 8 | import java.util.Date; 9 | 10 | /** 11 | * Calling javascript functions from java with nashorn. 12 | * 13 | * @author Benjamin Winterberg 14 | */ 15 | public class Nashorn1 { 16 | 17 | public static void main(String[] args) throws Exception { 18 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 19 | engine.eval(new FileReader("java8-nashorn/src/main/resources/nashorn1.js")); 20 | 21 | Invocable invocable = (Invocable) engine; 22 | Object result = invocable.invokeFunction("fun1", "Peter Parker"); 23 | System.out.println(result); 24 | System.out.println(result.getClass()); 25 | 26 | invocable.invokeFunction("fun2", new Date()); 27 | invocable.invokeFunction("fun2", LocalDateTime.now()); 28 | invocable.invokeFunction("fun2", new Person()); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn10.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import jdk.nashorn.api.scripting.NashornScriptEngine; 4 | 5 | import javax.script.ScriptEngineManager; 6 | import javax.script.ScriptException; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * @author Benjamin Winterberg 11 | */ 12 | public class Nashorn10 { 13 | 14 | public static void main(String[] args) throws ScriptException, NoSuchMethodException { 15 | NashornScriptEngine engine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn"); 16 | engine.eval("load('java8-nashorn/src/main/resources/nashorn10.js')"); 17 | 18 | long t0 = System.nanoTime(); 19 | 20 | for (int i = 0; i < 100000; i++) { 21 | engine.invokeFunction("testPerf"); 22 | } 23 | 24 | long took = System.nanoTime() - t0; 25 | System.out.format("Elapsed time: %d ms", TimeUnit.NANOSECONDS.toMillis(took)); 26 | } 27 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn11.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import jdk.nashorn.api.scripting.NashornScriptEngine; 4 | 5 | import javax.script.Bindings; 6 | import javax.script.ScriptContext; 7 | import javax.script.ScriptEngineManager; 8 | import javax.script.ScriptException; 9 | import javax.script.SimpleBindings; 10 | import javax.script.SimpleScriptContext; 11 | 12 | /** 13 | * @author Benjamin Winterberg 14 | */ 15 | public class Nashorn11 { 16 | 17 | public static void main(String[] args) throws Exception { 18 | // test1(); 19 | // test2(); 20 | // test3(); 21 | // test4(); 22 | // test5(); 23 | // test6(); 24 | // test7(); 25 | test8(); 26 | } 27 | 28 | private static void test8() throws ScriptException { 29 | NashornScriptEngine engine = createEngine(); 30 | 31 | engine.eval("var obj = { foo: 23 };"); 32 | 33 | ScriptContext defaultContext = engine.getContext(); 34 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE); 35 | 36 | SimpleScriptContext context1 = new SimpleScriptContext(); 37 | context1.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE); 38 | 39 | SimpleScriptContext context2 = new SimpleScriptContext(); 40 | context2.getBindings(ScriptContext.ENGINE_SCOPE).put("obj", defaultBindings.get("obj")); 41 | 42 | engine.eval("obj.foo = 44;", context1); 43 | engine.eval("print(obj.foo);", context1); 44 | engine.eval("print(obj.foo);", context2); 45 | } 46 | 47 | private static void test7() throws ScriptException { 48 | NashornScriptEngine engine = createEngine(); 49 | 50 | engine.eval("var foo = 23;"); 51 | 52 | ScriptContext defaultContext = engine.getContext(); 53 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE); 54 | 55 | SimpleScriptContext context1 = new SimpleScriptContext(); 56 | context1.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE); 57 | 58 | SimpleScriptContext context2 = new SimpleScriptContext(); 59 | context2.getBindings(ScriptContext.ENGINE_SCOPE).put("foo", defaultBindings.get("foo")); 60 | 61 | engine.eval("foo = 44;", context1); 62 | engine.eval("print(foo);", context1); 63 | engine.eval("print(foo);", context2); 64 | } 65 | 66 | private static void test6() throws ScriptException { 67 | NashornScriptEngine engine = createEngine(); 68 | 69 | ScriptContext defaultContext = engine.getContext(); 70 | defaultContext.getBindings(ScriptContext.GLOBAL_SCOPE).put("foo", "hello"); 71 | 72 | ScriptContext customContext = new SimpleScriptContext(); 73 | customContext.setBindings(defaultContext.getBindings(ScriptContext.ENGINE_SCOPE), ScriptContext.ENGINE_SCOPE); 74 | 75 | Bindings bindings = new SimpleBindings(); 76 | bindings.put("foo", "world"); 77 | customContext.setBindings(bindings, ScriptContext.GLOBAL_SCOPE); 78 | 79 | // engine.eval("foo = 23;"); // overrides foo in all contexts, why??? 80 | 81 | engine.eval("print(foo)"); // hello 82 | engine.eval("print(foo)", customContext); // world 83 | engine.eval("print(foo)", defaultContext); // hello 84 | } 85 | 86 | private static void test5() throws ScriptException { 87 | NashornScriptEngine engine = createEngine(); 88 | 89 | engine.eval("var obj = { foo: 'foo' };"); 90 | engine.eval("function printFoo() { print(obj.foo) };"); 91 | 92 | ScriptContext defaultContext = engine.getContext(); 93 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE); 94 | 95 | SimpleScriptContext context1 = new SimpleScriptContext(); 96 | context1.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE); 97 | 98 | SimpleScriptContext context2 = new SimpleScriptContext(); 99 | context2.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE); 100 | 101 | engine.eval("obj.foo = 'bar';", context1); 102 | engine.eval("printFoo();", context1); 103 | engine.eval("printFoo();", context2); 104 | } 105 | 106 | private static void test4() throws ScriptException { 107 | NashornScriptEngine engine = createEngine(); 108 | 109 | engine.eval("function foo() { print('bar') };"); 110 | 111 | ScriptContext defaultContext = engine.getContext(); 112 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE); 113 | 114 | SimpleScriptContext context = new SimpleScriptContext(); 115 | context.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE); 116 | 117 | engine.eval("foo();", context); 118 | System.out.println(context.getAttribute("foo")); 119 | } 120 | 121 | private static void test3() throws ScriptException { 122 | NashornScriptEngine engine = createEngine(); 123 | 124 | ScriptContext defaultContext = engine.getContext(); 125 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE); 126 | 127 | SimpleScriptContext context = new SimpleScriptContext(); 128 | context.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE); 129 | 130 | engine.eval("function foo() { print('bar') };", context); 131 | engine.eval("foo();", context); 132 | 133 | Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE); 134 | System.out.println(bindings.get("foo")); 135 | System.out.println(context.getAttribute("foo")); 136 | } 137 | 138 | private static void test2() throws ScriptException { 139 | NashornScriptEngine engine = createEngine(); 140 | engine.eval("function foo() { print('bar') };"); 141 | 142 | SimpleScriptContext context = new SimpleScriptContext(); 143 | engine.eval("print(Function);", context); 144 | engine.eval("foo();", context); 145 | } 146 | 147 | private static void test1() throws ScriptException { 148 | NashornScriptEngine engine = createEngine(); 149 | engine.eval("function foo() { print('bar') };"); 150 | engine.eval("foo();"); 151 | } 152 | 153 | private static NashornScriptEngine createEngine() { 154 | return (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn"); 155 | } 156 | 157 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import jdk.nashorn.api.scripting.ScriptObjectMirror; 4 | 5 | import javax.script.ScriptEngine; 6 | import javax.script.ScriptEngineManager; 7 | import java.io.FileReader; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Calling java methods from javascript with nashorn. 12 | * 13 | * @author Benjamin Winterberg 14 | */ 15 | public class Nashorn2 { 16 | 17 | public static String fun(String name) { 18 | System.out.format("Hi there from Java, %s", name); 19 | return "greetings from java"; 20 | } 21 | 22 | public static void fun2(Object object) { 23 | System.out.println(object.getClass()); 24 | } 25 | 26 | public static void fun3(ScriptObjectMirror mirror) { 27 | System.out.println(mirror.getClassName() + ": " + Arrays.toString(mirror.getOwnKeys(true))); 28 | } 29 | 30 | public static void fun4(ScriptObjectMirror person) { 31 | System.out.println("Full Name is: " + person.callMember("getFullName")); 32 | } 33 | 34 | public static void main(String[] args) throws Exception { 35 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 36 | engine.eval(new FileReader("java8-nashorn/src/main/resources/nashorn2.js")); 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn3.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import javax.script.ScriptEngine; 4 | import javax.script.ScriptEngineManager; 5 | 6 | /** 7 | * Working with java types from javascript. 8 | * 9 | * @author Benjamin Winterberg 10 | */ 11 | public class Nashorn3 { 12 | 13 | public static void main(String[] args) throws Exception { 14 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 15 | engine.eval("load('java8-nashorn/src/main/resources/nashorn3.js')"); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn4.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import javax.script.ScriptEngine; 4 | import javax.script.ScriptEngineManager; 5 | 6 | /** 7 | * Working with java types from javascript. 8 | * 9 | * @author Benjamin Winterberg 10 | */ 11 | public class Nashorn4 { 12 | 13 | public static void main(String[] args) throws Exception { 14 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 15 | engine.eval("loadWithNewGlobal('java8-nashorn/src/main/resources/nashorn4.js')"); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn5.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import javax.script.Invocable; 4 | import javax.script.ScriptEngine; 5 | import javax.script.ScriptEngineManager; 6 | 7 | /** 8 | * Bind java objects to custom javascript objects. 9 | * 10 | * @author Benjamin Winterberg 11 | */ 12 | public class Nashorn5 { 13 | 14 | public static void main(String[] args) throws Exception { 15 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 16 | engine.eval("load('java8-nashorn/src/main/resources/nashorn5.js')"); 17 | 18 | Invocable invocable = (Invocable) engine; 19 | 20 | Product product = new Product(); 21 | product.setName("Rubber"); 22 | product.setPrice(1.99); 23 | product.setStock(1037); 24 | 25 | Object result = invocable.invokeFunction("getValueOfGoods", product); 26 | System.out.println(result); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn6.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import jdk.nashorn.api.scripting.ScriptObjectMirror; 4 | 5 | import javax.script.Invocable; 6 | import javax.script.ScriptEngine; 7 | import javax.script.ScriptEngineManager; 8 | 9 | /** 10 | * Using Backbone Models from Nashorn. 11 | * 12 | * @author Benjamin Winterberg 13 | */ 14 | public class Nashorn6 { 15 | 16 | public static void main(String[] args) throws Exception { 17 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 18 | engine.eval("load('java8-nashorn/src/main/resources/nashorn6.js')"); 19 | 20 | Invocable invocable = (Invocable) engine; 21 | 22 | Product product = new Product(); 23 | product.setName("Rubber"); 24 | product.setPrice(1.99); 25 | product.setStock(1337); 26 | 27 | ScriptObjectMirror result = (ScriptObjectMirror) 28 | invocable.invokeFunction("calculate", product); 29 | System.out.println(result.get("name") + ": " + result.get("valueOfGoods")); 30 | } 31 | 32 | public static void getProduct(ScriptObjectMirror result) { 33 | System.out.println(result.get("name") + ": " + result.get("valueOfGoods")); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn7.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import javax.script.Invocable; 4 | import javax.script.ScriptEngine; 5 | import javax.script.ScriptEngineManager; 6 | import javax.script.ScriptException; 7 | 8 | /** 9 | * @author Benjamin Winterberg 10 | */ 11 | public class Nashorn7 { 12 | 13 | public static class Person { 14 | private String name; 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | 24 | public int getLengthOfName() { 25 | return name.length(); 26 | } 27 | } 28 | 29 | public static void main(String[] args) throws ScriptException, NoSuchMethodException { 30 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 31 | engine.eval("function foo(predicate, obj) { return !!(eval(predicate)); };"); 32 | 33 | Invocable invocable = (Invocable) engine; 34 | 35 | Person person = new Person(); 36 | person.setName("Hans"); 37 | 38 | String predicate = "obj.getLengthOfName() >= 4"; 39 | Object result = invocable.invokeFunction("foo", predicate, person); 40 | System.out.println(result); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn8.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import jdk.nashorn.api.scripting.NashornScriptEngine; 4 | 5 | import javax.script.ScriptEngineManager; 6 | import javax.script.ScriptException; 7 | 8 | /** 9 | * @author Benjamin Winterberg 10 | */ 11 | public class Nashorn8 { 12 | public static void main(String[] args) throws ScriptException, NoSuchMethodException { 13 | NashornScriptEngine engine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn"); 14 | engine.eval("load('java8-nashorn/src/main/resources/nashorn8.js')"); 15 | 16 | engine.invokeFunction("evaluate1"); // [object global] 17 | engine.invokeFunction("evaluate2"); // [object Object] 18 | engine.invokeFunction("evaluate3", "Foobar"); // Foobar 19 | engine.invokeFunction("evaluate3", new Person("John", "Doe")); // [object global] <- ??????? 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn9.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import jdk.nashorn.api.scripting.NashornScriptEngine; 4 | 5 | import javax.script.ScriptEngineManager; 6 | import javax.script.ScriptException; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * @author Benjamin Winterberg 11 | */ 12 | public class Nashorn9 { 13 | 14 | public static void main(String[] args) throws ScriptException, NoSuchMethodException { 15 | NashornScriptEngine engine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn"); 16 | engine.eval("load('java8-nashorn/src/main/resources/nashorn9.js')"); 17 | 18 | long t0 = System.nanoTime(); 19 | 20 | double result = 0; 21 | for (int i = 0; i < 1000; i++) { 22 | double num = (double) engine.invokeFunction("testPerf"); 23 | result += num; 24 | } 25 | 26 | System.out.println(result > 0); 27 | 28 | long took = System.nanoTime() - t0; 29 | System.out.format("Elapsed time: %d ms", TimeUnit.NANOSECONDS.toMillis(took)); 30 | } 31 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Person.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | /** 4 | * @author Benjamin Winterberg 5 | */ 6 | public class Person { 7 | public String firstName; 8 | public String lastName; 9 | 10 | public Person() {} 11 | 12 | public Person(String firstName, String lastName) { 13 | this.firstName = firstName; 14 | this.lastName = lastName; 15 | } 16 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Product.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class Product { 7 | private String name; 8 | private double price; 9 | private int stock; 10 | private double valueOfGoods; 11 | 12 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/SuperRunner.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.nashorn; 2 | 3 | public class SuperRunner implements Runnable { 4 | 5 | @Override 6 | public void run() { 7 | System.out.println("super run"); 8 | } 9 | 10 | } -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn1.js: -------------------------------------------------------------------------------- 1 | var fun1 = function(name) { 2 | print('Hi there from Javascript, ' + name); 3 | return "greetings from javascript"; 4 | }; 5 | 6 | var fun2 = function (object) { 7 | print("JS Class Definition: " + Object.prototype.toString.call(object)); 8 | }; -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn10.js: -------------------------------------------------------------------------------- 1 | var results = []; 2 | 3 | var Context = function () { 4 | this.foo = 'bar'; 5 | }; 6 | 7 | Context.prototype.testArgs = function () { 8 | if (arguments[0]) { 9 | results.push(true); 10 | } 11 | if (arguments[1]) { 12 | results.push(true); 13 | } 14 | if (arguments[2]) { 15 | results.push(true); 16 | } 17 | if (arguments[3]) { 18 | results.push(true); 19 | } 20 | }; 21 | 22 | var testPerf = function () { 23 | var context = new Context(); 24 | context.testArgs(); 25 | context.testArgs(1); 26 | context.testArgs(1, 2); 27 | context.testArgs(1, 2, 3); 28 | context.testArgs(1, 2, 3, 4); 29 | }; -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn2.js: -------------------------------------------------------------------------------- 1 | var Nashorn2 = Java.type('io.github.biezhi.java8.nashorn.Nashorn2'); 2 | var result = Nashorn2.fun('John Doe'); 3 | print('\n' + result); 4 | 5 | Nashorn2.fun2(123); 6 | Nashorn2.fun2(49.99); 7 | Nashorn2.fun2(true); 8 | Nashorn2.fun2("hi there") 9 | Nashorn2.fun2(String("bam")) 10 | Nashorn2.fun2(new Number(23)); 11 | Nashorn2.fun2(new Date()); 12 | Nashorn2.fun2(new RegExp()); 13 | Nashorn2.fun2({foo: 'bar'}); 14 | 15 | 16 | print('passing object hash:'); 17 | Nashorn2.fun3({ 18 | foo: 'bar', 19 | bar: 'foo' 20 | }); 21 | 22 | 23 | print('passing custom person object:'); 24 | 25 | function Person(firstName, lastName) { 26 | this.firstName = firstName; 27 | this.lastName = lastName; 28 | this.getFullName = function() { 29 | return this.firstName + " " + this.lastName; 30 | } 31 | } 32 | 33 | var person1 = new Person("Peter", "Parker"); 34 | Nashorn2.fun3(person1); 35 | Nashorn2.fun4(person1); -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn3.js: -------------------------------------------------------------------------------- 1 | print('------------------'); 2 | print('IntArray:'); 3 | 4 | var IntArray = Java.type('int[]'); 5 | 6 | var array = new IntArray(5); 7 | array[0] = 5; 8 | array[1] = 4; 9 | array[2] = 3; 10 | array[3] = 2; 11 | array[4] = 1; 12 | 13 | try { 14 | array[5] = 23; 15 | } catch (e) { 16 | print(e.message); 17 | } 18 | 19 | array[0] = "17"; 20 | print(array[0]); 21 | 22 | array[0] = "wrong type"; 23 | print(array[0]); 24 | 25 | array[0] = "17.3"; 26 | print(array[0]); 27 | 28 | print('------------------'); 29 | 30 | for (var i in array) print(i); 31 | 32 | print('------------------'); 33 | 34 | for each (var val in array) print(val); 35 | 36 | print('------------------'); 37 | print('ArrayList:'); 38 | 39 | var ArrayList = Java.type('java.util.ArrayList'); 40 | 41 | var list = new ArrayList(); 42 | list.add('a'); 43 | list.add('b'); 44 | list.add('c'); 45 | 46 | for each (var el in list) print(el); 47 | 48 | 49 | print('------------------'); 50 | print('HashMap:'); 51 | 52 | var HashMap = Java.type('java.util.HashMap'); 53 | 54 | var map = new HashMap(); 55 | map.put('foo', 'foo1'); 56 | map.put('bar', 'bar1'); 57 | 58 | for each(var e in map.keySet()) print(e); 59 | 60 | for each(var e in map.values()) print(e); 61 | 62 | 63 | print('------------------'); 64 | print('Streams:'); 65 | 66 | var list2 = new ArrayList(); 67 | list2.add("ddd2"); 68 | list2.add("aaa2"); 69 | list2.add("bbb1"); 70 | list2.add("aaa1"); 71 | list2.add("bbb3"); 72 | list2.add("ccc"); 73 | list2.add("bbb2"); 74 | list2.add("ddd1"); 75 | 76 | list2 77 | .stream() 78 | .filter(function(el) { 79 | return el.startsWith("aaa"); 80 | }) 81 | .sorted() 82 | .forEach(function(el) { 83 | print(el); 84 | }); 85 | 86 | 87 | 88 | print('------------------'); 89 | print('Extend:'); 90 | 91 | var Runnable = Java.type('java.lang.Runnable'); 92 | var Printer = Java.extend(Runnable, { 93 | run: function() { 94 | print('This was printed from a seperate thread.'); 95 | } 96 | }); 97 | 98 | var Thread = Java.type('java.lang.Thread'); 99 | new Thread(new Printer()).start(); 100 | 101 | new Thread(function() { 102 | print('this was printed from another thread'); 103 | }).start(); 104 | 105 | 106 | print('------------------'); 107 | print('Parameter Overload:'); 108 | 109 | var System = Java.type('java.lang.System'); 110 | 111 | System.out.println(10); 112 | System.out["println"](11.0); 113 | System.out["println(double)"](12); 114 | 115 | print('------------------'); 116 | print('JavaBeans:'); 117 | 118 | var Date = Java.type('java.util.Date'); 119 | var date = new Date(); 120 | date.year += 1900; 121 | System.out.println(date.year); -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn4.js: -------------------------------------------------------------------------------- 1 | // function literal with no braces 2 | 3 | function sqr(x) x * x; 4 | 5 | print(sqr(3)); 6 | 7 | 8 | // for each 9 | 10 | var array = [1, 2, 3, 4]; 11 | for each (var num in array) print(num); 12 | 13 | 14 | // object literals in constructors 15 | 16 | var runnable = new java.lang.Runnable() { 17 | run: function() { 18 | print('on the run'); 19 | } 20 | }; 21 | 22 | runnable.run(); 23 | 24 | 25 | // bind properties 26 | 27 | var o1 = {}; 28 | var o2 = { foo: 'bar'}; 29 | 30 | Object.bindProperties(o1, o2); 31 | 32 | print(o1.foo); 33 | o1.foo = 'BAM'; 34 | print(o2.foo); 35 | 36 | 37 | // string trim 38 | 39 | print(" hehe".trimLeft()); 40 | print("hehe ".trimRight() + "he"); 41 | 42 | 43 | // whereis 44 | print(__FILE__, __LINE__, __DIR__); 45 | 46 | 47 | // java import 48 | 49 | var imports = new JavaImporter(java.io, java.lang); 50 | with (imports) { 51 | var file = new File(__FILE__); 52 | System.out.println(file.getAbsolutePath()); 53 | // /path/to/my/script.js 54 | } 55 | 56 | 57 | // convert iterable to js array 58 | 59 | var list = new java.util.ArrayList(); 60 | list.add("s1"); 61 | list.add("s2"); 62 | list.add("s3"); 63 | 64 | var jsArray = Java.from(list); 65 | print(jsArray); 66 | print(Object.prototype.toString.call(jsArray)); 67 | 68 | 69 | // convert js array to java array 70 | 71 | var javaArray = Java.to([3, 5, 7, 11], "int[]"); 72 | print(Object.prototype.toString.call(javaArray)); 73 | 74 | 75 | // calling super 76 | 77 | var SuperRunner = Java.type('io.github.biezhi.java8.nashorn.SuperRunner'); 78 | var Runner = Java.extend(SuperRunner); 79 | 80 | var runner = new Runner() { 81 | run: function() { 82 | Java.super(runner).run(); 83 | print('on my run'); 84 | } 85 | } 86 | runner.run(); 87 | 88 | 89 | 90 | // load 91 | 92 | load('http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js'); 93 | 94 | var odds = _.filter([1, 2, 3, 4, 5, 6], function (num) { 95 | return num % 2 == 1; 96 | }); 97 | 98 | print(odds); -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn5.js: -------------------------------------------------------------------------------- 1 | function Product(name) { 2 | this.name = name; 3 | } 4 | 5 | Product.prototype.stock = 0; 6 | Product.prototype.price = 0; 7 | Product.prototype.getValueOfGoods = function() { 8 | return this.stock * this.price; 9 | }; 10 | 11 | var product = new Product('Pencil'); 12 | product.price = 4.99; 13 | product.stock = 78; 14 | 15 | print('Value of Goods: ' + product.getValueOfGoods()); 16 | 17 | 18 | var getValueOfGoods = function(javaProduct) { 19 | var jsProduct = new Product(); 20 | Object.bindProperties(jsProduct, javaProduct); 21 | return jsProduct.getValueOfGoods(); 22 | }; -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn6.js: -------------------------------------------------------------------------------- 1 | load('http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js'); 2 | load('http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js'); 3 | 4 | 5 | // simple backbone model: 6 | // valueOfGoods will automatically be calculated when stock or price changes 7 | var Product = Backbone.Model.extend({ 8 | defaults: { 9 | stock: 0, 10 | price: 0.0, 11 | name:'', 12 | valueOfGoods: 0.0 13 | }, 14 | 15 | initialize: function() { 16 | this.on('change:stock change:price', function() { 17 | var stock = this.get('stock'); 18 | var price = this.get('price'); 19 | var valueOfGoods = this.getValueOfGoods(stock, price); 20 | this.set('valueOfGoods', valueOfGoods); 21 | }); 22 | }, 23 | 24 | getValueOfGoods: function(stock, price) { 25 | return stock * price; 26 | } 27 | }); 28 | 29 | var product = new Product(); 30 | product.set('name', 'Pencil'); 31 | product.set('stock', 1000); 32 | product.set('price', 3.99); 33 | 34 | 35 | // pass backbone model to java method 36 | var Nashorn6 = Java.type('io.github.biezhi.java8.nashorn.Nashorn6'); 37 | Nashorn6.getProduct(product.attributes); 38 | 39 | 40 | // bind java object to backbone model and pass result back to java 41 | var calculate = function(javaProduct) { 42 | var model = new Product(); 43 | model.set('name', javaProduct.name); 44 | model.set('price', javaProduct.price); 45 | model.set('stock', javaProduct.stock); 46 | return model.attributes; 47 | }; -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn7.js: -------------------------------------------------------------------------------- 1 | function sqrt(x) x * x 2 | print(sqrt(3)); 3 | 4 | var array = [1, 2, 3, 4]; 5 | for each (var num in array) print(num); 6 | 7 | var runnable = new java.lang.Runnable() { 8 | run: function () { 9 | print('on the run'); 10 | } 11 | }; 12 | 13 | runnable.run(); 14 | 15 | var System = Java.type('java.lang.System'); 16 | System.out["println(double)"](12); 17 | 18 | var Arrays = Java.type("java.util.Arrays"); 19 | var javaArray = Java.to([2, 3, 7, 11, 14], "int[]"); 20 | 21 | Arrays.stream(javaArray) 22 | .filter(function (num) { 23 | return num % 2 === 1; 24 | }) 25 | .forEach(function (num) { 26 | print(num); 27 | }); -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn8.js: -------------------------------------------------------------------------------- 1 | var evaluate1 = function () { 2 | (function () { 3 | print(eval("this")); 4 | }).call(this); 5 | }; 6 | 7 | var evaluate2 = function () { 8 | var context = {}; 9 | (function () { 10 | print(eval("this")); 11 | }).call(context); 12 | }; 13 | 14 | var evaluate3 = function (context) { 15 | (function () { 16 | print(eval("this")); 17 | }).call(context); 18 | }; -------------------------------------------------------------------------------- /java8-nashorn/src/main/resources/nashorn9.js: -------------------------------------------------------------------------------- 1 | var size = 100000; 2 | 3 | var testPerf = function () { 4 | var result = Math.floor(Math.random() * size) + 1; 5 | for (var i = 0; i < size; i++) { 6 | result += i; 7 | } 8 | return result; 9 | }; -------------------------------------------------------------------------------- /java8-optional/README.md: -------------------------------------------------------------------------------- 1 | # Optional 2 | 3 | ## Optional类的方法 4 | 5 | | 方法 | 描述 | 6 | |:-----:|:-------| 7 | | `empty` | 返回一个空的 Optional 实例 | 8 | | `filter` | 如果值存在并且满足提供的断言, 就返回包含该值的 Optional 对象;否则返回一个空的 Optional 对象 | 9 | | `map` | 如果值存在,就对该值执行提供的 mapping 函数调用 | 10 | | `flatMap` | 如果值存在,就对该值执行提供的 mapping 函数调用,返回一个 Optional 类型的值,否则就返 回一个空的 Optional 对象 | 11 | | `get` | 如果该值存在,将该值用 Optional 封装返回,否则抛出一个 NoSuchElementException 异常 | 12 | | `ifPresent` | 如果值存在,就执行使用该值的方法调用,否则什么也不做 | 13 | | `isPresent` | 如果值存在就返回 true,否则返回 false | 14 | | `of` | 将指定值用 Optional 封装之后返回,如果该值为 null,则抛出一个 NullPointerException 异常 | 15 | | `ofNullable` | 将指定值用 Optional 封装之后返回,如果该值为 null,则返回一个空的 Optional 对象 | 16 | | `orElse` | 如果有值则将其返回,否则返回一个默认值 | 17 | | `orElseGet` | 如果有值则将其返回,否则返回一个由指定的 Supplier 接口生成的值 | 18 | | `orElseThrow` | 如果有值则将其返回,否则抛出一个由指定的 Supplier 接口生成的异常 | 19 | -------------------------------------------------------------------------------- /java8-optional/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-optional 13 | 14 | 15 | -------------------------------------------------------------------------------- /java8-optional/src/main/java/io/github/biezhi/java8/optional/Address.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.optional; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * 住址对象 10 | * 11 | * @author biezhi 12 | * @date 2018/2/11 13 | */ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class Address { 18 | 19 | /** 20 | * 街道 21 | */ 22 | private String street; 23 | 24 | /** 25 | * 门牌 26 | */ 27 | private String door; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java8-optional/src/main/java/io/github/biezhi/java8/optional/BeforeJava8.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.optional; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/2/11 6 | */ 7 | public class BeforeJava8 { 8 | 9 | /** 10 | * Java 8 之前 11 | * 12 | * @param user 13 | */ 14 | public void saveUser(User user) { 15 | if (null != user) { 16 | if (null != user.getAddress()) { 17 | // 保存 user 18 | } 19 | } 20 | } 21 | 22 | /** 23 | * 过多的退出语句 24 | * 25 | * @param user 26 | */ 27 | public void saveUser2(User user) { 28 | if (null == user) { 29 | return; 30 | } 31 | if (null == user.getAddress()) { 32 | return; 33 | } 34 | // 保存 user 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /java8-optional/src/main/java/io/github/biezhi/java8/optional/OptionalDemo.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.optional; 2 | 3 | import java.util.Optional; 4 | import java.util.Properties; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2018/2/11 9 | */ 10 | public class OptionalDemo { 11 | 12 | /** 13 | * 1. 创建 Optional 14 | */ 15 | public void createOptional() { 16 | // 声明一个空的Optional 17 | Optional

optionalAddress = Optional.empty(); 18 | 19 | // 依据一个非空值创建Optional 20 | Optional
optionalAddress2 = Optional.of(new Address()); 21 | 22 | // 可接受null的Optional 23 | Optional
optionalAddress3 = Optional.ofNullable(new Address()); 24 | } 25 | 26 | /** 27 | * 2. 使用 map 从 Optional 对象中提取和转换值 28 | */ 29 | public void map() { 30 | Optional
addressOptional = Optional.ofNullable(new Address("达尔文路", "88号")); 31 | Optional street = addressOptional.map(Address::getStreet); 32 | } 33 | 34 | /** 35 | * 3. 使用 flatMap 链接 Optional 对象 36 | */ 37 | public void flatMap() { 38 | User user = new User(); 39 | Optional userOptional = Optional.of(user); 40 | // userOptional.map(user -> user.getOptAddress()) 41 | Optional stringOptional = userOptional.flatMap(User::getOptAddress).map(Address::getStreet); 42 | 43 | } 44 | 45 | /** 46 | * 4. 默认行为及解引用 Optional 对象 47 | */ 48 | public void defaultValue() { 49 | Optional
addressOptional = Optional.ofNullable(null); 50 | String street = addressOptional.map(Address::getStreet).orElse("北京二环"); 51 | System.out.println(street); 52 | } 53 | 54 | public static void main(String[] args) { 55 | User user = new User(); 56 | user.setUsername("biezhi"); 57 | user.setPassword("123456"); 58 | user.setOptAddress(Optional.of(new Address("达尔文路", "88号"))); 59 | user.setAge(30); 60 | 61 | // Address address1 = null; 62 | // try { 63 | // address1 = user.getOptAddress().filter(address -> address.getDoor().contains("878")) 64 | // .orElseThrow(new Supplier() { 65 | // @Override 66 | // public Throwable get() { 67 | // return new Exception("挂了"); 68 | // } 69 | // }); 70 | // } catch (Throwable throwable) { 71 | // throwable.printStackTrace(); 72 | // } 73 | // System.out.println(address1); 74 | 75 | System.out.println(getStreet(Optional.of(user), 50)); 76 | } 77 | 78 | public static String getStreet(Optional user, int minAge) { 79 | return user.filter(u -> u.getAge() >= minAge) 80 | .flatMap(User::getOptAddress) 81 | .map(Address::getStreet) 82 | .orElse("没有"); 83 | } 84 | 85 | public static Optional parseInt(String value) { 86 | try { 87 | return Optional.ofNullable(Integer.parseInt(value)); 88 | } catch (Exception e) { 89 | return Optional.empty(); 90 | } 91 | } 92 | 93 | public int readPoint(Properties props, String name) { 94 | return Optional.ofNullable(props.getProperty(name)) 95 | .flatMap(OptionalDemo::parseInt) 96 | .filter(i -> i > 0) 97 | .orElse(0); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /java8-optional/src/main/java/io/github/biezhi/java8/optional/User.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.optional; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Optional; 6 | 7 | /** 8 | * User 9 | * 10 | * @author biezhi 11 | * @date 2018/2/11 12 | */ 13 | @Data 14 | public class User { 15 | 16 | private String username; 17 | private String password; 18 | private Integer age; 19 | private Address address; 20 | 21 | private Optional
optAddress; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /java8-proper/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-proper 13 | 14 | 15 | -------------------------------------------------------------------------------- /java8-stream/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | learn-java8 7 | io.github.biezhi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | java8-stream 13 | 14 | 15 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/Project.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * 项目 11 | * 12 | * @author biezhi 13 | * @date 2018/2/9 14 | */ 15 | @Data 16 | @Builder 17 | public class Project { 18 | 19 | /** 20 | * 项目名称 21 | */ 22 | private String name; 23 | 24 | /** 25 | * 编程语言 26 | */ 27 | private String language; 28 | 29 | /** 30 | * star 数 31 | */ 32 | private Integer stars; 33 | 34 | /** 35 | * 描述 36 | */ 37 | private String description; 38 | 39 | /** 40 | * 作者 41 | */ 42 | private String author; 43 | 44 | /** 45 | * fork数 46 | */ 47 | private Integer forks; 48 | 49 | public static List buildData(){ 50 | List data = new ArrayList<>(); 51 | 52 | data.add(Project.builder().name("Blade").language("java").author("biezhi") 53 | .stars(3500).forks(2000).description("Lightning fast and elegant mvc framework for Java8").build()); 54 | 55 | data.add(Project.builder().name("Tale").language("javascript").author("biezhi") 56 | .stars(2600).forks(2300).description("Best beautiful java blog, worth a try").build()); 57 | 58 | data.add(Project.builder().name("Vue.js").language("js").author("yyx990803") 59 | .stars(83000).forks(10322).description("A progressive, incrementally-adoptable JavaScript framework for building UI on the web.").build()); 60 | 61 | data.add(Project.builder().name("Flask").language("python").author("pallets") 62 | .stars(10500).forks(3000).description("The Python micro framework for building web applications").build()); 63 | 64 | data.add(Project.builder().name("Elves").language("java").author("biezhi") 65 | .stars(200).forks(100).description("Spider").build()); 66 | 67 | return data; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson1/Java7.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson1; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.Comparator; 8 | import java.util.List; 9 | 10 | /** 11 | * @author biezhi 12 | * @date 2018/2/11 13 | */ 14 | public class Java7 { 15 | 16 | public static void main(String[] args) { 17 | List result = new ArrayList<>(); 18 | 19 | List projects = new ArrayList<>(); 20 | for (Project project : projects) { 21 | if(project.getStars() > 1000){ 22 | result.add(project); 23 | } 24 | } 25 | Collections.sort(projects, new Comparator() { 26 | @Override 27 | public int compare(Project o1, Project o2) { 28 | return o1.getStars().compareTo(o2.getStars()); 29 | } 30 | }); 31 | 32 | List names = new ArrayList<>(); 33 | 34 | for (Project project : projects) { 35 | names.add(project.getName()); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson1/Java8.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson1; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | /** 9 | * @author biezhi 10 | * @date 2018/2/11 11 | */ 12 | public class Java8 { 13 | 14 | public static void main(String[] args) { 15 | List projects = Project.buildData(); 16 | List names = projects.stream() 17 | .filter(p -> { 18 | System.out.println(p.getName()); 19 | return p.getStars() > 1000; 20 | }) 21 | .map(p -> { 22 | System.out.println(p.getName()); 23 | return p.getName(); 24 | }) 25 | .limit(3) 26 | .collect(Collectors.toList()); 27 | System.out.println(names); 28 | 29 | names.stream().forEach(name-> System.out.println(name)); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Stream; 6 | 7 | /** 8 | * 创建流 9 | *

10 | * Stream.of 11 | * Arrays.stream 12 | * collection.stream 13 | * Files.lines 14 | * Stream.iterate 15 | * 16 | * @author biezhi 17 | * @date 2018/2/12 18 | */ 19 | public class Example1 { 20 | 21 | public static void main(String[] args) { 22 | List list = Arrays.asList("hello", "world"); 23 | Stream stream = list.stream(); 24 | 25 | Stream stringStream = Arrays.stream(new String[]{"hello", "world"}); 26 | 27 | Stream stream1 = Stream.of("hello", "world"); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | /** 10 | * 筛选元素 11 | * 12 | * filter 使用 13 | * distinct 使用 14 | * limit 使用 15 | * skip 使用 16 | * 17 | * @author biezhi 18 | * @date 2018/2/12 19 | */ 20 | public class Example2 { 21 | 22 | public static void main(String[] args) { 23 | List projects = Project.buildData(); 24 | 25 | List collect = projects.stream() 26 | .filter(project -> project.getStars() > 1000) 27 | .collect(Collectors.toList()); 28 | 29 | // distinct 30 | Stream numbers = Stream.of(1, 2, 3, 3, 2, 4); 31 | numbers.distinct().limit(3).forEach(n -> System.out.println(n)); 32 | 33 | System.out.println("==================="); 34 | Stream.of(1, 2, 3, 3, 2, 4).skip(4).forEach(n -> System.out.println(n)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example3.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * 映射 9 | *

10 | * map 使用 11 | * 12 | * @author biezhi 13 | * @date 2018/2/12 14 | */ 15 | public class Example3 { 16 | 17 | public static void main(String[] args) { 18 | List words = Arrays.asList("Java 8", "Lambdas", "In", "Action"); 19 | 20 | words.stream() 21 | .map(word -> word.length()) 22 | .collect(Collectors.toList()) 23 | .forEach(i -> System.out.println(i)); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example4.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * 扁平流 flatMap 9 | *

10 | * 列出List中各不相同的单词 11 | *

12 | * 13 | * @author biezhi 14 | * @date 2018/2/12 15 | */ 16 | public class Example4 { 17 | 18 | public static void main(String[] args) { 19 | List list = Arrays.asList("I am a boy", "I love the girl", "But the girl loves another girl"); 20 | 21 | list.stream() 22 | .map(word -> word.split(" ")) // Stream 23 | .flatMap(Arrays::stream) 24 | .distinct() 25 | .collect(Collectors.toList()); 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example5.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 匹配元素 9 | *

10 | * allMatch 使用 11 | * anyMatch 使用 12 | * noneMatch 使用 13 | * findFirst 使用 14 | * findAny 使用 15 | * 16 | * @author biezhi 17 | * @date 2018/2/12 18 | */ 19 | public class Example5 { 20 | 21 | public static void main(String[] args) { 22 | List projects = Project.buildData(); 23 | 24 | boolean hasBiezhi = projects.stream() 25 | .anyMatch(p -> p.getAuthor().equals("biezhi")); 26 | 27 | System.out.println(hasBiezhi); 28 | 29 | System.out.println(projects.stream() 30 | .allMatch(p -> p.getAuthor().equals("biezhi"))); 31 | 32 | System.out.println(projects.stream() 33 | .noneMatch(p -> p.getAuthor().equals("biezhi"))); 34 | 35 | System.out.println(projects.stream().findAny().get()); 36 | System.out.println(projects.stream().findFirst().get()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example6.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | /** 9 | * 归约(reduce) 10 | *

11 | * 1.元素求和 12 | * 2. 13 | * 14 | * @author biezhi 15 | * @date 2018/2/12 16 | */ 17 | public class Example6 { 18 | 19 | public static void main(String[] args) { 20 | List projects = Project.buildData(); 21 | List numbers = Arrays.asList(2, 4, 5, 6); 22 | 23 | int sum = 0; 24 | for (int x : numbers) { 25 | sum += x; 26 | } 27 | 28 | System.out.println(sum); 29 | 30 | Integer reduce = numbers.stream() 31 | .reduce(0, (a, b) -> a + b); 32 | System.out.println(reduce); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example7.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.List; 6 | import java.util.OptionalInt; 7 | 8 | /** 9 | * 数值流 10 | *

11 | * IntStream、DoubleStream、LongStream 12 | * 13 | * @author biezhi 14 | * @date 2018/2/12 15 | */ 16 | public class Example7 { 17 | 18 | public static void main(String[] args) { 19 | List projects = Project.buildData(); 20 | OptionalInt max = projects.stream() 21 | .mapToInt(p -> p.getStars()) 22 | .max(); 23 | System.out.println(max.getAsInt()); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Quiz1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import lombok.AllArgsConstructor; 4 | 5 | import java.util.stream.Stream; 6 | 7 | /** 8 | * 3. 斐波纳契元组序列 9 | *

10 | * 斐波纳契数列是著名的经典编程练习。 11 | * 下面这个数列就是斐波纳契数列的一部分: 12 | * 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55…数列中开始的两个数字是 0 和 1,后续的每个数字都是前两个数字之和。 13 | *

14 | * 斐波纳契元组序列与此类似,是数列中数字和其后续数字组成的元组构成的序列: 15 | * (0, 1), (1, 1), (1, 2), (2, 3), (3, 5), (5, 8), (8, 13), (13, 21) … 16 | * 你的任务是用iterate方法生成斐波纳契元组序列中的前20个元素。 17 | * 18 | * @author biezhi 19 | * @date 2018/2/12 20 | */ 21 | public class Quiz1 { 22 | 23 | @AllArgsConstructor 24 | static class Tuple{ 25 | int first; 26 | int second; 27 | } 28 | 29 | public static void main(String[] args) { 30 | // tuple = (0, 1) 31 | // next [0] = prev tuple [1] 32 | // next [1] = prev (tuple [0] + tuple[1]) 33 | Stream.iterate(new Tuple(0, 1), tuple -> new Tuple(tuple.second, tuple.first + tuple.second)) 34 | .limit(20) 35 | .forEach(tuple -> System.out.println("("+ tuple.first +","+ tuple.second +")")); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Quiz2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | 9 | /** 10 | * 1. 你将如何利用流来筛选前两个Java项目呢? 11 | *

12 | * 13 | * @author biezhi 14 | * @date 2018/2/12 15 | */ 16 | public class Quiz2 { 17 | 18 | public static void main(String[] args) { 19 | List projects = Project.buildData(); 20 | 21 | System.out.println(projects.stream().map(Project::getName).limit(2).collect(Collectors.toList())); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Quiz3.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * 2. 9 | *

10 | * 2.1 给定一个数字列表,如何返回一个由每个数的平方构成的列表呢? 11 | * 例如,给定[1, 2, 3, 4, 5],应该返回[1, 4, 9, 16, 25] 12 | *

13 | * 2.2 给定两个数字列表,如何返回所有的数对呢?例如,给定列表[1, 2, 3]和列表[3, 4], 14 | * 应该返回[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]。 15 | * 为简单起见,你可以用有两个元素的数组来代表数对。 16 | *

17 | * 2.3 如何扩展前一个例子,只返回总和能被3整除的数对呢?例如(2, 4)和(3, 3)是可以的。 18 | * 19 | * @author biezhi 20 | * @date 2018/2/12 21 | */ 22 | public class Quiz3 { 23 | 24 | private static void q1() { 25 | List numbers = Arrays.asList(1, 2, 3, 4, 5); 26 | 27 | numbers.stream() 28 | .map(n -> n * n) 29 | .forEach(n -> System.out.println(n)); 30 | } 31 | 32 | private static void q2() { 33 | List numbers1 = Arrays.asList(1, 2, 3); 34 | List numbers2 = Arrays.asList(3, 4); 35 | 36 | List pairs = numbers1.stream() 37 | .flatMap(i -> numbers2.stream().map(j -> new int[]{i, j})) 38 | .collect(Collectors.toList()); 39 | pairs.forEach(pair -> System.out.println(Arrays.toString(pair))); 40 | } 41 | 42 | private static void q3() { 43 | List numbers1 = Arrays.asList(1, 2, 3); 44 | List numbers2 = Arrays.asList(3, 4); 45 | 46 | List pairs = numbers1.stream() 47 | .flatMap(i -> numbers2.stream().filter(j -> (i + j) % 3 == 0).map(j -> new int[]{i, j})) 48 | .collect(Collectors.toList()); 49 | pairs.forEach(pair -> System.out.println(Arrays.toString(pair))); 50 | } 51 | 52 | public static void main(String[] args) { 53 | // q1(); 54 | // q2(); 55 | q3(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Quiz4.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 4. 请使用reduce计算 biezhi 的项目有多少 star 9 | * 10 | * @author biezhi 11 | * @date 2018/2/12 12 | */ 13 | public class Quiz4 { 14 | 15 | public static void main(String[] args) { 16 | 17 | List projects = Project.buildData(); 18 | Integer biezhi = projects.stream() 19 | .filter(p -> p.getAuthor().equals("biezhi")) 20 | .map(p -> p.getStars()) 21 | .reduce(0, Integer::sum); 22 | System.out.println(biezhi); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/QuizEnd.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson2; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | import java.util.Arrays; 7 | import java.util.Comparator; 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | /** 12 | * (1) 找出2011年发生的所有交易,并按交易额排序(从低到高)。 13 | * (2) 交易员都在哪些不同的城市工作过? 14 | * (3) 查找所有来自于剑桥的交易员,并按姓名排序。 15 | * (4) 返回所有交易员的姓名字符串,按字母顺序排序。 16 | * (5) 有没有交易员是在米兰工作的? 17 | * (6) 打印生活在剑桥的交易员的所有交易额。 18 | * (7) 所有交易中,最高的交易额是多少? 19 | * (8) 找到交易额最小的交易。 20 | * 21 | * @author biezhi 22 | * @date 2018/2/12 23 | */ 24 | public class QuizEnd { 25 | 26 | // 交易员 27 | @Data 28 | @AllArgsConstructor 29 | static class Trader { 30 | // 姓名 31 | private String name; 32 | // 城市 33 | private String city; 34 | } 35 | 36 | // 交易 37 | @Data 38 | @AllArgsConstructor 39 | static class Transaction { 40 | private Trader trader; 41 | // 交易年份 42 | private int year; 43 | // 交易额 44 | private int value; 45 | } 46 | 47 | public static void main(String[] args) { 48 | Trader raoul = new Trader("Raoul", "Cambridge"); 49 | Trader mario = new Trader("Mario", "Milan"); 50 | Trader alan = new Trader("Alan", "Cambridge"); 51 | Trader brian = new Trader("Brian", "Cambridge"); 52 | 53 | List transactions = Arrays.asList( 54 | new Transaction(brian, 2011, 300), 55 | new Transaction(raoul, 2012, 1000), 56 | new Transaction(raoul, 2011, 400), 57 | new Transaction(mario, 2012, 710), 58 | new Transaction(mario, 2012, 700), 59 | new Transaction(alan, 2012, 950) 60 | ); 61 | 62 | // 01 63 | transactions.stream() 64 | .filter(transaction -> transaction.year == 2011) 65 | .sorted(Comparator.comparing(Transaction::getValue)) 66 | .collect(Collectors.toList()); 67 | 68 | // 02 69 | transactions.stream() 70 | .map(Transaction::getTrader) 71 | .map(Trader::getCity) 72 | .distinct() 73 | .collect(Collectors.toList()); 74 | 75 | // 03 76 | transactions.stream() 77 | .map(Transaction::getTrader) 78 | .filter(trader -> trader.getCity().equals("Cambridge")) 79 | .sorted(Comparator.comparing(Trader::getName)) 80 | .collect(Collectors.toList()); 81 | 82 | // 04 83 | transactions.stream() 84 | .map(Transaction::getTrader) 85 | .map(Trader::getName) 86 | .sorted(Comparator.naturalOrder()) 87 | .collect(Collectors.toList()); 88 | 89 | // 05 90 | transactions.stream() 91 | .map(Transaction::getTrader) 92 | .anyMatch(trader -> trader.getCity().equals("Milan")); 93 | 94 | // 06 95 | transactions.stream() 96 | .filter(transaction -> transaction.getTrader().getCity().equals("Cambridge")) 97 | .map(Transaction::getValue) 98 | .reduce(0, Integer::sum); 99 | 100 | // 07 101 | transactions.stream() 102 | .mapToInt(Transaction::getValue) 103 | .max(); 104 | 105 | // 08 106 | transactions.stream() 107 | .reduce((t1, t2) -> t1.getValue() < t2.getValue() ? t1 : t2); 108 | } 109 | 110 | } -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson3/Example1.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson3; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | import java.util.stream.Stream; 8 | 9 | import static java.util.stream.Collectors.*; 10 | 11 | /** 12 | * 1. 计数 13 | *

14 | * Collectors.counting 15 | * count 16 | *

17 | * 2. 最值 18 | * Collectors.maxBy 19 | *

20 | * 3. 求和 21 | * Collectors.summingInt 22 | *

23 | * 4. 求平均值 24 | * Collectors.averagingInt 25 | *

26 | * 5. 连接字符串 27 | * Collectors.joining 28 | *

29 | * 6. 一般归约 30 | * Collectors.reducing 31 | * 32 | * @author biezhi 33 | * @date 2018/3/2 34 | */ 35 | public class Example1 { 36 | 37 | public static void main(String[] args) { 38 | List projects = Project.buildData(); 39 | Double collect = projects.stream() 40 | .collect(averagingInt(Project::getStars)); 41 | System.out.println(collect); 42 | 43 | System.out.println(Stream.of("Hello", "Java8") 44 | .collect(joining(","))); 45 | 46 | Integer collect1 = projects.stream() 47 | .collect(reducing(0, Project::getStars, (x, y) -> x + y)); 48 | System.out.println(collect1); 49 | 50 | Optional collect2 = projects.stream() 51 | .map(Project::getStars) 52 | .collect(reducing((x, y) -> x + y)); 53 | System.out.println(collect2); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson3/Example2.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson3; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | import static java.util.stream.Collectors.*; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.function.Function; 9 | 10 | /** 11 | * 将结果收集到 Map 中 12 | *

13 | * Collectors.toMap 14 | * Function.identity() 15 | * 16 | * @author biezhi 17 | * @date 2018/3/2 18 | */ 19 | public class Example2 { 20 | 21 | public static void main(String[] args) { 22 | List projects = Project.buildData(); 23 | 24 | Map collect = projects.stream() 25 | .collect(toMap(Project::getName, Project::getStars)); 26 | System.out.println(collect); 27 | 28 | Map collect1 = projects.stream() 29 | .collect(toMap(Project::getName, Function.identity())); 30 | System.out.println(collect1); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson3/Example3.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson3; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import static java.util.stream.Collectors.*; 9 | 10 | /** 11 | * 根据作者名进行分组 12 | *

13 | * Collectors.groupingBy 14 | *

15 | * 然后根据编程语言类型做前后端分组 16 | * 17 | * @author biezhi 18 | * @date 2018/3/2 19 | */ 20 | public class Example3 { 21 | 22 | public static void main(String[] args) { 23 | List projects = Project.buildData(); 24 | Map> collect = projects.stream() 25 | .collect(groupingBy(Project::getAuthor)); 26 | System.out.println(collect); 27 | 28 | Map> collect1 = projects.stream() 29 | .collect(groupingBy(Project::getAuthor, 30 | groupingBy(p -> { 31 | if ("java".equalsIgnoreCase(p.getLanguage()) || 32 | "python".equalsIgnoreCase(p.getLanguage())) { 33 | return "后端"; 34 | } 35 | return "前端"; 36 | }, counting()) 37 | )); 38 | System.out.println(collect1); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson3/Example4.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson3; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import static java.util.stream.Collectors.*; 9 | 10 | /** 11 | * 数据分区 12 | *

13 | * Collectors.partitioningBy 14 | *

15 | * 根据前后端将项目分为两组 16 | * 17 | * @author biezhi 18 | * @date 2018/3/2 19 | */ 20 | public class Example4 { 21 | 22 | public static boolean isBackEnd(Project project){ 23 | return "java".equalsIgnoreCase(project.getLanguage()) || "python".equalsIgnoreCase(project.getLanguage()); 24 | } 25 | 26 | public static void main(String[] args) { 27 | List projects = Project.buildData(); 28 | 29 | Map> collect = projects.stream() 30 | .collect(partitioningBy(Example4::isBackEnd)); 31 | System.out.println(collect); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson3/Example5.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson3; 2 | 3 | import io.github.biezhi.java8.stream.Project; 4 | 5 | import java.util.*; 6 | import java.util.concurrent.CopyOnWriteArrayList; 7 | 8 | import static java.util.stream.Collectors.*; 9 | 10 | /** 11 | * 转换类型 12 | *

13 | * Collectors.toCollection 14 | *

15 | * Collectors.collectingAndThen 16 | *

17 | * Collectors.maxBy 18 | *

19 | * Collectors.minBy 20 | *

21 | * 按照作者名称筛选出每组star最高的项目 22 | * 23 | * @author biezhi 24 | * @date 2018/3/2 25 | */ 26 | public class Example5 { 27 | 28 | public static void main(String[] args) { 29 | List projects = Project.buildData(); 30 | 31 | Collection collect = projects.stream() 32 | .collect(toCollection(CopyOnWriteArrayList::new)); 33 | System.out.println(collect); 34 | 35 | Map collect1 = projects.stream() 36 | .collect(groupingBy(Project::getAuthor, collectingAndThen( 37 | maxBy(Comparator.comparingInt(Project::getStars)), 38 | Optional::get 39 | ))); 40 | System.out.println(collect1); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson3/Example6.java: -------------------------------------------------------------------------------- 1 | package io.github.biezhi.java8.stream.lesson3; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.UUID; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * 并行流 11 | * 12 | * @author biezhi 13 | * @date 2018/3/2 14 | */ 15 | public class Example6 { 16 | 17 | public static void main(String[] args) { 18 | // int max = 1000000; 19 | // List values = new ArrayList<>(max); 20 | // for (int i = 0; i < max; i++) { 21 | // UUID uuid = UUID.randomUUID(); 22 | // values.add(uuid.toString()); 23 | // } 24 | // 25 | // long t0 = System.nanoTime(); 26 | // long count = values.parallelStream().sorted().count(); 27 | // System.out.println(count); 28 | // long t1 = System.nanoTime(); 29 | // long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0); 30 | // System.out.println(String.format("sequential sort took: %d ms", millis)); 31 | // 32 | // List list = Arrays.asList(1, 3, 4, 2, 9); 33 | // list.stream() 34 | // .parallel(); 35 | 36 | Arrays.asList("a1", "a2", "b1", "c2", "c1") 37 | .parallelStream() 38 | .filter(s -> { 39 | System.out.format("filter: %s [%s]\n", 40 | s, Thread.currentThread().getName()); 41 | return true; 42 | }) 43 | .map(s -> { 44 | System.out.format("map: %s [%s]\n", 45 | s, Thread.currentThread().getName()); 46 | return s.toUpperCase(); 47 | }) 48 | .sorted((s1, s2) -> { 49 | System.out.format("sort: %s <> %s [%s]\n", 50 | s1, s2, Thread.currentThread().getName()); 51 | return s1.compareTo(s2); 52 | }) 53 | .forEach(s -> System.out.format("forEach: %s [%s]\n", 54 | s, Thread.currentThread().getName())); 55 | 56 | } 57 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | io.github.biezhi 8 | learn-java8 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | 13 | java8-lambda 14 | java8-optional 15 | java8-stream 16 | java8-default-methods 17 | java8-datetime-api 18 | java8-nashorn 19 | java8-best-practice 20 | java8-proper 21 | java8-concurrent 22 | java8-growing 23 | java8-completablefuture 24 | 25 | 26 | 27 | 28 | org.projectlombok 29 | lombok 30 | 1.16.18 31 | provided 32 | 33 | 34 | 35 | 36 | 37 | 38 | maven-compiler-plugin 39 | 40 | 1.8 41 | 1.8 42 | UTF-8 43 | 44 | 45 | 46 | 47 | 48 | --------------------------------------------------------------------------------