From adaa365040dd19596aa1bb1911032cedb3b5130a Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Sun, 30 Oct 2016 23:02:01 +0800
Subject: [PATCH 01/57] [update] update the README about future plan.
---
README.md | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index 52baff7..f9a446d 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
# 我的java学习笔记
-笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解java基础语法,想进一步深入学习的人
+旨在打造在线最佳的 java 学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解 java 基础语法,想进一步深入学习的人
-含**博客讲解**和**源码实例**,采用maven构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。
+含**博客讲解**和**源码实例**,采用 maven 构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。
-**如果觉得不错,请先在这个仓库上点个star吧**,这也是对我的肯定和鼓励,谢谢了。
+**如果觉得不错,请先在这个仓库上点个 star 吧**,这也是对我的肯定和鼓励,谢谢了。
不定时进行调整和补充,需要关注更新的请 Watch、Star、Fork
@@ -16,14 +16,14 @@
**点击相应的模块能看到每个目录的说明文档**
- [blogs](/blogs):博客文档
-- [java-base](/java-base):java基础巩固模块的java源码
-- [java-multithread](/java-multithread):多线程模块的java源码
+- [java-base](/java-base):java基础巩固模块的 java 源码
+- [java-multithread](/java-multithread):多线程模块的 java 源码
# 博客文档
-如果你只是单纯要阅读的话,建议移步CSDN或者oschina上观看,访问速度快很多:
+如果你只是单纯要阅读的话,建议移步 CSDN 或者 oschina 上观看,访问速度快很多:
>* CSDN:[我的java&javaweb学习笔记(汇总)](http://blog.csdn.net/h3243212/article/details/50659471)
>* oschina:[我的java&javaweb学习笔记(汇总)](http://my.oschina.net/brianway/blog/614355)
@@ -49,29 +49,31 @@
- [javaweb入门笔记(5)-cookie和session.md](/blogs/javaweb/javaweb入门笔记(5)-cookie和session.md)
- [javaweb入门笔记(6)-JSP技术.md](/blogs/javaweb/javaweb入门笔记(6)-JSP技术.md)
-
------
+
+-----
# TODO
计划将这个仓库进行重构,逐步扩充并实现下面的功能。
-* [x] 整理成maven的结构,使用聚合和继承特性(2016.4.12完成)
-* [ ] 原有的javase部分代码重构为java-base模块,并逐步上传代码
-* [x] 多线程部分使用java-multithread模块(2016.4.17完成)
-* [ ] 集合类部分使用模块java-collection
+* [x] 整理成 maven 的结构,使用聚合和继承特性(2016.4.12完成)
+* [ ] 原有的 javase 部分代码重构为 java-base 模块,并逐步上传代码
+* [x] 多线程部分使用 java-multithread 模块(2016.4.17完成)
+* [ ] 集合类部分使用模块 java-collections
* [ ] IO部分使用模块java-io
+* [ ] java虚拟机相关部分使用模块 java-jvm
+* [ ] java 8 新特性使用模块 java8
-
-----
# 联系作者
- [Brian's Personal Website](http://brianway.github.io/)
-- [oschina](http://my.oschina.net/brianway)
- [CSDN](http://blog.csdn.net/h3243212/)
+- [oschina](http://my.oschina.net/brianway)
+
Email: weichuyang@163.com
From 0616b6e07441bb95c54653465412311ee5f59c75 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Thu, 10 Nov 2016 16:32:04 +0800
Subject: [PATCH 02/57] [add] add some examples in java-base module.
---
.../brianway/learning/java/base/Binary.java | 14 ++++++
.../java/base/constructor/FatherClass.java | 7 ++-
.../java/base/constructor/SonClass.java | 19 +++++---
.../java/base/{ => datatype}/Boxing.java | 23 +++++-----
.../java/base/datatype/IntegerChanger.java | 44 +++++++++++++++++++
.../java/base/datatype/NumberEquation.java | 22 ++++++++++
.../java/base/innerclass/ClassCreator.java | 16 +++++++
.../java/base/innerclass/EnclosingOne.java | 21 +++++++++
8 files changed, 149 insertions(+), 17 deletions(-)
create mode 100644 java-base/src/main/java/com/brianway/learning/java/base/Binary.java
rename java-base/src/main/java/com/brianway/learning/java/base/{ => datatype}/Boxing.java (57%)
create mode 100644 java-base/src/main/java/com/brianway/learning/java/base/datatype/IntegerChanger.java
create mode 100644 java-base/src/main/java/com/brianway/learning/java/base/datatype/NumberEquation.java
create mode 100644 java-base/src/main/java/com/brianway/learning/java/base/innerclass/ClassCreator.java
create mode 100644 java-base/src/main/java/com/brianway/learning/java/base/innerclass/EnclosingOne.java
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/Binary.java b/java-base/src/main/java/com/brianway/learning/java/base/Binary.java
new file mode 100644
index 0000000..f970cd5
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/Binary.java
@@ -0,0 +1,14 @@
+package com.brianway.learning.java.base;
+
+/**
+ * Created by brian on 16/11/10.
+ *
+ * TODO 补码/反码相关知识
+ */
+public class Binary {
+ public static void main(String[] args) {
+ int i = 5;
+ int j = 10;
+ System.out.println(i + ~j);
+ }
+}
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java b/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java
index bea7928..4ccca61 100644
--- a/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java
+++ b/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java
@@ -4,14 +4,19 @@
* Created by Brian on 2016/4/14.
*/
public class FatherClass {
+ protected static int count = 10;
private String name;
+ static {
+ System.out.println("父类的静态属性count初始化:" + count);
+ }
+
public FatherClass() {
System.out.println("执行了父类的无参构造方法");
}
public FatherClass(String name) {
this.name = name;
- System.out.println("执行了父类的构造方法FatherClass(String name)");
+ System.out.println("执行了父类的构造方法FatherClass(String name) " + name);
}
}
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java b/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java
index 3289afe..6ea4cb4 100644
--- a/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java
+++ b/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java
@@ -2,16 +2,22 @@
/**
* Created by Brian on 2016/4/14.
- */
-
-/**
+ *
* 构造方法调用问题
* 子类构造方法会首先默认调用父类的无参构造方法,无论是否显式写了super();
*/
public class SonClass extends FatherClass {
+
+ private static int countSon;
+
+ static {
+ System.out.println("子类可以访问父类的静态属性count " + count);
+ System.out.println("子类的静态属性countSon初始化:" + countSon);
+ }
+
public SonClass(String name) {
//super(name);
- System.out.println("执行了子类的构造方法SonClass(String name)");
+ System.out.println("执行了子类的构造方法SonClass(String name) " + name);
}
public SonClass() {
@@ -26,8 +32,11 @@ public static void main(String[] args) {
}
/*
+父类的静态属性count初始化:10
+子类可以访问父类的静态属性count 10
+子类的静态属性countSon初始化:0
执行了父类的无参构造方法
-执行了子类的构造方法SonClass(String name)
+执行了子类的构造方法SonClass(String name) aaa
执行了父类的无参构造方法
执行了子类的无参构造方法
*/
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/Boxing.java b/java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java
similarity index 57%
rename from java-base/src/main/java/com/brianway/learning/java/base/Boxing.java
rename to java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java
index 8ec2160..8ac8da7 100644
--- a/java-base/src/main/java/com/brianway/learning/java/base/Boxing.java
+++ b/java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java
@@ -1,13 +1,11 @@
-package com.brianway.learning.java.base;
+package com.brianway.learning.java.base.datatype;
/**
* Created by Brian on 2016/4/14.
- */
-
-/**
- * TODO
- * 待理解。
- * 应该是考装箱和拆箱
+ *
+ * TODO 有些细节待理解
+ *
+ * 主要是考装箱和拆箱
*/
public class Boxing {
public static void main(String[] args) {
@@ -24,16 +22,19 @@ public static void main(String[] args) {
System.out.println(c.equals(a + b));
System.out.println(g == (a + b));
System.out.println(g.equals(a + b));
+ System.out.println(new Integer(2) == new Integer(2));
}
}
/*
-输出:
-true
-false
-true
+输出: 原因:
+true 自动装箱,缓存
+false 自动装箱,未缓存
true
+true 调用 equals(),比较的是值,而不是对象地址
true
false
+false 比较的是对象地址
+
*/
\ No newline at end of file
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/datatype/IntegerChanger.java b/java-base/src/main/java/com/brianway/learning/java/base/datatype/IntegerChanger.java
new file mode 100644
index 0000000..45326c8
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/datatype/IntegerChanger.java
@@ -0,0 +1,44 @@
+package com.brianway.learning.java.base.datatype;
+
+import java.lang.reflect.Field;
+
+/**
+ * Created by brian on 16/11/1.
+ *
+ * 涉及到的知识点:
+ * 1.java 的参数传递都是值传递
+ * 2.Integer的内部实现(value,缓存,等等)
+ * 3.反射操作(可访问性)
+ * 4.自动装箱和拆箱
+ *
+ * 参考博客 http://www.voidcn.com/blog/zgwangbo/article/p-6101689.html
+ */
+public class IntegerChanger {
+
+ public static void main(String[] args) {
+ Integer a = 1, b = 2;
+ System.out.println("before swap a = " + a + ", b = " + b);
+ swap(a, b);
+ System.out.println("after swap a = " + a + ", b = " + b);
+
+ Integer c = 1;
+ System.out.println("(警告:Integer缓存被改了,代码里:Integer c = 1;) 实际c=" + c);
+ }
+
+ public static void swap(Integer i1, Integer i2) {
+ try {
+ Field f = Integer.class.getDeclaredField("value");
+ f.setAccessible(true);
+
+ int tmp = i1;
+ f.setInt(i1, i2);
+ f.setInt(i2, tmp);
+
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/datatype/NumberEquation.java b/java-base/src/main/java/com/brianway/learning/java/base/datatype/NumberEquation.java
new file mode 100644
index 0000000..6cd718b
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/datatype/NumberEquation.java
@@ -0,0 +1,22 @@
+package com.brianway.learning.java.base.datatype;
+
+/**
+ * Created by brian on 16/11/10.
+ *
+ * 包装类的“==”运算在不遇到算术运算的情况下不会自动拆箱;
+ * 包装类的equals()方法不处理数据转型.
+ */
+public class NumberEquation {
+ public static void main(String[] args) {
+ Integer i = 42;
+ Long l = 42l;
+ Double d = 42.0;
+
+ System.out.println(i.equals(d)); // false
+ System.out.println(d.equals(l)); // false
+ System.out.println(i.equals(l)); // false
+ System.out.println(l.equals(42L)); // true
+ }
+}
+
+// (i == l),(i == d),(l == d)会出现编译错误
\ No newline at end of file
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/innerclass/ClassCreator.java b/java-base/src/main/java/com/brianway/learning/java/base/innerclass/ClassCreator.java
new file mode 100644
index 0000000..09de444
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/innerclass/ClassCreator.java
@@ -0,0 +1,16 @@
+package com.brianway.learning.java.base.innerclass;
+
+/**
+ * Created by brian on 16/11/10.
+ *
+ * 创建内部类的测试类
+ */
+public class ClassCreator {
+ public static void main(String[] args) {
+ //在其他类里创建非静态内部类和静态内部类
+ EnclosingOne eo = new EnclosingOne();
+ EnclosingOne.InsideOne io = eo.new InsideOne();
+ EnclosingOne.InsideTwo it = new EnclosingOne.InsideTwo();
+ }
+
+}
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/innerclass/EnclosingOne.java b/java-base/src/main/java/com/brianway/learning/java/base/innerclass/EnclosingOne.java
new file mode 100644
index 0000000..4718fd4
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/innerclass/EnclosingOne.java
@@ -0,0 +1,21 @@
+package com.brianway.learning.java.base.innerclass;
+
+/**
+ * Created by brian on 16/11/10.
+ */
+public class EnclosingOne {
+
+ public class InsideOne {
+
+ }
+
+ static public class InsideTwo {
+
+ }
+
+ public static void main(String[] args) {
+ EnclosingOne eo = new EnclosingOne();
+ InsideOne io = eo.new InsideOne();
+ InsideTwo it = new InsideTwo();
+ }
+}
From 30a5eac5c27d8365b43f2f632a3d596881f20a07 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Sat, 19 Nov 2016 18:44:35 +0800
Subject: [PATCH 03/57] [add] add module java-container and update README.
---
README.md | 6 +++---
.../brianway/learning/java/base/Binary.java | 18 ++++++++++++++++++
java-container/pom.xml | 14 ++++++++++++++
pom.xml | 1 +
4 files changed, 36 insertions(+), 3 deletions(-)
create mode 100644 java-container/pom.xml
diff --git a/README.md b/README.md
index f9a446d..aee7c1a 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
**点击相应的模块能看到每个目录的说明文档**
- [blogs](/blogs):博客文档
-- [java-base](/java-base):java基础巩固模块的 java 源码
+- [java-base](/java-base):java 基础巩固模块的 java 源码
- [java-multithread](/java-multithread):多线程模块的 java 源码
@@ -60,8 +60,8 @@
* [x] 整理成 maven 的结构,使用聚合和继承特性(2016.4.12完成)
* [ ] 原有的 javase 部分代码重构为 java-base 模块,并逐步上传代码
* [x] 多线程部分使用 java-multithread 模块(2016.4.17完成)
-* [ ] 集合类部分使用模块 java-collections
-* [ ] IO部分使用模块java-io
+* [ ] 容器类部分使用模块 java-container
+* [ ] IO 部分使用模块 java-io
* [ ] java虚拟机相关部分使用模块 java-jvm
* [ ] java 8 新特性使用模块 java8
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/Binary.java b/java-base/src/main/java/com/brianway/learning/java/base/Binary.java
index f970cd5..2a8849a 100644
--- a/java-base/src/main/java/com/brianway/learning/java/base/Binary.java
+++ b/java-base/src/main/java/com/brianway/learning/java/base/Binary.java
@@ -4,11 +4,29 @@
* Created by brian on 16/11/10.
*
* TODO 补码/反码相关知识
+ * https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html
+ * http://weihe6666.iteye.com/blog/1190033
+ *
+ * 在计算机中,负数以原码的补码形式表达。
*/
public class Binary {
public static void main(String[] args) {
int i = 5;
int j = 10;
System.out.println(i + ~j);
+
+ int[] arr = new int[] {3, -2};
+ for (int a : arr) {
+ //原数
+ System.out.println("a:" + a + " 二进制:" + Integer.toBinaryString(a));
+ // 按位取反
+ System.out.println("~a:" + ~a + " 二进制:" + Integer.toBinaryString(~a));
+ // 相反数
+ System.out.println("-a:" + -a + " 二进制:" + Integer.toBinaryString(-a));
+
+ System.out.println(-a == ~a + 1);
+ System.out.println(~a == -a - 1);
+ }
+
}
}
diff --git a/java-container/pom.xml b/java-container/pom.xml
new file mode 100644
index 0000000..7f8d9ed
--- /dev/null
+++ b/java-container/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ java-learning
+ com.brianway.learning.java
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ java-container
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9c68e4b..9901359 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,7 @@
java-multithread
java-base
+ java-container
From 1b9e2a23fd27f5dbb024cc343372d1c43f65a12f Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Mon, 21 Nov 2016 23:56:46 +0800
Subject: [PATCH 04/57] [update] update REAMDE,plan for java-container module.
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index aee7c1a..cd387e7 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# 我的java学习笔记
-旨在打造在线最佳的 java 学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解 java 基础语法,想进一步深入学习的人
+旨在打造在线最佳的 java 学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解 java 基础语法,想进一步深入学习的人
含**博客讲解**和**源码实例**,采用 maven 构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。
@@ -18,7 +18,7 @@
- [blogs](/blogs):博客文档
- [java-base](/java-base):java 基础巩固模块的 java 源码
- [java-multithread](/java-multithread):多线程模块的 java 源码
-
+- [java-container](/java-container):容器类模块的 java 源码
# 博客文档
From 724ffb2a1a12983bdad16879d34af3a693a4f8bd Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Mon, 28 Nov 2016 18:53:27 +0800
Subject: [PATCH 05/57] [add] add module java-io and add examples about File
---
java-io/pom.xml | 14 +++
.../brianway/learning/java/io/DirList.java | 32 +++++++
.../learning/java/io/MakeDirectories.java | 86 +++++++++++++++++++
pom.xml | 1 +
4 files changed, 133 insertions(+)
create mode 100644 java-io/pom.xml
create mode 100644 java-io/src/main/java/com/brianway/learning/java/io/DirList.java
create mode 100755 java-io/src/main/java/com/brianway/learning/java/io/MakeDirectories.java
diff --git a/java-io/pom.xml b/java-io/pom.xml
new file mode 100644
index 0000000..d62726d
--- /dev/null
+++ b/java-io/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ java-learning
+ com.brianway.learning.java
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ java-io
+
+
\ No newline at end of file
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/DirList.java b/java-io/src/main/java/com/brianway/learning/java/io/DirList.java
new file mode 100644
index 0000000..c7e8898
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/io/DirList.java
@@ -0,0 +1,32 @@
+package com.brianway.learning.java.io;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+/**
+ * Created by brian on 16/11/28.
+ * 列举文件/文件夹
+ */
+public class DirList {
+ public static void main(final String[] args) {
+ File path = new File(".");
+ String[] list;
+ if (args.length == 0) {
+ list = path.list();
+ } else {
+ list = path.list(new FilenameFilter() {
+ private Pattern pattern = Pattern.compile(args[0]); // final String[] args
+
+ public boolean accept(File dir, String name) {
+ return pattern.matcher(name).matches();
+ }
+ });
+ }
+ Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);
+ for (String dirItem : list) {
+ System.out.println(dirItem);
+ }
+ }
+}
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/MakeDirectories.java b/java-io/src/main/java/com/brianway/learning/java/io/MakeDirectories.java
new file mode 100755
index 0000000..d48d7dc
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/io/MakeDirectories.java
@@ -0,0 +1,86 @@
+package com.brianway.learning.java.io;
+//: io/MakeDirectories.java
+// Demonstrates the use of the File class to
+// create directories and manipulate files.
+// {Args: MakeDirectoriesTest}
+
+import java.io.File;
+
+public class MakeDirectories {
+ private static void usage() {
+ System.err.println(
+ "Usage:MakeDirectories path1 ...\n" +
+ "Creates each path\n" +
+ "Usage:MakeDirectories -d path1 ...\n" +
+ "Deletes each path\n" +
+ "Usage:MakeDirectories -r path1 path2\n" +
+ "Renames from path1 to path2");
+ System.exit(1);
+ }
+
+ private static void fileData(File f) {
+ System.out.println(
+ "Absolute path: " + f.getAbsolutePath() +
+ "\n Can read: " + f.canRead() +
+ "\n Can write: " + f.canWrite() +
+ "\n getName: " + f.getName() +
+ "\n getParent: " + f.getParent() +
+ "\n getPath: " + f.getPath() +
+ "\n length: " + f.length() +
+ "\n lastModified: " + f.lastModified());
+ if (f.isFile()) {
+ System.out.println("It's a file");
+ } else if (f.isDirectory()) {
+ System.out.println("It's a directory");
+ }
+ }
+
+ public static void main(String[] args) {
+ if (args.length < 1) usage();
+ if (args[0].equals("-r")) {
+ if (args.length != 3) usage();
+ File
+ old = new File(args[1]),
+ rname = new File(args[2]);
+ old.renameTo(rname);
+ fileData(old);
+ fileData(rname);
+ return; // Exit main
+ }
+ int count = 0;
+ boolean del = false;
+ if (args[0].equals("-d")) {
+ count++;
+ del = true;
+ }
+ count--;
+ while (++count < args.length) {
+ File f = new File(args[count]);
+ if (f.exists()) {
+ System.out.println(f + " exists");
+ if (del) {
+ System.out.println("deleting..." + f);
+ f.delete();
+ }
+ } else { // Doesn't exist
+ if (!del) {
+ f.mkdirs();
+ System.out.println("created " + f);
+ }
+ }
+ fileData(f);
+ }
+ }
+}
+/* Output: (80% match)
+created MakeDirectoriesTest
+Absolute path: d:\aaa-TIJ4\code\io\MakeDirectoriesTest
+ Can read: true
+ Can write: true
+ getName: MakeDirectoriesTest
+ getParent: null
+ getPath: MakeDirectoriesTest
+ length: 0
+ lastModified: 1101690308831
+It's a directory
+*///:~
diff --git a/pom.xml b/pom.xml
index 9901359..5bf3a88 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,6 +47,7 @@
java-multithread
java-base
java-container
+ java-io
From a76f7a428bc5affaff98c97b840a0cf764ad2a7e Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Mon, 28 Nov 2016 22:22:54 +0800
Subject: [PATCH 06/57] [add] add io examples
---
.../learning/java/io/BufferedInputFile.java | 28 +++++
.../com/brianway/learning/java/io/Echo.java | 25 +++++
.../brianway/learning/java/io/FileOutput.java | 60 ++++++++++
.../learning/java/io/MemoryInput.java | 55 +++++++++
.../brianway/learning/java/io/TextFile.java | 104 ++++++++++++++++++
java-io/src/main/resources/infile.txt | 12 ++
6 files changed, 284 insertions(+)
create mode 100644 java-io/src/main/java/com/brianway/learning/java/io/BufferedInputFile.java
create mode 100644 java-io/src/main/java/com/brianway/learning/java/io/Echo.java
create mode 100644 java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
create mode 100755 java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java
create mode 100755 java-io/src/main/java/com/brianway/learning/java/io/TextFile.java
create mode 100644 java-io/src/main/resources/infile.txt
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/BufferedInputFile.java b/java-io/src/main/java/com/brianway/learning/java/io/BufferedInputFile.java
new file mode 100644
index 0000000..213424d
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/io/BufferedInputFile.java
@@ -0,0 +1,28 @@
+package com.brianway.learning.java.io;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+/**
+ * Created by brian on 16/11/28.
+ */
+public class BufferedInputFile {
+ public static String read(String filename) throws IOException {
+ BufferedReader in = new BufferedReader(
+ new FileReader(filename));
+ String s;
+ StringBuilder sb = new StringBuilder();
+ while ((s = in.readLine()) != null) {
+ sb.append(s).append("\n");
+ }
+ in.close();
+ return sb.toString();
+ }
+
+ public static void main(String[] args) throws IOException {
+ String file = BufferedInputFile.class.getResource("/").getPath()
+ + "/infile.txt";
+ System.out.print(read(file));
+ }
+}
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/Echo.java b/java-io/src/main/java/com/brianway/learning/java/io/Echo.java
new file mode 100644
index 0000000..34ba225
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/io/Echo.java
@@ -0,0 +1,25 @@
+package com.brianway.learning.java.io;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+
+/**
+ * Created by brian on 16/11/28.
+ *
+ * 从标准输入中读取,并将 System.out 转换成 PrintWriter
+ */
+public class Echo {
+ public static void main(String[] args) throws IOException {
+ BufferedReader stdin = new BufferedReader(
+ new InputStreamReader(System.in));
+ PrintWriter out = new PrintWriter(System.out, true);// 开启自动清空
+
+ String s;
+ while ((s = stdin.readLine()) != null && s.length() != 0) {
+ //System.out.println(s);
+ out.println(s);
+ }
+ }
+}
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java b/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
new file mode 100644
index 0000000..c78f419
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
@@ -0,0 +1,60 @@
+package com.brianway.learning.java.io;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+
+/**
+ * Created by brian on 16/11/28.
+ */
+public class FileOutput {
+
+ /**
+ * 基本的文件输出
+ */
+ public static void basic(String infile, String outfile) throws IOException {
+ BufferedReader in = new BufferedReader(
+ new StringReader(
+ BufferedInputFile.read(infile)));
+ PrintWriter out = new PrintWriter(
+ new BufferedWriter(new FileWriter(outfile)));
+ int lineCount = 1;
+ String s;
+ while ((s = in.readLine()) != null) {
+ out.println(lineCount++ + ": " + s);
+ }
+ out.close();
+ System.out.println(BufferedInputFile.read(outfile));
+ }
+
+ /**
+ * 文本文件输出的快捷方式
+ */
+ public static void shortcut(String infile, String outfile)throws IOException{
+ BufferedReader in = new BufferedReader(
+ new StringReader(
+ BufferedInputFile.read(infile)));
+ PrintWriter out = new PrintWriter(outfile);
+ int lineCount = 1;
+ String s;
+ while ((s = in.readLine()) != null) {
+ out.println(lineCount++ + ": " + s);
+ }
+ out.close();
+ System.out.println(BufferedInputFile.read(outfile));
+ }
+
+ public static void main(String[] args) throws IOException {
+ String parent = BufferedInputFile.class.getResource("/").getPath();
+ String infile = parent + "/infile.txt";
+
+ String outfile = parent + "/BasicOut";
+ basic(infile, outfile);
+
+ outfile = parent+"ShortcutOut";
+ shortcut(infile,outfile);
+ }
+}
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java b/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java
new file mode 100755
index 0000000..d8a1973
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java
@@ -0,0 +1,55 @@
+package com.brianway.learning.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * Created by brian on 16/11/28.
+ * 内存输入
+ */
+
+public class MemoryInput {
+
+ /**
+ * 从内存输入
+ */
+ public static void useStringReader(String filename) {
+ try {
+ StringReader in = new StringReader(
+ BufferedInputFile.read(filename));
+ int c;
+ while ((c = in.read()) != -1)
+ System.out.print((char) c);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * 格式化的内存输入
+ */
+ public static void readFormattedInput(String filename) {
+ try {
+ DataInputStream in = new DataInputStream(
+ new ByteArrayInputStream(
+ BufferedInputFile.read(filename)
+ .getBytes()));
+ while (in.available() != 0) {
+ System.out.print((char) in.readByte());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ throws IOException {
+ String filename = BufferedInputFile.class.getResource("/").getPath()
+ + "/infile.txt";
+ useStringReader(filename);
+ readFormattedInput(filename);
+ }
+}
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java b/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java
new file mode 100755
index 0000000..6c76eab
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java
@@ -0,0 +1,104 @@
+package com.brianway.learning.java.io;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.TreeSet;
+
+/**
+ * Static functions for reading and writing text files as
+ * a single string, and treating a file as an ArrayList.
+ */
+public class TextFile extends ArrayList {
+ // Read a file as a single string:
+ public static String read(String fileName) {
+ StringBuilder sb = new StringBuilder();
+ try {
+ BufferedReader in = new BufferedReader(
+ new FileReader(
+ new File(fileName).getAbsoluteFile()));
+ try {
+ String s;
+ while ((s = in.readLine()) != null) {
+ sb.append(s);
+ sb.append("\n");
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return sb.toString();
+ }
+
+ // Write a single file in one method call:
+ public static void write(String fileName, String text) {
+ try {
+ PrintWriter out = new PrintWriter(
+ new File(fileName).getAbsoluteFile());
+ try {
+ out.print(text);
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // Read a file, split by any regular expression:
+ public TextFile(String fileName, String splitter) {
+ super(Arrays.asList(read(fileName).split(splitter)));
+ // Regular expression split() often leaves an empty
+ // String at the first position:
+ if (get(0).equals("")) remove(0);
+ }
+
+ // Normally read by lines:
+ public TextFile(String fileName) {
+ this(fileName, "\n");
+ }
+
+ public void write(String fileName) {
+ try {
+ PrintWriter out = new PrintWriter(
+ new File(fileName).getAbsoluteFile());
+ try {
+ for (String item : this)
+ out.println(item);
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // Simple test:
+ public static void main(String[] args) {
+ String parent = BufferedInputFile.class.getResource("/").getPath();
+ String inFileName = parent + "/infile.txt";
+
+ String file = read(inFileName);
+ write(parent + "/text.txt", file);
+ TextFile text = new TextFile(parent + "/text.txt");
+ text.write(parent + "test2.txt");
+ // Break into unique sorted list of words:
+ TreeSet words = new TreeSet(
+ new TextFile(inFileName, "\\W+"));
+ // Display the capitalized words:
+ System.out.println(words.headSet("a"));
+
+ }
+}
+
diff --git a/java-io/src/main/resources/infile.txt b/java-io/src/main/resources/infile.txt
new file mode 100644
index 0000000..a643f77
--- /dev/null
+++ b/java-io/src/main/resources/infile.txt
@@ -0,0 +1,12 @@
+-----------------------------------------
+public static String read(String filename) throws IOException {
+ BufferedReader in = new BufferedReader(
+ new FileReader(filename));
+ String s;
+ StringBuilder sb = new StringBuilder();
+ while ((s = in.readLine()) != null) {
+ sb.append(s).append("\n");
+ }
+ in.close();
+ return sb.toString();
+}
\ No newline at end of file
From 5423ec56a5640ca4accea28943a34ad9f7f2b196 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Tue, 29 Nov 2016 13:54:11 +0800
Subject: [PATCH 07/57] [update] update the class that resource path gets from
in main methods
---
.../src/main/java/com/brianway/learning/java/io/FileOutput.java | 2 +-
.../main/java/com/brianway/learning/java/io/MemoryInput.java | 2 +-
.../src/main/java/com/brianway/learning/java/io/TextFile.java | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java b/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
index c78f419..9481ada 100644
--- a/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
+++ b/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
@@ -48,7 +48,7 @@ public static void shortcut(String infile, String outfile)throws IOException{
}
public static void main(String[] args) throws IOException {
- String parent = BufferedInputFile.class.getResource("/").getPath();
+ String parent = FileOutput.class.getResource("/").getPath();
String infile = parent + "/infile.txt";
String outfile = parent + "/BasicOut";
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java b/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java
index d8a1973..7b459ed 100755
--- a/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java
+++ b/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java
@@ -47,7 +47,7 @@ public static void readFormattedInput(String filename) {
public static void main(String[] args)
throws IOException {
- String filename = BufferedInputFile.class.getResource("/").getPath()
+ String filename = MemoryInput.class.getResource("/").getPath()
+ "/infile.txt";
useStringReader(filename);
readFormattedInput(filename);
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java b/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java
index 6c76eab..6170202 100755
--- a/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java
+++ b/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java
@@ -86,7 +86,7 @@ public void write(String fileName) {
// Simple test:
public static void main(String[] args) {
- String parent = BufferedInputFile.class.getResource("/").getPath();
+ String parent = TextFile.class.getResource("/").getPath();
String inFileName = parent + "/infile.txt";
String file = read(inFileName);
From 490a25fee0a7089f0caf7a9d94f1b9104987b6c9 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Tue, 29 Nov 2016 17:02:15 +0800
Subject: [PATCH 08/57] [add] add some examples of nio
---
.../learning/java/nio/BufferToText.java | Bin 0 -> 2237 bytes
.../learning/java/nio/ChannelCopy.java | 45 ++++++++++
.../brianway/learning/java/nio/Endians.java | 36 ++++++++
.../learning/java/nio/GetChannel.java | 47 +++++++++++
.../learning/java/nio/ViewBuffers.java | 78 ++++++++++++++++++
5 files changed, 206 insertions(+)
create mode 100755 java-io/src/main/java/com/brianway/learning/java/nio/BufferToText.java
create mode 100644 java-io/src/main/java/com/brianway/learning/java/nio/ChannelCopy.java
create mode 100644 java-io/src/main/java/com/brianway/learning/java/nio/Endians.java
create mode 100644 java-io/src/main/java/com/brianway/learning/java/nio/GetChannel.java
create mode 100755 java-io/src/main/java/com/brianway/learning/java/nio/ViewBuffers.java
diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/BufferToText.java b/java-io/src/main/java/com/brianway/learning/java/nio/BufferToText.java
new file mode 100755
index 0000000000000000000000000000000000000000..6d9c5d7574296bbb7a458f13a311d29828b89256
GIT binary patch
literal 2237
zcmd5-&2G~`5bilr-eKfRofOt2sw!yJOG+zophf+;fH-XIb+XjiwRYEaBLor;z>!Db
z%mpN#2Z=rhGix_-(gcdc0V`7cGduHr^L;y;^Z1gF1jKs6hDLH#@+r#%H%h7zd&93d
zQ&R7>TkTfV?Y3Lcg##nF6A28b;8%cF(A$Z6y{P|$QA8D`)s-*~vw#!V4x9$A5=f1n
zz+mdcph#0;EX78YT~2as9QcY-vm=>_XDTn;nZt4u1h69Dq;TsZ5Hy>YSz1mX<1trC
zWY$+Ys2)~_87mya2>SPp$ctenV~8_uEmSNRjPvK??^qe}~i*RjZ*#Gcp1C`A@R>~9w!?KcPgwdOf1463Oe-S1$X1HgFq+;U3H!mn~z!QbXyQaL$6k!lw|JO
z1vBupinOXb2x$!a^L+G`E+tAI)f6nGDjr6?b^%Emv(iW>!nug}g6CmyrYFK%Dj*8<
z*@m4?lLfAgGi}9ELS%G{qv5RI!7{w@W%K@qDXp-)Y8)c>pC1xFSocG6G8J
z#$eG%Zd|p9W9wy>(au$_(G;@t%r*bOy?1%7^mA}=e)O=nGdK+H;cOKASeM|;6v%W$
zh>vi9tfO&n^Lt0cbQmlc0=L&+n0tl%KJOnad|?G}FL~v1IzRkC@N=*jjn}cezeogQ
z&4%u8clH4L`dk~FHF!9n2Sg&0xqK@)Fg%Nzc11S$Od_~qu?=N})w-hBGrZY@p$vi##+n2q;#Yt`+>#zwo<
LjiPAxeY^Dw=oFTp
literal 0
HcmV?d00001
diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/ChannelCopy.java b/java-io/src/main/java/com/brianway/learning/java/nio/ChannelCopy.java
new file mode 100644
index 0000000..8054ebc
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/nio/ChannelCopy.java
@@ -0,0 +1,45 @@
+package com.brianway.learning.java.nio;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/**
+ * Created by brian on 16/11/29.
+ */
+public class ChannelCopy {
+
+ private static final int BSIZE = 1024;
+
+ public static void main(String[] args) throws IOException {
+ String parent = ChannelCopy.class.getResource("/").getPath();
+ String infile = parent + "/infile.txt";
+ String outCopy = parent + "/outCopy.txt";
+ String outTransferTo = parent + "/outTransferTo.txt";
+ copy(infile, outCopy);
+ transferTo(infile, outTransferTo);
+ }
+
+ private static void copy(String infile, String outfile) throws IOException {
+ FileChannel
+ in = new FileInputStream(infile).getChannel(),
+ out = new FileOutputStream(outfile).getChannel();
+ ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
+ while (in.read(buffer) != -1) {
+ buffer.flip(); // prepare for writing
+ out.write(buffer);
+ buffer.clear(); // prepare for reading
+ }
+ }
+
+ private static void transferTo(String infile, String outfile) throws IOException {
+ FileChannel
+ in = new FileInputStream(infile).getChannel(),
+ out = new FileOutputStream(outfile).getChannel();
+ in.transferTo(0, in.size(), out);
+ // Or:
+ // out.transferFrom(in,0,in.size());
+ }
+}
diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/Endians.java b/java-io/src/main/java/com/brianway/learning/java/nio/Endians.java
new file mode 100644
index 0000000..f7b2404
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/nio/Endians.java
@@ -0,0 +1,36 @@
+package com.brianway.learning.java.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+/**
+ * Created by brian on 16/11/29.
+ *
+ * "big endian"(高位优先),将最重要的字节放在地址最低的存储器单元;
+ * "little endian"(低位优先),将最重要的字节放在地址最高的存储器单元;
+ *
+ * ByteBuffer 是以高位优先的形式存储数据的。
+ */
+public class Endians {
+ public static void main(String[] args) {
+ ByteBuffer bb = ByteBuffer.wrap(new byte[12]);
+ bb.asCharBuffer().put("abcdef");
+ System.out.println(Arrays.toString(bb.array()));
+
+ bb.rewind();
+ bb.order(ByteOrder.BIG_ENDIAN);
+ bb.asCharBuffer().put("abcdef");
+ System.out.println(Arrays.toString(bb.array()));
+
+ bb.rewind();
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+ bb.asCharBuffer().put("abcdef");
+ System.out.println(Arrays.toString(bb.array()));
+ }
+}
+/* Output:
+[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
+[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
+[97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0]
+*///:~
diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/GetChannel.java b/java-io/src/main/java/com/brianway/learning/java/nio/GetChannel.java
new file mode 100644
index 0000000..9a23798
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/nio/GetChannel.java
@@ -0,0 +1,47 @@
+package com.brianway.learning.java.nio;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/**
+ * Created by brian on 16/11/29.
+ */
+public class GetChannel {
+ private static final int BSIZE = 1024;
+
+ public static void main(String[] args) throws IOException {
+ String parent = GetChannel.class.getResource("/").getPath();
+ String filename = parent + "/data.txt";
+ write(filename);
+ addToEnd(filename);
+ read(filename);
+ }
+
+ private static void write(String filename) throws IOException {
+ FileChannel fc = new FileOutputStream(filename).getChannel();
+ fc.write(ByteBuffer.wrap("Some text ".getBytes()));
+ fc.close();
+ }
+
+ private static void addToEnd(String filename) throws IOException {
+ FileChannel fc = new RandomAccessFile(filename, "rw").getChannel();
+ fc.position(fc.size());
+ fc.write(ByteBuffer.wrap("Some more ".getBytes()));
+ fc.close();
+ }
+
+ private static void read(String filename) throws IOException {
+ FileChannel fc = new FileInputStream(filename).getChannel();
+ ByteBuffer buff = ByteBuffer.allocate(BSIZE);
+ fc.read(buff);
+ buff.flip();
+ while (buff.hasRemaining()) {
+ System.out.print((char) buff.get());
+ }
+ fc.close();
+ }
+}
diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/ViewBuffers.java b/java-io/src/main/java/com/brianway/learning/java/nio/ViewBuffers.java
new file mode 100755
index 0000000..f95b2a5
--- /dev/null
+++ b/java-io/src/main/java/com/brianway/learning/java/nio/ViewBuffers.java
@@ -0,0 +1,78 @@
+package com.brianway.learning.java.nio;//: io/ViewBuffers.java
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
+
+/**
+ * Created by brian on 16/11/29.
+ *
+ * 通过在同一个 ByteBuffer 上建立不同的试图缓冲器,
+ * 将同一字节序列翻译成short,int,float,long,double等类型的数据
+ */
+
+public class ViewBuffers {
+ public static void main(String[] args) {
+ ByteBuffer bb = ByteBuffer.wrap(
+ new byte[] {0, 0, 0, 0, 0, 0, 0, 'a'});
+ bb.rewind();
+ System.out.print("Byte Buffer ");
+ while (bb.hasRemaining())
+ System.out.print(bb.position() + " -> " + bb.get() + ", ");
+ System.out.println();
+
+ CharBuffer cb =
+ ((ByteBuffer) bb.rewind()).asCharBuffer();
+ System.out.println("Char Buffer ");
+ while (cb.hasRemaining())
+ System.out.print(cb.position() + " -> " + cb.get() + ", ");
+ System.out.println();
+
+ FloatBuffer fb =
+ ((ByteBuffer) bb.rewind()).asFloatBuffer();
+ System.out.print("Float Buffer ");
+ while (fb.hasRemaining())
+ System.out.print(fb.position() + " -> " + fb.get() + ", ");
+ System.out.println();
+
+ IntBuffer ib =
+ ((ByteBuffer) bb.rewind()).asIntBuffer();
+ System.out.print("Int Buffer ");
+ while (ib.hasRemaining())
+ System.out.print(ib.position() + " -> " + ib.get() + ", ");
+ System.out.println();
+
+ LongBuffer lb =
+ ((ByteBuffer) bb.rewind()).asLongBuffer();
+ System.out.print("Long Buffer ");
+ while (lb.hasRemaining())
+ System.out.print(lb.position() + " -> " + lb.get() + ", ");
+ System.out.println();
+
+ ShortBuffer sb =
+ ((ByteBuffer) bb.rewind()).asShortBuffer();
+ System.out.print("Short Buffer ");
+ while (sb.hasRemaining())
+ System.out.print(sb.position() + " -> " + sb.get() + ", ");
+ System.out.println();
+
+ DoubleBuffer db =
+ ((ByteBuffer) bb.rewind()).asDoubleBuffer();
+ System.out.print("Double Buffer ");
+ while (db.hasRemaining())
+ System.out.print(db.position() + " -> " + db.get() + ", ");
+ }
+}
+/* Output:
+Byte Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0, 5 -> 0, 6 -> 0, 7 -> 97,
+Char Buffer 0 -> , 1 -> , 2 -> , 3 -> a,
+Float Buffer 0 -> 0.0, 1 -> 1.36E-43,
+Int Buffer 0 -> 0, 1 -> 97,
+Long Buffer 0 -> 97,
+Short Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 97,
+Double Buffer 0 -> 4.8E-322,
+*///:~
From 1c2fcdc8c9d5354aaa81c36c7a836fce8654a30d Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Tue, 29 Nov 2016 17:04:35 +0800
Subject: [PATCH 09/57] [update] update README
---
README.md | 19 ++++++++++---------
.../brianway/learning/java/io/FileOutput.java | 6 +++---
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/README.md b/README.md
index cd387e7..9021dca 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
# 我的java学习笔记
-旨在打造在线最佳的 java 学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解 java 基础语法,想进一步深入学习的人
+旨在打造在线最佳的 Java 学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解 Java 基础语法,想进一步深入学习的人
含**博客讲解**和**源码实例**,采用 maven 构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。
**如果觉得不错,请先在这个仓库上点个 star 吧**,这也是对我的肯定和鼓励,谢谢了。
-不定时进行调整和补充,需要关注更新的请 Watch、Star、Fork
+不定时进行调整和补充,需要关注更新的请 watch、star、fork
-----
@@ -16,9 +16,10 @@
**点击相应的模块能看到每个目录的说明文档**
- [blogs](/blogs):博客文档
-- [java-base](/java-base):java 基础巩固模块的 java 源码
-- [java-multithread](/java-multithread):多线程模块的 java 源码
-- [java-container](/java-container):容器类模块的 java 源码
+- [java-base](/java-base):Java 基础巩固模块的 Java 源码
+- [java-multithread](/java-multithread):多线程模块的 Java 源码
+- [java-container](/java-container):容器类模块的 Java 源码
+- [java-io](/java-io):IO 模块的 Java 源码
# 博客文档
@@ -58,12 +59,12 @@
计划将这个仓库进行重构,逐步扩充并实现下面的功能。
* [x] 整理成 maven 的结构,使用聚合和继承特性(2016.4.12完成)
-* [ ] 原有的 javase 部分代码重构为 java-base 模块,并逐步上传代码
-* [x] 多线程部分使用 java-multithread 模块(2016.4.17完成)
+* [ ] 原有的 Java SE 部分代码重构为 java-base 模块,并逐步上传代码
+* [x] 多线程部分使用 java-multithread 模块(2016.4.17完成雏形)
* [ ] 容器类部分使用模块 java-container
* [ ] IO 部分使用模块 java-io
-* [ ] java虚拟机相关部分使用模块 java-jvm
-* [ ] java 8 新特性使用模块 java8
+* [ ] Java 虚拟机相关部分使用模块 java-jvm
+* [ ] Java 8 新特性使用模块 java8
-----
diff --git a/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java b/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
index 9481ada..2c4b171 100644
--- a/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
+++ b/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java
@@ -33,7 +33,7 @@ public static void basic(String infile, String outfile) throws IOException {
/**
* 文本文件输出的快捷方式
*/
- public static void shortcut(String infile, String outfile)throws IOException{
+ public static void shortcut(String infile, String outfile) throws IOException {
BufferedReader in = new BufferedReader(
new StringReader(
BufferedInputFile.read(infile)));
@@ -54,7 +54,7 @@ public static void main(String[] args) throws IOException {
String outfile = parent + "/BasicOut";
basic(infile, outfile);
- outfile = parent+"ShortcutOut";
- shortcut(infile,outfile);
+ outfile = parent + "ShortcutOut";
+ shortcut(infile, outfile);
}
}
From 4a04b689f7e461bb7318ca5f47cad13849fab9f9 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Wed, 30 Nov 2016 20:01:12 +0800
Subject: [PATCH 10/57] [fix] rename the folder of java-multithread
---
README.md | 2 +-
java-multithread/pom.xml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 9021dca..044b571 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# 我的java学习笔记
+# 我的 Java 学习笔记
旨在打造在线最佳的 Java 学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解 Java 基础语法,想进一步深入学习的人
diff --git a/java-multithread/pom.xml b/java-multithread/pom.xml
index 4757ef8..c9f06fe 100644
--- a/java-multithread/pom.xml
+++ b/java-multithread/pom.xml
@@ -9,7 +9,7 @@
4.0.0
- java-multihread
+ java-multithread
From c0170486f5783e4882ba1977607dd7c22f4e79ca Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Thu, 1 Dec 2016 13:08:34 +0800
Subject: [PATCH 11/57] [add] add some examples of concurrency
---
.../java/concurrent/CachedThreadPool.java | 17 +++++
.../java/concurrent/CallableDemo.java | 49 ++++++++++++++
.../concurrent/CaptureUncaughtException.java | 59 +++++++++++++++++
.../java/concurrent/DaemonFromFactory.java | 30 +++++++++
.../java/concurrent/DaemonThreadFactory.java | 15 +++++
.../concurrent/DaemonsDontRunFinally.java | 37 +++++++++++
.../java/concurrent/FixedThreadPool.java | 17 +++++
.../learning/java/concurrent/Joining.java | 64 +++++++++++++++++++
.../learning/java/concurrent/LiftOff.java | 29 +++++++++
.../java/concurrent/MoreBasicThreads.java | 13 ++++
.../java/concurrent/SimpleDaemons.java | 45 +++++++++++++
.../java/concurrent/SingleThreadExecutor.java | 17 +++++
.../java/concurrent/SleepingTask.java | 30 +++++++++
.../synchronize/example13/Run13_inner01.java | 1 +
.../synchronize/example13/Run13_inner02.java | 6 ++
15 files changed, 429 insertions(+)
create mode 100644 java-multithread/src/main/java/com/brianway/learning/java/concurrent/CachedThreadPool.java
create mode 100644 java-multithread/src/main/java/com/brianway/learning/java/concurrent/CallableDemo.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/CaptureUncaughtException.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonFromFactory.java
create mode 100644 java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonThreadFactory.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonsDontRunFinally.java
create mode 100644 java-multithread/src/main/java/com/brianway/learning/java/concurrent/FixedThreadPool.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/Joining.java
create mode 100644 java-multithread/src/main/java/com/brianway/learning/java/concurrent/LiftOff.java
create mode 100644 java-multithread/src/main/java/com/brianway/learning/java/concurrent/MoreBasicThreads.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/SimpleDaemons.java
create mode 100644 java-multithread/src/main/java/com/brianway/learning/java/concurrent/SingleThreadExecutor.java
create mode 100644 java-multithread/src/main/java/com/brianway/learning/java/concurrent/SleepingTask.java
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CachedThreadPool.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CachedThreadPool.java
new file mode 100644
index 0000000..5c00c5d
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CachedThreadPool.java
@@ -0,0 +1,17 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Created by brian on 16/11/30.
+ */
+public class CachedThreadPool {
+ public static void main(String[] args) {
+ ExecutorService exec = Executors.newCachedThreadPool();
+ for (int i = 0; i < 5; i++) {
+ exec.execute(new LiftOff());
+ }
+ exec.shutdown();
+ }
+}
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CallableDemo.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CallableDemo.java
new file mode 100644
index 0000000..6bf07d6
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CallableDemo.java
@@ -0,0 +1,49 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.ArrayList;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Created by brian on 16/11/30.
+ */
+public class CallableDemo {
+ public static void main(String[] args) {
+ ExecutorService exec = Executors.newCachedThreadPool();
+ ArrayList> results = new ArrayList<>();
+
+ for (int i = 0; i < 10; i++) {
+ results.add(exec.submit(new TaskWithResult(i)));
+ }
+
+ for (Future fs : results) {
+ try {
+ System.out.println(fs.get());
+ } catch (InterruptedException e) {
+ System.out.println(e);
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ System.out.println(e);
+ e.printStackTrace();
+ } finally {
+ exec.shutdown();
+ }
+ }
+ }
+}
+
+class TaskWithResult implements Callable {
+ private int id;
+
+ public TaskWithResult(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public String call() throws Exception {
+ return "result of TaskWithResult " + id;
+ }
+}
\ No newline at end of file
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CaptureUncaughtException.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CaptureUncaughtException.java
new file mode 100755
index 0000000..07c4c60
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CaptureUncaughtException.java
@@ -0,0 +1,59 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * TODO 为什么有两个线程?
+ */
+public class CaptureUncaughtException {
+ public static void main(String[] args) {
+ ExecutorService exec = Executors.newCachedThreadPool(
+ new HandlerThreadFactory());
+ exec.execute(new ExceptionThread());
+ }
+}
+
+class ExceptionThread implements Runnable {
+ public void run() {
+ Thread t = Thread.currentThread();
+ System.out.println("run() by " + t);
+ System.out.println(
+ "eh = " + t.getUncaughtExceptionHandler());
+ throw new RuntimeException();
+ }
+}
+
+class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
+ public void uncaughtException(Thread t, Throwable e) {
+ System.out.println("caught " + e + " in " + t);
+ }
+}
+
+class HandlerThreadFactory implements ThreadFactory {
+ public Thread newThread(Runnable r) {
+ System.out.println(this + " creating new Thread");
+ Thread t = new Thread(r);
+ System.out.println("created " + t);
+ t.setUncaughtExceptionHandler(
+ new MyUncaughtExceptionHandler());
+ System.out.println(
+ "eh = " + t.getUncaughtExceptionHandler());
+ return t;
+ }
+}
+
+
+
+/* Output: (90% match)
+com.brianway.learning.java.concurrent.HandlerThreadFactory@266474c2 creating new Thread
+created Thread[Thread-0,5,main]
+eh = com.brianway.learning.java.concurrent.MyUncaughtExceptionHandler@6f94fa3e
+run() by Thread[Thread-0,5,main]
+eh = com.brianway.learning.java.concurrent.MyUncaughtExceptionHandler@6f94fa3e
+com.brianway.learning.java.concurrent.HandlerThreadFactory@266474c2 creating new Thread
+created Thread[Thread-1,5,main]
+eh = com.brianway.learning.java.concurrent.MyUncaughtExceptionHandler@3ff961b5
+caught java.lang.RuntimeException in Thread[Thread-0,5,main]
+*///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonFromFactory.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonFromFactory.java
new file mode 100755
index 0000000..46004ff
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonFromFactory.java
@@ -0,0 +1,30 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Using a Thread Factory to create daemons.
+ */
+public class DaemonFromFactory implements Runnable {
+ public void run() {
+ try {
+ while (true) {
+ TimeUnit.MILLISECONDS.sleep(100);
+ System.out.println(Thread.currentThread() + " " + this);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Interrupted");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ ExecutorService exec = Executors.newCachedThreadPool(
+ new DaemonThreadFactory());
+ for (int i = 0; i < 10; i++)
+ exec.execute(new DaemonFromFactory());
+ System.out.println("All daemons started");
+ TimeUnit.MILLISECONDS.sleep(500); // Run for a while
+ }
+} /* (Execute to see output) *///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonThreadFactory.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonThreadFactory.java
new file mode 100644
index 0000000..506f98b
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonThreadFactory.java
@@ -0,0 +1,15 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * Created by brian on 16/12/1.
+ */
+public class DaemonThreadFactory implements ThreadFactory {
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ t.setDaemon(true);
+ return t;
+ }
+}
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonsDontRunFinally.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonsDontRunFinally.java
new file mode 100755
index 0000000..86de25b
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonsDontRunFinally.java
@@ -0,0 +1,37 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Daemon threads don't run the finally clause
+ *
+ * output:"Starting ADaemon" or nothing
+ */
+
+public class DaemonsDontRunFinally {
+ public static void main(String[] args) throws Exception {
+ Thread t = new Thread(new ADaemon());
+ t.setDaemon(true);
+ t.start();
+ }
+}
+
+class ADaemon implements Runnable {
+ public void run() {
+ try {
+ System.out.println("Starting ADaemon");
+ TimeUnit.SECONDS.sleep(1);
+ } catch (InterruptedException e) {
+ System.out.println("Exiting via InterruptedException");
+ } finally {
+ System.out.println("This should always run?");
+ }
+ }
+}
+/* Output:
+Starting ADaemon
+
+or
+
+output nothing
+*///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/FixedThreadPool.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/FixedThreadPool.java
new file mode 100644
index 0000000..fe9f063
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/FixedThreadPool.java
@@ -0,0 +1,17 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Created by brian on 16/11/30.
+ */
+public class FixedThreadPool {
+ public static void main(String[] args) {
+ ExecutorService exec = Executors.newFixedThreadPool(5);
+ for (int i = 0; i < 5; i++) {
+ exec.execute(new LiftOff());
+ }
+ exec.shutdown();
+ }
+}
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Joining.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Joining.java
new file mode 100755
index 0000000..a3e5532
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Joining.java
@@ -0,0 +1,64 @@
+package com.brianway.learning.java.concurrent;
+
+/**
+ * Understanding join().
+ *
+ * 异常捕获时将清理标志位
+ */
+class Sleeper extends Thread {
+ private int duration;
+
+ public Sleeper(String name, int sleepTime) {
+ super(name);
+ duration = sleepTime;
+ start();
+ }
+
+ public void run() {
+ try {
+ sleep(duration);
+ } catch (InterruptedException e) {
+ System.out.println(getName() + " was interrupted. " +
+ "isInterrupted(): " + isInterrupted());
+ return;
+ }
+ System.out.println(getName() + " has awakened");
+ }
+}
+
+class Joiner extends Thread {
+ private Sleeper sleeper;
+
+ public Joiner(String name, Sleeper sleeper) {
+ super(name);
+ this.sleeper = sleeper;
+ start();
+ }
+
+ public void run() {
+ try {
+ sleeper.join();
+ } catch (InterruptedException e) {
+ System.out.println("Interrupted");
+ }
+ System.out.println(getName() + " join completed");
+ }
+}
+
+public class Joining {
+ public static void main(String[] args) {
+ Sleeper
+ sleepy = new Sleeper("Sleepy", 1500),
+ grumpy = new Sleeper("Grumpy", 1500);
+ Joiner
+ dopey = new Joiner("Dopey", sleepy),
+ doc = new Joiner("Doc", grumpy);
+ grumpy.interrupt();
+ }
+}
+/* Output:
+Grumpy was interrupted. isInterrupted(): false
+Doc join completed
+Sleepy has awakened
+Dopey join completed
+*///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/LiftOff.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/LiftOff.java
new file mode 100644
index 0000000..c42f9cf
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/LiftOff.java
@@ -0,0 +1,29 @@
+package com.brianway.learning.java.concurrent;
+
+/**
+ * Created by brian on 16/11/30.
+ */
+public class LiftOff implements Runnable {
+ protected int countDown = 10;
+ private static int taskCount = 0;
+ private final int id = taskCount++;
+
+ public LiftOff() {
+ }
+
+ public LiftOff(int countDown) {
+ this.countDown = countDown;
+ }
+
+ public String status() {
+ return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff!") + "), ";
+ }
+
+ @Override
+ public void run() {
+ while (countDown-- > 0) {
+ System.out.print(status());
+ Thread.yield();
+ }
+ }
+}
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/MoreBasicThreads.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/MoreBasicThreads.java
new file mode 100644
index 0000000..0aec425
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/MoreBasicThreads.java
@@ -0,0 +1,13 @@
+package com.brianway.learning.java.concurrent;
+
+/**
+ * Created by brian on 16/11/30.
+ */
+public class MoreBasicThreads {
+ public static void main(String[] args) {
+ for (int i = 0; i < 5; i++) {
+ new Thread(new LiftOff()).start();
+ }
+ System.out.println("Waiting for LiftOff");
+ }
+}
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SimpleDaemons.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SimpleDaemons.java
new file mode 100755
index 0000000..6a6d477
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SimpleDaemons.java
@@ -0,0 +1,45 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Daemon threads don't prevent the program from ending.
+ */
+public class SimpleDaemons implements Runnable {
+ public void run() {
+ try {
+ while (true) {
+ TimeUnit.MILLISECONDS.sleep(100);
+ System.out.println(Thread.currentThread() + " " + this);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("sleep() interrupted");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ for (int i = 0; i < 10; i++) {
+ Thread daemon = new Thread(new SimpleDaemons());
+ daemon.setDaemon(true); // Must call before start()
+ daemon.start();
+ }
+ System.out.println("All daemons started");
+ TimeUnit.MILLISECONDS.sleep(175);
+ }
+}
+
+/* Output: (Sample)
+All daemons started
+Thread[Thread-8,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@1ec8f532
+Thread[Thread-4,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@17d10736
+Thread[Thread-1,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@2eec0173
+Thread[Thread-0,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@78f0e569
+Thread[Thread-5,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@572f3b73
+Thread[Thread-6,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@6c8d15b7
+Thread[Thread-2,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@31229a57
+Thread[Thread-3,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@4059e324
+Thread[Thread-9,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@32e39829
+Thread[Thread-7,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@45401023
+
+...
+*///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SingleThreadExecutor.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SingleThreadExecutor.java
new file mode 100644
index 0000000..dc70e5c
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SingleThreadExecutor.java
@@ -0,0 +1,17 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Created by brian on 16/11/30.
+ */
+public class SingleThreadExecutor {
+ public static void main(String[] args) {
+ ExecutorService exec = Executors.newSingleThreadExecutor();
+ for (int i = 0; i < 5; i++) {
+ exec.execute(new LiftOff());
+ }
+ exec.shutdown();
+ }
+}
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SleepingTask.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SleepingTask.java
new file mode 100644
index 0000000..b53f1f4
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SleepingTask.java
@@ -0,0 +1,30 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by brian on 16/11/30.
+ */
+public class SleepingTask extends LiftOff {
+ @Override
+ public void run() {
+ try {
+ while (countDown-- > 0) {
+ System.out.print(status());
+ TimeUnit.MILLISECONDS.sleep(100);
+ }
+ } catch (InterruptedException e) {
+ System.err.println("Interrupted");
+ }
+ }
+
+ public static void main(String[] args) {
+ ExecutorService exec = Executors.newCachedThreadPool();
+ for (int i = 0; i < 5; i++) {
+ exec.execute(new SleepingTask());
+ }
+ exec.shutdown();
+ }
+}
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java
index 8e3b8c2..21bbe0c 100644
--- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java
+++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java
@@ -6,6 +6,7 @@
* P112
* 内置类和同步测试1
*/
+
import com.brianway.learning.java.multithread.synchronize.example13.OutClass.Inner;
public class Run13_inner01 {
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java
index d2e9630..b93a5b7 100644
--- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java
+++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java
@@ -8,6 +8,12 @@
*
* T1和T3竞争in2的锁。只有T1结束,T3才能开始;或者T3结束,T1才能开始
* T2与另外两个没关系,因为其锁对象是in2
+ *
+ * P112
+ * 内置类与同步测试2
+ *
+ * T1和T3竞争in2的锁。只有T1结束,T3才能开始;或者T3结束,T1才能开始
+ * T2与另外两个没关系,因为其锁对象是in2
*/
/**
From 50a4d82300fd834e6b4c7864b29cfe95ebe5c490 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Thu, 1 Dec 2016 20:06:59 +0800
Subject: [PATCH 12/57] [add] add some examples of concurrency,especially
BlockingQueue
---
.../java/concurrent/CloseResource.java | 43 +++++
.../java/concurrent/Interrupting.java | 106 +++++++++++
.../java/concurrent/InterruptingIdiom.java | 83 +++++++++
.../java/concurrent/OrnamentalGarden.java | 101 ++++++++++
.../learning/java/concurrent/PipedIO.java | 71 +++++++
.../java/concurrent/TestBlockingQueues.java | 77 ++++++++
.../learning/java/concurrent/ToastOMatic.java | 174 ++++++++++++++++++
7 files changed, 655 insertions(+)
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/CloseResource.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/Interrupting.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/InterruptingIdiom.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/OrnamentalGarden.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/PipedIO.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/TestBlockingQueues.java
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/ToastOMatic.java
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CloseResource.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CloseResource.java
new file mode 100755
index 0000000..7a5ded2
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CloseResource.java
@@ -0,0 +1,43 @@
+package com.brianway.learning.java.concurrent;
+
+import java.io.InputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Interrupting a blocked task by closing the underlying resource.
+ * {RunByHand}
+ */
+public class CloseResource {
+ public static void main(String[] args) throws Exception {
+ ExecutorService exec = Executors.newCachedThreadPool();
+ ServerSocket server = new ServerSocket(8080);
+ InputStream socketInput =
+ new Socket("localhost", 8080).getInputStream();
+ exec.execute(new IOBlocked(socketInput));
+ exec.execute(new IOBlocked(System.in));
+ TimeUnit.MILLISECONDS.sleep(100);
+ System.out.println("Shutting down all threads");
+ exec.shutdownNow();
+ TimeUnit.SECONDS.sleep(1);
+ System.out.println("Closing " + socketInput.getClass().getName());
+ socketInput.close(); // Releases blocked thread
+ TimeUnit.SECONDS.sleep(1);
+ System.out.println("Closing " + System.in.getClass().getName());
+ System.in.close(); // Releases blocked thread
+ }
+}
+
+/* Output: (85% match)
+Waiting for read():
+Waiting for read():
+Shutting down all threads
+Closing java.net.SocketInputStream
+Interrupted from blocked I/O
+Exiting IOBlocked.run()
+Closing java.io.BufferedInputStream
+Exiting IOBlocked.run()
+*///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Interrupting.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Interrupting.java
new file mode 100755
index 0000000..1118727
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Interrupting.java
@@ -0,0 +1,106 @@
+package com.brianway.learning.java.concurrent;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Interrupting a blocked thread.
+ *
+ *
+ */
+public class Interrupting {
+ private static ExecutorService exec =
+ Executors.newCachedThreadPool();
+
+ static void test(Runnable r) throws InterruptedException {
+ Future> f = exec.submit(r);
+ TimeUnit.MILLISECONDS.sleep(100);
+ System.out.println("Interrupting " + r.getClass().getSimpleName());
+ f.cancel(true); // Interrupts if running
+ System.out.println("Interrupt sent to " + r.getClass().getSimpleName());
+ }
+
+ public static void main(String[] args) throws Exception {
+ test(new SleepBlocked());
+ test(new IOBlocked(System.in));
+ test(new SynchronizedBlocked());
+ TimeUnit.SECONDS.sleep(3);
+ System.out.println("Aborting with System.exit(0)");
+ System.exit(0); // ... since last 2 interrupts failed
+ }
+}
+
+/**
+ * 可中断的阻塞示例
+ */
+class SleepBlocked implements Runnable {
+ public void run() {
+ try {
+ TimeUnit.SECONDS.sleep(100);
+ } catch (InterruptedException e) {
+ System.out.println("InterruptedException");
+ }
+ System.out.println("Exiting SleepBlocked.run()");
+ }
+}
+
+class IOBlocked implements Runnable {
+ private InputStream in;
+
+ public IOBlocked(InputStream is) {
+ in = is;
+ }
+
+ public void run() {
+ try {
+ System.out.println("Waiting for read():");
+ in.read();
+ } catch (IOException e) {
+ if (Thread.currentThread().isInterrupted()) {
+ System.out.println("Interrupted from blocked I/O");
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ System.out.println("Exiting IOBlocked.run()");
+ }
+}
+
+class SynchronizedBlocked implements Runnable {
+ public synchronized void f() {
+ while (true) // Never releases lock
+ Thread.yield();
+ }
+
+ public SynchronizedBlocked() {
+ new Thread() {
+ public void run() {
+ f(); // Lock acquired by this thread
+ }
+ }.start();
+ }
+
+ public void run() {
+ System.out.println("Trying to call f()");
+ f();
+ System.out.println("Exiting SynchronizedBlocked.run()");
+ }
+}
+
+/* Output: (95% match)
+Interrupting SleepBlocked
+Interrupt sent to SleepBlocked
+InterruptedException
+Exiting SleepBlocked.run()
+Waiting for read():
+Interrupting IOBlocked
+Interrupt sent to IOBlocked
+Trying to call f()
+Interrupting SynchronizedBlocked
+Interrupt sent to SynchronizedBlocked
+Aborting with System.exit(0)
+*///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/InterruptingIdiom.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/InterruptingIdiom.java
new file mode 100755
index 0000000..208db8d
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/InterruptingIdiom.java
@@ -0,0 +1,83 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * General idiom for interrupting a task.
+ * {Args: 1100}
+ */
+public class InterruptingIdiom {
+ public static void main(String[] args) throws Exception {
+ if (args.length != 1) {
+ System.out.println("usage: java InterruptingIdiom delay-in-mS");
+ System.exit(1);
+ }
+ Thread t = new Thread(new Blocked3());
+ t.start();
+ TimeUnit.MILLISECONDS.sleep(new Integer(args[0]));
+ t.interrupt();
+ }
+}
+
+class NeedsCleanup {
+ private final int id;
+
+ public NeedsCleanup(int ident) {
+ id = ident;
+ System.out.println("NeedsCleanup " + id);
+ }
+
+ public void cleanup() {
+ System.out.println("Cleaning up " + id);
+ }
+}
+
+class Blocked3 implements Runnable {
+ private volatile double d = 0.0;
+
+ public void run() {
+ try {
+ while (!Thread.interrupted()) {
+ // point1
+ NeedsCleanup n1 = new NeedsCleanup(1);
+ // Start try-finally immediately after definition
+ // of n1, to guarantee proper cleanup of n1:
+ try {
+ System.out.println("Sleeping");
+ TimeUnit.SECONDS.sleep(1);
+ // point2
+ NeedsCleanup n2 = new NeedsCleanup(2);
+ // Guarantee proper cleanup of n2:
+ try {
+ System.out.println("Calculating");
+ // A time-consuming, non-blocking operation:
+ for (int i = 1; i < 2500000; i++)
+ d = d + (Math.PI + Math.E) / d;
+ System.out.println("Finished time-consuming operation");
+ } finally {
+ n2.cleanup();
+ }
+ } finally {
+ n1.cleanup();
+ }
+ }
+ System.out.println("Exiting via while() test");
+ } catch (InterruptedException e) {
+ System.out.println("Exiting via InterruptedException");
+ }
+ }
+}
+
+/* Output: (Sample)
+NeedsCleanup 1
+Sleeping
+NeedsCleanup 2
+Calculating
+Finished time-consuming operation
+Cleaning up 2
+Cleaning up 1
+NeedsCleanup 1
+Sleeping
+Cleaning up 1
+Exiting via InterruptedException
+*///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/OrnamentalGarden.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/OrnamentalGarden.java
new file mode 100755
index 0000000..11a0eca
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/OrnamentalGarden.java
@@ -0,0 +1,101 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+class Count {
+ private int count = 0;
+ private Random rand = new Random(47);
+
+ // Remove the synchronized keyword to see counting fail:
+ public synchronized int increment() {
+ int temp = count;
+ if (rand.nextBoolean()) // Yield half the time
+ {
+ Thread.yield();
+ }
+ return (count = ++temp);
+ }
+
+ public synchronized int value() {
+ return count;
+ }
+}
+
+class Entrance implements Runnable {
+ private static Count count = new Count();
+ private static List entrances =
+ new ArrayList();
+ private int number = 0;
+ // Doesn't need synchronization to read:
+ private final int id;
+ private static volatile boolean canceled = false;
+
+ // Atomic operation on a volatile field:
+ public static void cancel() {
+ canceled = true;
+ }
+
+ public Entrance(int id) {
+ this.id = id;
+ // Keep this task in a list. Also prevents
+ // garbage collection of dead tasks:
+ entrances.add(this);
+ }
+
+ public void run() {
+ while (!canceled) {
+ synchronized (this) {
+ ++number;
+ }
+ System.out.println(this + " Total: " + count.increment());
+ try {
+ TimeUnit.MILLISECONDS.sleep(100);
+ } catch (InterruptedException e) {
+ System.out.println("sleep interrupted");
+ }
+ }
+ System.out.println("Stopping " + this);
+ }
+
+ public synchronized int getValue() {
+ return number;
+ }
+
+ public String toString() {
+ return "Entrance " + id + ": " + getValue();
+ }
+
+ public static int getTotalCount() {
+ return count.value();
+ }
+
+ public static int sumEntrances() {
+ int sum = 0;
+ for (Entrance entrance : entrances)
+ sum += entrance.getValue();
+ return sum;
+ }
+}
+
+public class OrnamentalGarden {
+ public static void main(String[] args) throws Exception {
+ ExecutorService exec = Executors.newCachedThreadPool();
+ for (int i = 0; i < 5; i++)
+ exec.execute(new Entrance(i));
+ // Run for a while, then stop and collect the data:
+ TimeUnit.SECONDS.sleep(3);
+ Entrance.cancel();
+ exec.shutdown();
+ if (!exec.awaitTermination(250, TimeUnit.MILLISECONDS)) {
+ System.out.println("Some tasks were not terminated!");
+ }
+ System.out.println("Total: " + Entrance.getTotalCount());
+ System.out.println("Sum of Entrances: " + Entrance.sumEntrances());
+ }
+}
+
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/PipedIO.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/PipedIO.java
new file mode 100755
index 0000000..b21de44
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/PipedIO.java
@@ -0,0 +1,71 @@
+package com.brianway.learning.java.concurrent;
+
+import java.io.IOException;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Using pipes for inter-task I/O
+ */
+public class PipedIO {
+ public static void main(String[] args) throws Exception {
+ Sender sender = new Sender();
+ Receiver receiver = new Receiver(sender);
+ ExecutorService exec = Executors.newCachedThreadPool();
+ exec.execute(sender);
+ exec.execute(receiver);
+ TimeUnit.SECONDS.sleep(4);
+ exec.shutdownNow();
+ }
+}
+
+class Sender implements Runnable {
+ private Random rand = new Random(47);
+ private PipedWriter out = new PipedWriter();
+
+ public PipedWriter getPipedWriter() {
+ return out;
+ }
+
+ public void run() {
+ try {
+ while (true)
+ for (char c = 'A'; c <= 'z'; c++) {
+ out.write(c);
+ TimeUnit.MILLISECONDS.sleep(rand.nextInt(500));
+ }
+ } catch (IOException e) {
+ System.out.println(e + " Sender write exception");
+ } catch (InterruptedException e) {
+ System.out.println(e + " Sender sleep interrupted");
+ }
+ }
+}
+
+class Receiver implements Runnable {
+ private PipedReader in;
+
+ public Receiver(Sender sender) throws IOException {
+ in = new PipedReader(sender.getPipedWriter());
+ }
+
+ public void run() {
+ try {
+ while (true) {
+ // Blocks until characters are there:
+ System.out.print("Read: " + (char) in.read() + ", ");
+ }
+ } catch (IOException e) {
+ System.out.println(e + " Receiver read exception");
+ }
+ }
+}
+
+/* Output: (65% match)
+Read: A, Read: B, Read: C, Read: D, Read: E, Read: F, Read: G, Read: H, Read: I, Read: J, Read: K, Read: L, Read: M, java.lang.InterruptedException: sleep interrupted Sender sleep interrupted
+java.io.InterruptedIOException Receiver read exception
+*///:~
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/TestBlockingQueues.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/TestBlockingQueues.java
new file mode 100755
index 0000000..9591ad7
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/TestBlockingQueues.java
@@ -0,0 +1,77 @@
+package com.brianway.learning.java.concurrent;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+
+public class TestBlockingQueues {
+ static void getkey() {
+ try {
+ // Compensate for Windows/Linux difference in the
+ // length of the result produced by the Enter key:
+ new BufferedReader(
+ new InputStreamReader(System.in)).readLine();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static void getkey(String message) {
+ System.out.println(message);
+ getkey();
+ }
+
+ static void test(String msg, BlockingQueue queue) {
+ System.out.println(msg);
+ LiftOffRunner runner = new LiftOffRunner(queue);
+ Thread t = new Thread(runner);
+ t.start();
+ for (int i = 0; i < 5; i++) {
+ runner.add(new LiftOff(5));
+ }
+ getkey("Press 'Enter' (" + msg + ")");
+ t.interrupt();
+ System.out.println("Finished " + msg + " test");
+ }
+
+ public static void main(String[] args) {
+ test("LinkedBlockingQueue", // Unlimited size
+ new LinkedBlockingQueue());
+ test("ArrayBlockingQueue", // Fixed size
+ new ArrayBlockingQueue(3));
+ test("SynchronousQueue", // Size of 1
+ new SynchronousQueue());
+ }
+}
+
+class LiftOffRunner implements Runnable {
+ private BlockingQueue rockets;
+
+ public LiftOffRunner(BlockingQueue queue) {
+ rockets = queue;
+ }
+
+ public void add(LiftOff lo) {
+ try {
+ rockets.put(lo);
+ } catch (InterruptedException e) {
+ System.out.println("Interrupted during put()");
+ }
+ }
+
+ public void run() {
+ try {
+ while (!Thread.interrupted()) {
+ LiftOff rocket = rockets.take();
+ rocket.run(); // Use this thread
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Waking from take()");
+ }
+ System.out.println("Exiting LiftOffRunner");
+ }
+}
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/ToastOMatic.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/ToastOMatic.java
new file mode 100755
index 0000000..021668a
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/ToastOMatic.java
@@ -0,0 +1,174 @@
+package com.brianway.learning.java.concurrent;
+
+/**
+ * A toaster that uses queues.
+ */
+
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class ToastOMatic {
+ public static void main(String[] args) throws Exception {
+ ToastQueue dryQueue = new ToastQueue(),
+ butteredQueue = new ToastQueue(),
+ finishedQueue = new ToastQueue();
+ ExecutorService exec = Executors.newCachedThreadPool();
+ exec.execute(new Toaster(dryQueue));
+ exec.execute(new Butterer(dryQueue, butteredQueue));
+ exec.execute(new Jammer(butteredQueue, finishedQueue));
+ exec.execute(new Eater(finishedQueue));
+ TimeUnit.SECONDS.sleep(5);
+ exec.shutdownNow();
+ }
+}
+
+class Toast {
+ public enum Status {
+ DRY,
+ BUTTERED,
+ JAMMED
+ }
+
+ private Status status = Status.DRY;
+ private final int id;
+
+ public Toast(int idn) {
+ id = idn;
+ }
+
+ public void butter() {
+ status = Status.BUTTERED;
+ }
+
+ public void jam() {
+ status = Status.JAMMED;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String toString() {
+ return "Toast " + id + ": " + status;
+ }
+}
+
+class ToastQueue extends LinkedBlockingQueue {
+}
+
+class Toaster implements Runnable {
+ private ToastQueue toastQueue;
+ private int count = 0;
+ private Random rand = new Random(47);
+
+ public Toaster(ToastQueue tq) {
+ toastQueue = tq;
+ }
+
+ public void run() {
+ try {
+ while (!Thread.interrupted()) {
+ TimeUnit.MILLISECONDS.sleep(
+ 100 + rand.nextInt(500));
+ // Make toast
+ Toast t = new Toast(count++);
+ System.out.println(t);
+ // Insert into queue
+ toastQueue.put(t);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Toaster interrupted");
+ }
+ System.out.println("Toaster off");
+ }
+}
+
+// Apply butter to toast:
+class Butterer implements Runnable {
+ private ToastQueue dryQueue, butteredQueue;
+
+ public Butterer(ToastQueue dry, ToastQueue buttered) {
+ dryQueue = dry;
+ butteredQueue = buttered;
+ }
+
+ public void run() {
+ try {
+ while (!Thread.interrupted()) {
+ // Blocks until next piece of toast is available:
+ Toast t = dryQueue.take();
+ t.butter();
+ System.out.println(t);
+ butteredQueue.put(t);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Butterer interrupted");
+ }
+ System.out.println("Butterer off");
+ }
+}
+
+// Apply jam to buttered toast:
+class Jammer implements Runnable {
+ private ToastQueue butteredQueue, finishedQueue;
+
+ public Jammer(ToastQueue buttered, ToastQueue finished) {
+ butteredQueue = buttered;
+ finishedQueue = finished;
+ }
+
+ public void run() {
+ try {
+ while (!Thread.interrupted()) {
+ // Blocks until next piece of toast is available:
+ Toast t = butteredQueue.take();
+ t.jam();
+ System.out.println(t);
+ finishedQueue.put(t);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Jammer interrupted");
+ }
+ System.out.println("Jammer off");
+ }
+}
+
+// Consume the toast:
+class Eater implements Runnable {
+ private ToastQueue finishedQueue;
+ private int counter = 0;
+
+ public Eater(ToastQueue finished) {
+ finishedQueue = finished;
+ }
+
+ public void run() {
+ try {
+ while (!Thread.interrupted()) {
+ // Blocks until next piece of toast is available:
+ Toast t = finishedQueue.take();
+ // Verify that the toast is coming in order,
+ // and that all pieces are getting jammed:
+ if (t.getId() != counter++ ||
+ t.getStatus() != Toast.Status.JAMMED) {
+ System.out.println(">>>> Error: " + t);
+ System.exit(1);
+ } else {
+ System.out.println("Chomp! " + t);
+ }
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Eater interrupted");
+ }
+ System.out.println("Eater off");
+ }
+}
+
+/* (Execute to see output) *///:~
From b1bdbe144b9e08f46f7b31e7b5f3c810f39cf9d8 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Tue, 6 Dec 2016 20:15:37 +0800
Subject: [PATCH 13/57] [add] add CountDownLatch example
---
.../java/concurrent/CountDownLatchDemo.java | 81 +++++++++++++++++++
1 file changed, 81 insertions(+)
create mode 100755 java-multithread/src/main/java/com/brianway/learning/java/concurrent/CountDownLatchDemo.java
diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CountDownLatchDemo.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CountDownLatchDemo.java
new file mode 100755
index 0000000..5c3fcf9
--- /dev/null
+++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CountDownLatchDemo.java
@@ -0,0 +1,81 @@
+package com.brianway.learning.java.concurrent;
+
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+public class CountDownLatchDemo {
+ static final int SIZE = 10;
+
+ public static void main(String[] args) throws Exception {
+ ExecutorService exec = Executors.newCachedThreadPool();
+ // All must share a single CountDownLatch object:
+ CountDownLatch latch = new CountDownLatch(SIZE);
+ for (int i = 0; i < 10; i++)
+ exec.execute(new WaitingTask(latch));
+ for (int i = 0; i < SIZE; i++)
+ exec.execute(new TaskPortion(latch));
+ System.out.println("Launched all tasks");
+ exec.shutdown(); // Quit when all tasks complete
+ }
+}
+
+// Performs some portion of a task:
+class TaskPortion implements Runnable {
+ private static int counter = 0;
+ private final int id = counter++;
+ private static Random rand = new Random(47);
+ private final CountDownLatch latch;
+
+ TaskPortion(CountDownLatch latch) {
+ this.latch = latch;
+ }
+
+ public void run() {
+ try {
+ doWork();
+ latch.countDown();
+ latch.await();
+ System.out.println(this + " TaskPortion after await");
+ } catch (InterruptedException ex) {
+ // Acceptable way to exit
+ }
+ }
+
+ public void doWork() throws InterruptedException {
+ TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
+ System.out.println(this + "completed");
+ }
+
+ public String toString() {
+ return String.format("%1$-3d ", id);
+ }
+}
+
+// Waits on the CountDownLatch:
+class WaitingTask implements Runnable {
+ private static int counter = 0;
+ private final int id = counter++;
+ private final CountDownLatch latch;
+
+ WaitingTask(CountDownLatch latch) {
+ this.latch = latch;
+ }
+
+ public void run() {
+ try {
+ latch.await();
+ System.out.println("Latch barrier passed for " + this);
+ } catch (InterruptedException ex) {
+ System.out.println(this + " interrupted");
+ }
+ }
+
+ public String toString() {
+ return String.format("WaitingTask %1$-3d ", id);
+ }
+}
+
+/* (Execute to see output) *///:~
From 3dafe096675cecb392555d4d74c2b78af5546285 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Wed, 7 Dec 2016 16:18:44 +0800
Subject: [PATCH 14/57] [add] add examples of type info
---
.../base/typeinfo/BoundedClassReferences.java | 10 +++
.../java/base/typeinfo/ClassCasts.java | 33 ++++++++++
.../base/typeinfo/ClassInitialization.java | 64 +++++++++++++++++++
.../java/base/typeinfo/FamilyVsExactType.java | 54 ++++++++++++++++
.../java/base/typeinfo/FilledList.java | 41 ++++++++++++
.../base/typeinfo/GenericClassReferences.java | 15 +++++
.../base/typeinfo/SimpleDynamicProxy.java | 52 +++++++++++++++
.../java/base/typeinfo/SimpleProxyDemo.java | 56 ++++++++++++++++
.../typeinfo/WildcardClassReferences.java | 8 +++
9 files changed, 333 insertions(+)
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/BoundedClassReferences.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassCasts.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassInitialization.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FamilyVsExactType.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FilledList.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/GenericClassReferences.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleDynamicProxy.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleProxyDemo.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/typeinfo/WildcardClassReferences.java
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/BoundedClassReferences.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/BoundedClassReferences.java
new file mode 100755
index 0000000..c5e7d6f
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/BoundedClassReferences.java
@@ -0,0 +1,10 @@
+package com.brianway.learning.java.base.typeinfo;
+
+public class BoundedClassReferences {
+ public static void main(String[] args) {
+ Class extends Number> bounded = int.class;
+ bounded = double.class;
+ bounded = Number.class;
+ // Or anything else derived from Number.
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassCasts.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassCasts.java
new file mode 100755
index 0000000..da64ce4
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassCasts.java
@@ -0,0 +1,33 @@
+package com.brianway.learning.java.base.typeinfo;
+
+class Building {
+}
+
+class House extends Building {
+}
+
+public class ClassCasts {
+ public static void main(String[] args) {
+ Building b = new House();
+ Class houseType = House.class;
+ House h = houseType.cast(b);
+ h = (House) b; // ... or just do this.
+
+ try {
+ Class hClass = House.class;
+ //Produces exact type
+ House house = hClass.newInstance();
+ Class super House> up = hClass.getSuperclass();
+ // won't compile:
+ //Class up2 = hClass.getSuperclass();
+
+ //Only produces Object
+ Object obj = up.newInstance();
+
+ System.out.println(house);
+ System.out.println(obj);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassInitialization.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassInitialization.java
new file mode 100755
index 0000000..0703121
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassInitialization.java
@@ -0,0 +1,64 @@
+package com.brianway.learning.java.base.typeinfo;
+
+import java.util.Random;
+
+/**
+ * 1.仅使用.class语法来获得对类的引用不会引发初始化
+ * 2."编译器常量",无需类初始化即可读取
+ * 3.static final域不一定是编译器常量,static非final域一定不是
+ */
+public class ClassInitialization {
+ public static Random rand = new Random(47);
+
+ public static void main(String[] args) throws Exception {
+ Class initable = Initable.class;
+ System.out.println("After creating Initable ref");
+ // Does not trigger initialization:
+ System.out.println(Initable.staticFinal);
+ // Does trigger initialization:
+ System.out.println(Initable.staticFinal2);
+ // Does trigger initialization:
+ System.out.println(Initable2.staticNonFinal);
+ Class initable3 = Class.forName("com.brianway.learning.java.base.typeinfo.Initable3");
+ System.out.println("After creating Initable3 ref");
+ System.out.println(Initable3.staticNonFinal);
+ }
+}
+
+class Initable {
+ static final int staticFinal = 47;
+ static final int staticFinal2 =
+ ClassInitialization.rand.nextInt(1000);
+
+ static {
+ System.out.println("Initializing Initable");
+ }
+}
+
+class Initable2 {
+ static int staticNonFinal = 147;
+
+ static {
+ System.out.println("Initializing Initable2");
+ }
+}
+
+class Initable3 {
+ static int staticNonFinal = 74;
+
+ static {
+ System.out.println("Initializing Initable3");
+ }
+}
+
+/* Output:
+After creating Initable ref
+47
+Initializing Initable
+258
+Initializing Initable2
+147
+Initializing Initable3
+After creating Initable3 ref
+74
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FamilyVsExactType.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FamilyVsExactType.java
new file mode 100755
index 0000000..5547fde
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FamilyVsExactType.java
@@ -0,0 +1,54 @@
+package com.brianway.learning.java.base.typeinfo;
+
+/**
+ * The difference between instanceof and class.
+ */
+public class FamilyVsExactType {
+ static void test(Object x) {
+ System.out.println("Testing x of type " + x.getClass());
+ System.out.println("x instanceof Base " + (x instanceof Base));
+ System.out.println("x instanceof Derived " + (x instanceof Derived));
+ System.out.println("Base.isInstance(x) " + Base.class.isInstance(x));
+ System.out.println("Derived.isInstance(x) "
+ + Derived.class.isInstance(x));
+ System.out.println("x.getClass() == Base.class "
+ + (x.getClass() == Base.class));
+ System.out.println("x.getClass() == Derived.class "
+ + (x.getClass() == Derived.class));
+ System.out.println("x.getClass().equals(Base.class)) "
+ + (x.getClass().equals(Base.class)));
+ System.out.println("x.getClass().equals(Derived.class)) "
+ + (x.getClass().equals(Derived.class)));
+ }
+
+ public static void main(String[] args) {
+ test(new Base());
+ test(new Derived());
+ }
+}
+
+class Base {
+}
+
+class Derived extends Base {
+}
+/* Output:
+Testing x of type class typeinfo.Base
+x instanceof Base true
+x instanceof Derived false
+Base.isInstance(x) true
+Derived.isInstance(x) false
+x.getClass() == Base.class true
+x.getClass() == Derived.class false
+x.getClass().equals(Base.class)) true
+x.getClass().equals(Derived.class)) false
+Testing x of type class typeinfo.Derived
+x instanceof Base true
+x instanceof Derived true
+Base.isInstance(x) true
+Derived.isInstance(x) true
+x.getClass() == Base.class false
+x.getClass() == Derived.class true
+x.getClass().equals(Base.class)) false
+x.getClass().equals(Derived.class)) true
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FilledList.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FilledList.java
new file mode 100755
index 0000000..437f452
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FilledList.java
@@ -0,0 +1,41 @@
+package com.brianway.learning.java.base.typeinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class CountedInteger {
+ private static long counter;
+ private final long id = counter++;
+
+ public String toString() {
+ return Long.toString(id);
+ }
+}
+
+public class FilledList {
+ private Class type;
+
+ public FilledList(Class type) {
+ this.type = type;
+ }
+
+ public List create(int nElements) {
+ List result = new ArrayList();
+ try {
+ for (int i = 0; i < nElements; i++)
+ result.add(type.newInstance());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+ FilledList fl =
+ new FilledList(CountedInteger.class);
+ System.out.println(fl.create(15));
+ }
+}
+/* Output:
+[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/GenericClassReferences.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/GenericClassReferences.java
new file mode 100755
index 0000000..23e0718
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/GenericClassReferences.java
@@ -0,0 +1,15 @@
+package com.brianway.learning.java.base.typeinfo;
+
+public class GenericClassReferences {
+ public static void main(String[] args) {
+
+ Class genericIntClass = int.class;
+ genericIntClass = Integer.class; // Same thing
+
+ Class intClass = int.class;
+ intClass = double.class;
+ // genericIntClass = double.class; // Illegal
+
+ System.out.println(int.class == Integer.class);
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleDynamicProxy.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleDynamicProxy.java
new file mode 100755
index 0000000..7b44a9e
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleDynamicProxy.java
@@ -0,0 +1,52 @@
+package com.brianway.learning.java.base.typeinfo;//: typeinfo/SimpleDynamicProxy.java
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+class DynamicProxyHandler implements InvocationHandler {
+ private Object proxied;
+
+ public DynamicProxyHandler(Object proxied) {
+ this.proxied = proxied;
+ }
+
+ public Object
+ invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ System.out.println("**** proxy: " + proxy.getClass().getSimpleName() +
+ ", method: " + method + ", args: " + args);
+ if (args != null) {
+ for (Object arg : args)
+ System.out.println(" " + arg);
+ }
+ return method.invoke(proxied, args);
+ }
+}
+
+class SimpleDynamicProxy {
+ public static void consumer(Interface iface) {
+ iface.doSomething();
+ iface.somethingElse("bonobo");
+ }
+
+ public static void main(String[] args) {
+ RealObject real = new RealObject();
+ consumer(real);
+ // Insert a proxy and call again:
+ Interface proxy = (Interface) Proxy.newProxyInstance(
+ Interface.class.getClassLoader(),
+ new Class[] {Interface.class},
+ new DynamicProxyHandler(real));
+ consumer(proxy);
+ }
+}
+/* Output: (95% match)
+doSomething
+somethingElse bonobo
+**** proxy: $Proxy0, method: public abstract void com.brianway.learning.java.base.typeinfo.Interface.doSomething(), args: null
+doSomething
+**** proxy: $Proxy0, method: public abstract void com.brianway.learning.java.base.typeinfo.Interface.somethingElse(java.lang.String), args: [Ljava.lang.Object;@d716361
+ bonobo
+somethingElse bonobo
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleProxyDemo.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleProxyDemo.java
new file mode 100755
index 0000000..7047cb0
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleProxyDemo.java
@@ -0,0 +1,56 @@
+package com.brianway.learning.java.base.typeinfo;
+
+interface Interface {
+ void doSomething();
+
+ void somethingElse(String arg);
+}
+
+class RealObject implements Interface {
+ public void doSomething() {
+ System.out.println("doSomething");
+ }
+
+ public void somethingElse(String arg) {
+ System.out.println("somethingElse " + arg);
+ }
+}
+
+class SimpleProxy implements Interface {
+ private Interface proxied;
+
+ public SimpleProxy(Interface proxied) {
+ this.proxied = proxied;
+ }
+
+ public void doSomething() {
+ System.out.println("SimpleProxy doSomething");
+ proxied.doSomething();
+ }
+
+ public void somethingElse(String arg) {
+ System.out.println("SimpleProxy somethingElse " + arg);
+ proxied.somethingElse(arg);
+ }
+}
+
+class SimpleProxyDemo {
+ public static void consumer(Interface iface) {
+ iface.doSomething();
+ iface.somethingElse("bonobo");
+ }
+
+ public static void main(String[] args) {
+ consumer(new RealObject());
+ consumer(new SimpleProxy(new RealObject()));
+ }
+}
+
+/* Output:
+doSomething
+somethingElse bonobo
+SimpleProxy doSomething
+doSomething
+SimpleProxy somethingElse bonobo
+somethingElse bonobo
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/WildcardClassReferences.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/WildcardClassReferences.java
new file mode 100755
index 0000000..cca198a
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/WildcardClassReferences.java
@@ -0,0 +1,8 @@
+package com.brianway.learning.java.base.typeinfo;
+
+public class WildcardClassReferences {
+ public static void main(String[] args) {
+ Class> intClass = int.class;
+ intClass = double.class;
+ }
+} ///:~
From d3e2afadcb7a5630a07472f16cf80aca0d9debd6 Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Wed, 7 Dec 2016 23:59:40 +0800
Subject: [PATCH 15/57] [add] add examples of generics
---
.../java/base/generics/ArrayMaker.java | 30 ++++
.../java/base/generics/BasicBounds.java | 118 ++++++++++++++++
.../java/base/generics/ClassTypeCapture.java | 47 +++++++
.../java/base/generics/CovariantArrays.java | 42 ++++++
.../java/base/generics/CreatorGeneric.java | 38 +++++
.../base/generics/ErasedTypeEquivalence.java | 17 +++
.../java/base/generics/FactoryConstraint.java | 39 ++++++
.../java/base/generics/GenericArray.java | 35 +++++
.../java/base/generics/GenericArray2.java | 41 ++++++
.../generics/GenericArrayWithTypeToken.java | 33 +++++
.../java/base/generics/GenericMethods.java | 28 ++++
.../java/base/generics/GenericReading.java | 53 +++++++
.../java/base/generics/GenericVarargs.java | 30 ++++
.../java/base/generics/GenericWriting.java | 36 +++++
.../base/generics/GenericsAndCovariance.java | 21 +++
.../learning/java/base/generics/Holder.java | 47 +++++++
.../java/base/generics/InheritBounds.java | 65 +++++++++
.../base/generics/InstantiateGenericType.java | 35 +++++
.../java/base/generics/LinkedStack.java | 52 +++++++
.../java/base/generics/LostInformation.java | 43 ++++++
.../base/generics/SuperTypeWildcards.java | 20 +++
.../java/base/generics/Wildcards.java | 130 ++++++++++++++++++
22 files changed, 1000 insertions(+)
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/ArrayMaker.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/BasicBounds.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/ClassTypeCapture.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/CovariantArrays.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/CreatorGeneric.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/ErasedTypeEquivalence.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/FactoryConstraint.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray2.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArrayWithTypeToken.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/GenericMethods.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/GenericReading.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/GenericVarargs.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/GenericWriting.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/GenericsAndCovariance.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/Holder.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/InheritBounds.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/InstantiateGenericType.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/LinkedStack.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/LostInformation.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/SuperTypeWildcards.java
create mode 100755 java-base/src/main/java/com/brianway/learning/java/base/generics/Wildcards.java
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/ArrayMaker.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/ArrayMaker.java
new file mode 100755
index 0000000..9045c41
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/ArrayMaker.java
@@ -0,0 +1,30 @@
+package com.brianway.learning.java.base.generics;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+/**
+ * 对于泛型中创建数组,使用Array.newInstance()是推荐的方式
+ */
+public class ArrayMaker {
+ private Class kind;
+
+ public ArrayMaker(Class kind) {
+ this.kind = kind;
+ }
+
+ @SuppressWarnings("unchecked")
+ T[] create(int size) {
+ return (T[]) Array.newInstance(kind, size);
+ }
+
+ public static void main(String[] args) {
+ ArrayMaker stringMaker =
+ new ArrayMaker(String.class);
+ String[] stringArray = stringMaker.create(9);
+ System.out.println(Arrays.toString(stringArray));
+ }
+}
+/* Output:
+[null, null, null, null, null, null, null, null, null]
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/BasicBounds.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/BasicBounds.java
new file mode 100755
index 0000000..7e37d06
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/BasicBounds.java
@@ -0,0 +1,118 @@
+package com.brianway.learning.java.base.generics;
+
+public class BasicBounds {
+ public static void main(String[] args) {
+ Solid solid =
+ new Solid(new Bounded());
+ solid.color();
+ solid.getY();
+ solid.weight();
+ }
+}
+
+interface HasColor {
+ java.awt.Color getColor();
+}
+
+class Colored {
+ T item;
+
+ Colored(T item) {
+ this.item = item;
+ }
+
+ T getItem() {
+ return item;
+ }
+
+ // The bound allows you to call a method:
+ java.awt.Color color() {
+ return item.getColor();
+ }
+}
+
+class Dimension {
+ public int x, y, z;
+}
+
+// This won't work -- class must be first, then interfaces:
+// class ColoredDimension {
+
+// Multiple bounds:
+class ColoredDimension {
+ T item;
+
+ ColoredDimension(T item) {
+ this.item = item;
+ }
+
+ T getItem() {
+ return item;
+ }
+
+ java.awt.Color color() {
+ return item.getColor();
+ }
+
+ int getX() {
+ return item.x;
+ }
+
+ int getY() {
+ return item.y;
+ }
+
+ int getZ() {
+ return item.z;
+ }
+}
+
+interface Weight {
+ int weight();
+}
+
+// As with inheritance, you can have only one
+// concrete class but multiple interfaces:
+class Solid {
+ T item;
+
+ Solid(T item) {
+ this.item = item;
+ }
+
+ T getItem() {
+ return item;
+ }
+
+ java.awt.Color color() {
+ return item.getColor();
+ }
+
+ int getX() {
+ return item.x;
+ }
+
+ int getY() {
+ return item.y;
+ }
+
+ int getZ() {
+ return item.z;
+ }
+
+ int weight() {
+ return item.weight();
+ }
+}
+
+class Bounded
+ extends Dimension implements HasColor, Weight {
+ public java.awt.Color getColor() {
+ return null;
+ }
+
+ public int weight() {
+ return 0;
+ }
+}
+///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/ClassTypeCapture.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/ClassTypeCapture.java
new file mode 100755
index 0000000..4af0aaa
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/ClassTypeCapture.java
@@ -0,0 +1,47 @@
+package com.brianway.learning.java.base.generics;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 擦除的补偿
+ * 显式传递类型的 Class 对象
+ */
+public class ClassTypeCapture {
+ //类型标签
+ Class kind;
+
+ Map> types = new HashMap<>();
+
+ public ClassTypeCapture(Class kind) {
+ this.kind = kind;
+ }
+
+ public boolean f(Object arg) {
+ return kind.isInstance(arg);
+ }
+
+ public static void main(String[] args) {
+ ClassTypeCapture ctt1 =
+ new ClassTypeCapture(Building.class);
+ System.out.println(ctt1.f(new Building()));
+ System.out.println(ctt1.f(new House()));
+ ClassTypeCapture ctt2 =
+ new ClassTypeCapture(House.class);
+ System.out.println(ctt2.f(new Building()));
+ System.out.println(ctt2.f(new House()));
+ }
+}
+
+class Building {
+}
+
+class House extends Building {
+}
+
+/* Output:
+true
+true
+false
+true
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/CovariantArrays.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/CovariantArrays.java
new file mode 100755
index 0000000..ce639a2
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/CovariantArrays.java
@@ -0,0 +1,42 @@
+package com.brianway.learning.java.base.generics;
+
+/**
+ * 通配符相关类的基础类
+ */
+public class CovariantArrays {
+ public static void main(String[] args) {
+ Fruit[] fruit = new Apple[10];
+ fruit[0] = new Apple(); // OK
+ fruit[1] = new Jonathan(); // OK
+ // Runtime type is Apple[], not Fruit[] or Orange[]:
+ try {
+ // Compiler allows you to add Fruit:
+ fruit[0] = new Fruit(); // ArrayStoreException
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ try {
+ // Compiler allows you to add Oranges:
+ fruit[0] = new Orange(); // ArrayStoreException
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ }
+}
+
+class Fruit {
+}
+
+class Apple extends Fruit {
+}
+
+class Jonathan extends Apple {
+}
+
+class Orange extends Fruit {
+}
+
+/* Output:
+java.lang.ArrayStoreException: Fruit
+java.lang.ArrayStoreException: Orange
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/CreatorGeneric.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/CreatorGeneric.java
new file mode 100755
index 0000000..8ccbcf1
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/CreatorGeneric.java
@@ -0,0 +1,38 @@
+package com.brianway.learning.java.base.generics;
+
+/**
+ * 末班方法设计模式
+ */
+public class CreatorGeneric {
+ public static void main(String[] args) {
+ Creator c = new Creator();
+ c.f();
+ }
+}
+
+abstract class GenericWithCreate {
+ final T element;
+
+ GenericWithCreate() {
+ element = create();
+ }
+
+ abstract T create();
+}
+
+class X {
+}
+
+class Creator extends GenericWithCreate {
+ X create() {
+ return new X();
+ }
+
+ void f() {
+ System.out.println(element.getClass().getSimpleName());
+ }
+}
+
+/* Output:
+X
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/ErasedTypeEquivalence.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/ErasedTypeEquivalence.java
new file mode 100755
index 0000000..0050950
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/ErasedTypeEquivalence.java
@@ -0,0 +1,17 @@
+package com.brianway.learning.java.base.generics;
+
+import java.util.ArrayList;
+
+public class ErasedTypeEquivalence {
+ public static void main(String[] args) {
+ Class c1 = new ArrayList().getClass();
+ Class c2 = new ArrayList().getClass();
+ Class c3 = ArrayList.class;
+ System.out.println(c1 == c2);
+ System.out.println(c1 == c3);
+ }
+}
+/* Output:
+true
+true
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/FactoryConstraint.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/FactoryConstraint.java
new file mode 100755
index 0000000..a53f978
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/FactoryConstraint.java
@@ -0,0 +1,39 @@
+package com.brianway.learning.java.base.generics;//: generics/FactoryConstraint.java
+
+/**
+ * 显式工厂
+ */
+public class FactoryConstraint {
+ public static void main(String[] args) {
+ new Foo2(new IntegerFactory());
+ new Foo2(new Widget.Factory());
+ }
+}
+
+interface FactoryI {
+ T create();
+}
+
+class Foo2 {
+ private T x;
+
+ public > Foo2(F factory) {
+ x = factory.create();
+ }
+
+}
+
+class IntegerFactory implements FactoryI {
+ public Integer create() {
+ return 0;
+ }
+}
+
+class Widget {
+ public static class Factory implements FactoryI {
+ public Widget create() {
+ return new Widget();
+ }
+ }
+}
+///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray.java
new file mode 100755
index 0000000..b9273fc
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray.java
@@ -0,0 +1,35 @@
+package com.brianway.learning.java.base.generics;//: generics/GenericArray.java
+
+/**
+ * 泛型数组
+ */
+public class GenericArray {
+ private T[] array;
+
+ @SuppressWarnings("unchecked")
+ public GenericArray(int sz) {
+ array = (T[]) new Object[sz];
+ }
+
+ public void put(int index, T item) {
+ array[index] = item;
+ }
+
+ public T get(int index) {
+ return array[index];
+ }
+
+ // Method that exposes the underlying representation:
+ public T[] rep() {
+ return array;
+ }
+
+ public static void main(String[] args) {
+ GenericArray gai =
+ new GenericArray(10);
+ // This causes a ClassCastException:
+ //! Integer[] ia = gai.rep();
+ // This is OK:
+ Object[] oa = gai.rep();
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray2.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray2.java
new file mode 100755
index 0000000..21ea014
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray2.java
@@ -0,0 +1,41 @@
+package com.brianway.learning.java.base.generics;
+
+public class GenericArray2 {
+ private Object[] array;
+
+ public GenericArray2(int sz) {
+ array = new Object[sz];
+ }
+
+ public void put(int index, T item) {
+ array[index] = item;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T get(int index) {
+ return (T) array[index];
+ }
+
+ @SuppressWarnings("unchecked")
+ public T[] rep() {
+ return (T[]) array; // Warning: unchecked cast
+ }
+
+ public static void main(String[] args) {
+ GenericArray2 gai =
+ new GenericArray2(10);
+ for (int i = 0; i < 10; i++)
+ gai.put(i, i);
+ for (int i = 0; i < 10; i++)
+ System.out.print(gai.get(i) + " ");
+ System.out.println();
+ try {
+ Integer[] ia = gai.rep();
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ }
+} /* Output: (Sample)
+0 1 2 3 4 5 6 7 8 9
+java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArrayWithTypeToken.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArrayWithTypeToken.java
new file mode 100755
index 0000000..cafbe61
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArrayWithTypeToken.java
@@ -0,0 +1,33 @@
+package com.brianway.learning.java.base.generics;
+
+import java.lang.reflect.Array;
+
+public class GenericArrayWithTypeToken {
+ private T[] array;
+
+ @SuppressWarnings("unchecked")
+ public GenericArrayWithTypeToken(Class type, int sz) {
+ array = (T[]) Array.newInstance(type, sz);
+ }
+
+ public void put(int index, T item) {
+ array[index] = item;
+ }
+
+ public T get(int index) {
+ return array[index];
+ }
+
+ // Expose the underlying representation:
+ public T[] rep() {
+ return array;
+ }
+
+ public static void main(String[] args) {
+ GenericArrayWithTypeToken gai =
+ new GenericArrayWithTypeToken(
+ Integer.class, 10);
+ // This now works:
+ Integer[] ia = gai.rep();
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericMethods.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericMethods.java
new file mode 100755
index 0000000..715c204
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericMethods.java
@@ -0,0 +1,28 @@
+package com.brianway.learning.java.base.generics;
+
+/**
+ * 泛型方法
+ */
+public class GenericMethods {
+ public void f(T x) {
+ System.out.println(x.getClass().getName());
+ }
+
+ public static void main(String[] args) {
+ GenericMethods gm = new GenericMethods();
+ gm.f("");
+ gm.f(1);
+ gm.f(1.0);
+ gm.f(1.0F);
+ gm.f('c');
+ gm.f(gm);
+ }
+}
+/* Output:
+java.lang.String
+java.lang.Integer
+java.lang.Double
+java.lang.Float
+java.lang.Character
+GenericMethods
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericReading.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericReading.java
new file mode 100755
index 0000000..dafc7c0
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericReading.java
@@ -0,0 +1,53 @@
+package com.brianway.learning.java.base.generics;//: generics/GenericReading.java
+
+import java.util.Arrays;
+import java.util.List;
+
+public class GenericReading {
+ static T readExact(List list) {
+ return list.get(0);
+ }
+
+ static List apples = Arrays.asList(new Apple());
+ static List fruit = Arrays.asList(new Fruit());
+
+ // A static method adapts to each call:
+ static void f1() {
+ Apple a = readExact(apples);
+ Fruit f = readExact(fruit);
+ f = readExact(apples);
+ }
+
+ // If, however, you have a class, then its type is
+ // established when the class is instantiated:
+ static class Reader {
+ T readExact(List list) {
+ return list.get(0);
+ }
+ }
+
+ static void f2() {
+ Reader fruitReader = new Reader();
+ Fruit f = fruitReader.readExact(fruit);
+ // Fruit a = fruitReader.readExact(apples); // Error:
+ // readExact(List) cannot be
+ // applied to (List).
+ }
+
+ static class CovariantReader {
+ T readCovariant(List extends T> list) {
+ return list.get(0);
+ }
+ }
+
+ static void f3() {
+ CovariantReader fruitReader =
+ new CovariantReader();
+ Fruit f = fruitReader.readCovariant(fruit);
+ Fruit a = fruitReader.readCovariant(apples);
+ }
+
+ public static void main(String[] args) {
+ f1(); f2(); f3();
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericVarargs.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericVarargs.java
new file mode 100755
index 0000000..1a64c5b
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericVarargs.java
@@ -0,0 +1,30 @@
+package com.brianway.learning.java.base.generics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 可变参数与泛型方法
+ */
+public class GenericVarargs {
+ public static List makeList(T... args) {
+ List result = new ArrayList();
+ for (T item : args)
+ result.add(item);
+ return result;
+ }
+
+ public static void main(String[] args) {
+ List ls = makeList("A");
+ System.out.println(ls);
+ ls = makeList("A", "B", "C");
+ System.out.println(ls);
+ ls = makeList("ABCDEFFHIJKLMNOPQRSTUVWXYZ".split(""));
+ System.out.println(ls);
+ }
+}
+/* Output:
+[A]
+[A, B, C]
+[, A, B, C, D, E, F, F, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericWriting.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericWriting.java
new file mode 100755
index 0000000..ac9e9d6
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericWriting.java
@@ -0,0 +1,36 @@
+package com.brianway.learning.java.base.generics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GenericWriting {
+ // 使用确切参数类型
+ static void writeExact(List list, T item) {
+ list.add(item);
+ }
+
+ static List apples = new ArrayList();
+ static List fruit = new ArrayList();
+
+ static void f1() {
+ writeExact(apples, new Apple());
+ // writeExact(fruit, new Apple()); // Error:
+ // Incompatible types: found Fruit, required Apple
+ }
+
+ //
+ static void
+ writeWithWildcard(List super T> list, T item) {
+ list.add(item);
+ }
+
+ static void f2() {
+ writeWithWildcard(apples, new Apple());
+ writeWithWildcard(fruit, new Apple());
+ }
+
+ public static void main(String[] args) {
+ f1();
+ f2();
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericsAndCovariance.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericsAndCovariance.java
new file mode 100755
index 0000000..5c9722d
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericsAndCovariance.java
@@ -0,0 +1,21 @@
+package com.brianway.learning.java.base.generics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class GenericsAndCovariance {
+ public static void main(String[] args) {
+ // Wildcards allow covariance:
+ List extends Fruit> flist = new ArrayList();
+ // Compile Error: can't add any type of object:
+ // flist.add(new Apple());
+ // flist.add(new Fruit());
+ // flist.add(new Object());
+ flist.add(null); // Legal but uninteresting
+ // We know that it returns at least Fruit:
+ Fruit f = flist.get(0);
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/Holder.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/Holder.java
new file mode 100755
index 0000000..70c2387
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/Holder.java
@@ -0,0 +1,47 @@
+package com.brianway.learning.java.base.generics;
+
+
+public class Holder {
+ private T value;
+
+ public Holder() {
+ }
+
+ public Holder(T val) {
+ value = val;
+ }
+
+ public void set(T val) {
+ value = val;
+ }
+
+ public T get() {
+ return value;
+ }
+
+ public boolean equals(Object obj) {
+ return value.equals(obj);
+ }
+
+ public static void main(String[] args) {
+ Holder Apple = new Holder(new Apple());
+ Apple d = Apple.get();
+ Apple.set(d);
+ // Holder Fruit = Apple; // Cannot upcast
+ Holder extends Fruit> fruit = Apple; // OK
+ Fruit p = fruit.get();
+ d = (Apple) fruit.get(); // Returns 'Object'
+ try {
+ Orange c = (Orange) fruit.get(); // No warning
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ // fruit.set(new Apple()); // Cannot call set()
+ // fruit.set(new Fruit()); // Cannot call set()
+ System.out.println(fruit.equals(d)); // OK
+ }
+}
+/* Output: (Sample)
+java.lang.ClassCastException: com.brianway.learning.java.base.generics.Apple cannot be cast to com.brianway.learning.java.base.generics.Orange
+true
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/InheritBounds.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/InheritBounds.java
new file mode 100755
index 0000000..4995479
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/InheritBounds.java
@@ -0,0 +1,65 @@
+package com.brianway.learning.java.base.generics;
+
+public class InheritBounds {
+ public static void main(String[] args) {
+ Solid2 solid2 =
+ new Solid2(new Bounded());
+ solid2.color();
+ solid2.getY();
+ solid2.weight();
+ }
+}
+
+class HoldItem {
+ T item;
+
+ HoldItem(T item) {
+ this.item = item;
+ }
+
+ T getItem() {
+ return item;
+ }
+}
+
+class Colored2 extends HoldItem {
+ Colored2(T item) {
+ super(item);
+ }
+
+ java.awt.Color color() {
+ return item.getColor();
+ }
+}
+
+class ColoredDimension2
+ extends Colored2 {
+ ColoredDimension2(T item) {
+ super(item);
+ }
+
+ int getX() {
+ return item.x;
+ }
+
+ int getY() {
+ return item.y;
+ }
+
+ int getZ() {
+ return item.z;
+ }
+}
+
+class Solid2
+ extends ColoredDimension2 {
+ Solid2(T item) {
+ super(item);
+ }
+
+ int weight() {
+ return item.weight();
+ }
+}
+
+///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/InstantiateGenericType.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/InstantiateGenericType.java
new file mode 100755
index 0000000..c7bd90f
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/InstantiateGenericType.java
@@ -0,0 +1,35 @@
+package com.brianway.learning.java.base.generics;
+
+public class InstantiateGenericType {
+ public static void main(String[] args) {
+ ClassAsFactory fe =
+ new ClassAsFactory(Employee.class);
+ System.out.println("ClassAsFactory succeeded");
+ try {
+ ClassAsFactory fi =
+ new ClassAsFactory(Integer.class);
+ } catch (Exception e) {
+ System.out.println("ClassAsFactory failed");
+ }
+ }
+}
+
+class ClassAsFactory {
+ T x;
+
+ public ClassAsFactory(Class kind) {
+ try {
+ x = kind.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
+
+class Employee {
+}
+
+/* Output:
+ClassAsFactory succeeded
+ClassAsFactory failed
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/LinkedStack.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/LinkedStack.java
new file mode 100755
index 0000000..c58ea6c
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/LinkedStack.java
@@ -0,0 +1,52 @@
+package com.brianway.learning.java.base.generics;
+
+/**
+ * A stack implemented with an internal linked structure.
+ */
+public class LinkedStack {
+ private static class Node {
+ U item;
+ Node next;
+
+ Node() {
+ item = null; next = null;
+ }
+
+ Node(U item, Node next) {
+ this.item = item;
+ this.next = next;
+ }
+
+ boolean end() {
+ return item == null && next == null;
+ }
+ }
+
+ private Node top = new Node(); // End sentinel
+
+ public void push(T item) {
+ top = new Node(item, top);
+ }
+
+ public T pop() {
+ T result = top.item;
+ if (!top.end()) {
+ top = top.next;
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+ LinkedStack lss = new LinkedStack();
+ for (String s : "Phasers on stun!".split(" "))
+ lss.push(s);
+ String s;
+ while ((s = lss.pop()) != null)
+ System.out.println(s);
+ }
+}
+/* Output:
+stun!
+on
+Phasers
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/LostInformation.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/LostInformation.java
new file mode 100755
index 0000000..617a224
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/LostInformation.java
@@ -0,0 +1,43 @@
+package com.brianway.learning.java.base.generics;//: generics/LostInformation.java
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class LostInformation {
+ public static void main(String[] args) {
+ List list = new ArrayList();
+ Map map = new HashMap();
+ Quark quark = new Quark();
+ Particle p = new Particle();
+ System.out.println(Arrays.toString(
+ list.getClass().getTypeParameters()));
+ System.out.println(Arrays.toString(
+ map.getClass().getTypeParameters()));
+ System.out.println(Arrays.toString(
+ quark.getClass().getTypeParameters()));
+ System.out.println(Arrays.toString(
+ p.getClass().getTypeParameters()));
+ }
+}
+
+class Frob {
+}
+
+class Fnorkle {
+}
+
+class Quark {
+}
+
+class Particle {
+}
+
+/* Output:
+[E]
+[K, V]
+[Q]
+[POSITION, MOMENTUM]
+*///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/SuperTypeWildcards.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/SuperTypeWildcards.java
new file mode 100755
index 0000000..fc4f031
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/SuperTypeWildcards.java
@@ -0,0 +1,20 @@
+package com.brianway.learning.java.base.generics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 逆变
+ * 超类型通配符
+ */
+public class SuperTypeWildcards {
+ static void writeTo(List super Apple> apples) {
+ apples.add(new Apple());
+ apples.add(new Jonathan());
+ // apples.add(new Fruit()); // Error
+ }
+
+ public static void main(String[] args) {
+ SuperTypeWildcards.writeTo(new ArrayList());
+ }
+} ///:~
diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/Wildcards.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/Wildcards.java
new file mode 100755
index 0000000..6618fdb
--- /dev/null
+++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/Wildcards.java
@@ -0,0 +1,130 @@
+package com.brianway.learning.java.base.generics;
+
+/**
+ * Exploring the meaning of wildcards.
+ */
+public class Wildcards {
+ // Raw argument:
+ static void rawArgs(Holder holder, Object arg) {
+ // holder.set(arg); // Warning:
+ // Unchecked call to set(T) as a
+ // member of the raw type Holder
+ // holder.set(new Wildcards()); // Same warning
+
+ // Can't do this; don't have any 'T':
+ // T t = holder.get();
+
+ // OK, but type information has been lost:
+ Object obj = holder.get();
+ }
+
+ // Similar to rawArgs(), but errors instead of warnings:
+ static void unboundedArg(Holder> holder, Object arg) {
+ // holder.set(arg); // Error:
+ // set(capture of ?) in Holder
+ // cannot be applied to (Object)
+ // holder.set(new Wildcards()); // Same error
+
+ // Can't do this; don't have any 'T':
+ // T t = holder.get();
+
+ // OK, but type information has been lost:
+ Object obj = holder.get();
+ }
+
+ static T exact1(Holder holder) {
+ T t = holder.get();
+ return t;
+ }
+
+ static T exact2(Holder holder, T arg) {
+ holder.set(arg);
+ T t = holder.get();
+ return t;
+ }
+
+ static
+ T wildSubtype(Holder extends T> holder, T arg) {
+ // holder.set(arg); // Error:
+ // set(capture of ? extends T) in
+ // Holder
+ // cannot be applied to (T)
+ T t = holder.get();
+ return t;
+ }
+
+ static
+ void wildSupertype(Holder super T> holder, T arg) {
+ holder.set(arg);
+ // T t = holder.get(); // Error:
+ // Incompatible types: found Object, required T
+
+ // OK, but type information has been lost:
+ Object obj = holder.get();
+ }
+
+ public static void main(String[] args) {
+ Holder raw = new Holder();
+ // Or:
+ raw = new Holder();
+ Holder qualified = new Holder();
+ Holder> unbounded = new Holder();
+ Holder extends Long> bounded = new Holder();
+ Long lng = 1L;
+
+ rawArgs(raw, lng);
+ rawArgs(qualified, lng);
+ rawArgs(unbounded, lng);
+ rawArgs(bounded, lng);
+
+ unboundedArg(raw, lng);
+ unboundedArg(qualified, lng);
+ unboundedArg(unbounded, lng);
+ unboundedArg(bounded, lng);
+
+ // Object r1 = exact1(raw); // Warnings:
+ // Unchecked conversion from Holder to Holder
+ // Unchecked method invocation: exact1(Holder)
+ // is applied to (Holder)
+ Long r2 = exact1(qualified);
+ Object r3 = exact1(unbounded); // Must return Object
+ Long r4 = exact1(bounded);
+
+ // Long r5 = exact2(raw, lng); // Warnings:
+ // Unchecked conversion from Holder to Holder
+ // Unchecked method invocation: exact2(Holder,T)
+ // is applied to (Holder,Long)
+ Long r6 = exact2(qualified, lng);
+ // Long r7 = exact2(unbounded, lng); // Error:
+ // exact2(Holder,T) cannot be applied to
+ // (Holder,Long)
+ // Long r8 = exact2(bounded, lng); // Error:
+ // exact2(Holder,T) cannot be applied
+ // to (Holder,Long)
+
+ // Long r9 = wildSubtype(raw, lng); // Warnings:
+ // Unchecked conversion from Holder
+ // to Holder extends Long>
+ // Unchecked method invocation:
+ // wildSubtype(Holder extends T>,T) is
+ // applied to (Holder,Long)
+ Long r10 = wildSubtype(qualified, lng);
+ // OK, but can only return Object:
+ Object r11 = wildSubtype(unbounded, lng);
+ Long r12 = wildSubtype(bounded, lng);
+
+ // wildSupertype(raw, lng); // Warnings:
+ // Unchecked conversion from Holder
+ // to Holder super Long>
+ // Unchecked method invocation:
+ // wildSupertype(Holder super T>,T)
+ // is applied to (Holder,Long)
+ wildSupertype(qualified, lng);
+ // wildSupertype(unbounded, lng); // Error:
+ // wildSupertype(Holder super T>,T) cannot be
+ // applied to (Holder,Long)
+ // wildSupertype(bounded, lng); // Error:
+ // wildSupertype(Holder super T>,T) cannot be
+ // applied to (Holder,Long)
+ }
+} ///:~
From 2bd399ce267e5013e8209c64027e1493249c86fb Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Mon, 26 Dec 2016 23:09:28 +0800
Subject: [PATCH 16/57] [add] add module java8
---
java8/pom.xml | 14 ++++
.../java8/lambda/FilteringApples.java | 81 +++++++++++++++++++
pom.xml | 3 +
3 files changed, 98 insertions(+)
create mode 100644 java8/pom.xml
create mode 100644 java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java
diff --git a/java8/pom.xml b/java8/pom.xml
new file mode 100644
index 0000000..9428faf
--- /dev/null
+++ b/java8/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ java-learning
+ com.brianway.learning.java
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ java8
+
+
\ No newline at end of file
diff --git a/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java b/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java
new file mode 100644
index 0000000..a06bdf1
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java
@@ -0,0 +1,81 @@
+package com.brianway.learning.java8.lambda;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+
+/**
+ * Created by brian on 16/12/26.
+ */
+public class FilteringApples {
+ public static void main(String[] args) {
+ List inventory = Arrays.asList(new Apple(80, "green"),
+ new Apple(155, "green"),
+ new Apple(120, "red"));
+
+ List greenApples = filter(inventory, FilteringApples::isGreenApple);
+ System.out.println(greenApples);
+
+ List greenApples2 = filter(inventory, (Apple a) -> "green".equals(a.getColor()));
+ System.out.println(greenApples2);
+
+ List heavyApples = filter(inventory, FilteringApples::isHeavyApple);
+ System.out.println(heavyApples);
+
+ List heavyApples2 = filter(inventory, (Apple a) -> a.getWeight() > 150);
+ System.out.println(heavyApples2);
+
+ }
+
+ public static List filter(List inventory, Predicate p) {
+ List result = new ArrayList<>();
+ for (Apple apple : inventory) {
+ if (p.test(apple)) {
+ result.add(apple);
+ }
+ }
+ return result;
+ }
+
+ public static boolean isGreenApple(Apple apple) {
+ return "green".equals(apple.getColor());
+ }
+
+ public static boolean isHeavyApple(Apple apple) {
+ return apple.getWeight() > 150;
+ }
+
+ public static class Apple {
+ private int weight = 0;
+ private String color = "";
+
+ public Apple(int weight, String color) {
+ this.weight = weight;
+ this.color = color;
+ }
+
+ public Integer getWeight() {
+ return weight;
+ }
+
+ public void setWeight(Integer weight) {
+ this.weight = weight;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+ public String toString() {
+ return "Apple{" +
+ "color='" + color + '\'' +
+ ", weight=" + weight +
+ '}';
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index 5bf3a88..551090f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,6 +13,8 @@
UTF-8
UTF-8
+ 1.8
+ 1.8
4.11
@@ -48,6 +50,7 @@
java-base
java-container
java-io
+ java8
From dec218074be1ec3f0f1785d3a109a28f65153f6b Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Thu, 29 Dec 2016 00:21:03 +0800
Subject: [PATCH 17/57] [add] add Stream API examples
---
java8/README.md | 6 ++
.../java8/streamapi/BuildingStreams.java | 80 +++++++++++++++++
.../learning/java8/streamapi/Dish.java | 57 +++++++++++++
.../java8/streamapi/GroupingTransactions.java | 84 ++++++++++++++++++
.../java8/streamapi/PuttingIntoPractice.java | 85 +++++++++++++++++++
.../learning/java8/streamapi/StreamBasic.java | 50 +++++++++++
.../learning/java8/streamapi/Trader.java | 28 ++++++
.../learning/java8/streamapi/Transaction.java | 32 +++++++
java8/src/main/resources/data-building.txt | 2 +
9 files changed, 424 insertions(+)
create mode 100644 java8/README.md
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/Dish.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/GroupingTransactions.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/PuttingIntoPractice.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/StreamBasic.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/Trader.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/Transaction.java
create mode 100644 java8/src/main/resources/data-building.txt
diff --git a/java8/README.md b/java8/README.md
new file mode 100644
index 0000000..f645ce7
--- /dev/null
+++ b/java8/README.md
@@ -0,0 +1,6 @@
+# Java 8 新特性
+
+《Java 8 In Action》一书
+
+源码参考了 **java8/Java8InAction**:[https://github.com/java8/Java8InAction](https://github.com/java8/Java8InAction)
+
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java
new file mode 100644
index 0000000..1dc21ba
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java
@@ -0,0 +1,80 @@
+package com.brianway.learning.java8.streamapi;
+
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.function.IntSupplier;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+public class BuildingStreams {
+
+ public static void main(String... args) throws Exception {
+
+ // Stream.of
+ Stream stream = Stream.of("Java 8", "Lambdas", "In", "Action");
+ stream.map(String::toUpperCase).forEach(System.out::println);
+
+ // Stream.empty
+ Stream emptyStream = Stream.empty();
+
+ // Arrays.stream
+ int[] numbers = {2, 3, 5, 7, 11, 13};
+ System.out.println(Arrays.stream(numbers).sum());
+
+ // Stream.iterate
+ Stream.iterate(0, n -> n + 2)
+ .limit(10)
+ .forEach(System.out::println);
+
+ // fibonnaci with iterate
+ Stream.iterate(new int[] {0, 1}, t -> new int[] {t[1], t[0] + t[1]})
+ .limit(10)
+ .forEach(t -> System.out.println("(" + t[0] + ", " + t[1] + ")"));
+
+ Stream.iterate(new int[] {0, 1}, t -> new int[] {t[1], t[0] + t[1]})
+ .limit(10)
+ .map(t -> t[0])
+ .forEach(System.out::println);
+
+ // random stream of doubles with Stream.generate
+ Stream.generate(Math::random)
+ .limit(10)
+ .forEach(System.out::println);
+
+ // stream of 1s with Stream.generate
+ IntStream.generate(() -> 1)
+ .limit(5)
+ .forEach(System.out::println);
+
+ IntStream.generate(new IntSupplier() {
+ public int getAsInt() {
+ return 2;
+ }
+ }).limit(5)
+ .forEach(System.out::println);
+
+ IntSupplier fib = new IntSupplier() {
+ private int previous = 0;
+ private int current = 1;
+
+ public int getAsInt() {
+ int nextValue = this.previous + this.current;
+ this.previous = this.current;
+ this.current = nextValue;
+ return this.previous;
+ }
+ };
+ IntStream.generate(fib).limit(10).forEach(System.out::println);
+
+ String path = BuildingStreams.class.getResource("/").getPath() + "/data-building.txt";
+ long uniqueWords = Files.lines(Paths.get(path), Charset.defaultCharset())
+ .flatMap(line -> Arrays.stream(line.split(" ")))
+ .distinct()
+ .count();
+
+ System.out.println("There are " + uniqueWords + " unique words in data.txt");
+
+ }
+}
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/Dish.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/Dish.java
new file mode 100644
index 0000000..5c74596
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/Dish.java
@@ -0,0 +1,57 @@
+package com.brianway.learning.java8.streamapi;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class Dish {
+
+ private final String name;
+ private final boolean vegetarian;
+ private final int calories;
+ private final Type type;
+
+ public Dish(String name, boolean vegetarian, int calories, Type type) {
+ this.name = name;
+ this.vegetarian = vegetarian;
+ this.calories = calories;
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isVegetarian() {
+ return vegetarian;
+ }
+
+ public int getCalories() {
+ return calories;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public enum Type {
+ MEAT,
+ FISH,
+ OTHER
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public static final List menu =
+ Arrays.asList(new Dish("pork", false, 800, Dish.Type.MEAT),
+ new Dish("beef", false, 700, Dish.Type.MEAT),
+ new Dish("chicken", false, 400, Dish.Type.MEAT),
+ new Dish("french fries", true, 530, Dish.Type.OTHER),
+ new Dish("rice", true, 350, Dish.Type.OTHER),
+ new Dish("season fruit", true, 120, Dish.Type.OTHER),
+ new Dish("pizza", true, 550, Dish.Type.OTHER),
+ new Dish("prawns", false, 400, Dish.Type.FISH),
+ new Dish("salmon", false, 450, Dish.Type.FISH));
+}
\ No newline at end of file
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/GroupingTransactions.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/GroupingTransactions.java
new file mode 100644
index 0000000..4a3a41f
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/GroupingTransactions.java
@@ -0,0 +1,84 @@
+package com.brianway.learning.java8.streamapi;
+
+import static java.util.stream.Collectors.groupingBy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class GroupingTransactions {
+
+ public static List transactions = Arrays.asList(
+ new Transaction(Currency.EUR, 1500.0),
+ new Transaction(Currency.USD, 2300.0),
+ new Transaction(Currency.GBP, 9900.0),
+ new Transaction(Currency.EUR, 1100.0),
+ new Transaction(Currency.JPY, 7800.0),
+ new Transaction(Currency.CHF, 6700.0),
+ new Transaction(Currency.EUR, 5600.0),
+ new Transaction(Currency.USD, 4500.0),
+ new Transaction(Currency.CHF, 3400.0),
+ new Transaction(Currency.GBP, 3200.0),
+ new Transaction(Currency.USD, 4600.0),
+ new Transaction(Currency.JPY, 5700.0),
+ new Transaction(Currency.EUR, 6800.0));
+
+ public static void main(String... args) {
+ groupImperatively();
+ groupFunctionally();
+
+ }
+
+ private static void groupImperatively() {
+ Map> transactionsByCurrencies = new HashMap<>();
+ for (Transaction transaction : transactions) {
+ Currency currency = transaction.getCurrency();
+ List transactionsForCurrency = transactionsByCurrencies.get(currency);
+ if (transactionsForCurrency == null) {
+ transactionsForCurrency = new ArrayList<>();
+ transactionsByCurrencies.put(currency, transactionsForCurrency);
+ }
+ transactionsForCurrency.add(transaction);
+ }
+
+ System.out.println(transactionsByCurrencies);
+ }
+
+ private static void groupFunctionally() {
+ Map> transactionsByCurrencies = transactions.stream().collect(groupingBy(Transaction::getCurrency));
+ System.out.println(transactionsByCurrencies);
+ }
+
+ public static class Transaction {
+ private final Currency currency;
+ private final double value;
+
+ public Transaction(Currency currency, double value) {
+ this.currency = currency;
+ this.value = value;
+ }
+
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ public double getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return currency + " " + value;
+ }
+ }
+
+ public enum Currency {
+ EUR,
+ USD,
+ JPY,
+ GBP,
+ CHF
+ }
+}
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/PuttingIntoPractice.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/PuttingIntoPractice.java
new file mode 100644
index 0000000..c27f3ed
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/PuttingIntoPractice.java
@@ -0,0 +1,85 @@
+package com.brianway.learning.java8.streamapi;
+
+import static java.util.Comparator.comparing;
+import static java.util.stream.Collectors.toList;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class PuttingIntoPractice {
+ public static void main(String... args) {
+ Trader raoul = new Trader("Raoul", "Cambridge");
+ Trader mario = new Trader("Mario", "Milan");
+ Trader alan = new Trader("Alan", "Cambridge");
+ Trader brian = new Trader("Brian", "Cambridge");
+
+ List transactions = Arrays.asList(
+ new Transaction(brian, 2011, 300),
+ new Transaction(raoul, 2012, 1000),
+ new Transaction(raoul, 2011, 400),
+ new Transaction(mario, 2012, 710),
+ new Transaction(mario, 2012, 700),
+ new Transaction(alan, 2012, 950)
+ );
+
+ // Query 1: Find all transactions from year 2011 and sort them by value (small to high).
+ List tr2011 = transactions.stream()
+ .filter(transaction -> transaction.getYear() == 2011)
+ .sorted(comparing(Transaction::getValue))
+ .collect(toList());
+ System.out.println(tr2011);
+
+ // Query 2: What are all the unique cities where the traders work?
+ List cities =
+ transactions.stream()
+ .map(transaction -> transaction.getTrader().getCity())
+ .distinct()
+ .collect(toList());
+ System.out.println(cities);
+
+ // Query 3: Find all traders from Cambridge and sort them by name.
+
+ List traders =
+ transactions.stream()
+ .map(Transaction::getTrader)
+ .filter(trader -> trader.getCity().equals("Cambridge"))
+ .distinct()
+ .sorted(comparing(Trader::getName))
+ .collect(toList());
+ System.out.println(traders);
+
+ // Query 4: Return a string of all traders’ names sorted alphabetically.
+
+ String traderStr =
+ transactions.stream()
+ .map(transaction -> transaction.getTrader().getName())
+ .distinct()
+ .sorted()
+ .reduce("", (n1, n2) -> n1 + n2);
+ System.out.println(traderStr);
+
+ // Query 5: Are there any trader based in Milan?
+
+ boolean milanBased =
+ transactions.stream()
+ .anyMatch(transaction -> transaction.getTrader()
+ .getCity()
+ .equals("Milan")
+ );
+ System.out.println(milanBased);
+
+ // Query 6: Update all transactions so that the traders from Milan are set to Cambridge.
+ transactions.stream()
+ .map(Transaction::getTrader)
+ .filter(trader -> trader.getCity().equals("Milan"))
+ .forEach(trader -> trader.setCity("Cambridge"));
+ System.out.println(transactions);
+
+ // Query 7: What's the highest value in all the transactions?
+ int highestValue =
+ transactions.stream()
+ .map(Transaction::getValue)
+ .reduce(0, Integer::max);
+ System.out.println(highestValue);
+ }
+}
\ No newline at end of file
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamBasic.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamBasic.java
new file mode 100644
index 0000000..7f516a5
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamBasic.java
@@ -0,0 +1,50 @@
+package com.brianway.learning.java8.streamapi;
+
+import static java.util.Comparator.comparing;
+import static java.util.stream.Collectors.toList;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class StreamBasic {
+
+ public static void main(String... args) {
+ // Java 7
+ getLowCaloricDishesNamesInJava7(Dish.menu).forEach(System.out::println);
+
+ System.out.println("---");
+
+ // Java 8
+ getLowCaloricDishesNamesInJava8(Dish.menu).forEach(System.out::println);
+
+ }
+
+ public static List getLowCaloricDishesNamesInJava7(List dishes) {
+ List lowCaloricDishes = new ArrayList<>();
+ for (Dish d : dishes) {
+ if (d.getCalories() < 400) {
+ lowCaloricDishes.add(d);
+ }
+ }
+ List lowCaloricDishesName = new ArrayList<>();
+ Collections.sort(lowCaloricDishes, new Comparator() {
+ public int compare(Dish d1, Dish d2) {
+ return Integer.compare(d1.getCalories(), d2.getCalories());
+ }
+ });
+ for (Dish d : lowCaloricDishes) {
+ lowCaloricDishesName.add(d.getName());
+ }
+ return lowCaloricDishesName;
+ }
+
+ public static List getLowCaloricDishesNamesInJava8(List dishes) {
+ return dishes.stream()
+ .filter(d -> d.getCalories() < 400)
+ .sorted(comparing(Dish::getCalories))
+ .map(Dish::getName)
+ .collect(toList());
+ }
+}
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/Trader.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/Trader.java
new file mode 100644
index 0000000..b008b12
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/Trader.java
@@ -0,0 +1,28 @@
+package com.brianway.learning.java8.streamapi;
+
+public class Trader {
+
+ private String name;
+ private String city;
+
+ public Trader(String n, String c) {
+ this.name = n;
+ this.city = c;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getCity() {
+ return this.city;
+ }
+
+ public void setCity(String newCity) {
+ this.city = newCity;
+ }
+
+ public String toString() {
+ return "Trader:" + this.name + " in " + this.city;
+ }
+}
\ No newline at end of file
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/Transaction.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/Transaction.java
new file mode 100644
index 0000000..656149c
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/Transaction.java
@@ -0,0 +1,32 @@
+package com.brianway.learning.java8.streamapi;
+
+public class Transaction {
+
+ private Trader trader;
+ private int year;
+ private int value;
+
+ public Transaction(Trader trader, int year, int value) {
+ this.trader = trader;
+ this.year = year;
+ this.value = value;
+ }
+
+ public Trader getTrader() {
+ return this.trader;
+ }
+
+ public int getYear() {
+ return this.year;
+ }
+
+ public int getValue() {
+ return this.value;
+ }
+
+ public String toString() {
+ return "{" + this.trader + ", " +
+ "year: " + this.year + ", " +
+ "value:" + this.value + "}";
+ }
+}
\ No newline at end of file
diff --git a/java8/src/main/resources/data-building.txt b/java8/src/main/resources/data-building.txt
new file mode 100644
index 0000000..2230972
--- /dev/null
+++ b/java8/src/main/resources/data-building.txt
@@ -0,0 +1,2 @@
+The quick brown fox jumped over the lazy dog
+The lazy dog jumped over the quick brown fox
From 874c3c4800d8943c81d340e7a930931334364fbd Mon Sep 17 00:00:00 2001
From: brianway <250902678@qq.com>
Date: Sat, 7 Jan 2017 23:03:43 +0800
Subject: [PATCH 18/57] [add] add some stream api examples
---
.../java8/lambda/FilteringApples.java | 2 +
.../java8/streamapi/BuildingStreams.java | 10 +-
.../java8/streamapi/GroupingTransactions.java | 3 +
.../learning/java8/streamapi/Laziness.java | 30 +++++
.../learning/java8/streamapi/Mapping.java | 48 +++++++
.../streamapi/PartitionPrimeNumbers.java | 121 ++++++++++++++++++
.../learning/java8/streamapi/Reducing.java | 30 +++++
.../learning/java8/streamapi/StreamBasic.java | 3 +
8 files changed, 242 insertions(+), 5 deletions(-)
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/Laziness.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/Mapping.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/PartitionPrimeNumbers.java
create mode 100644 java8/src/main/java/com/brianway/learning/java8/streamapi/Reducing.java
diff --git a/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java b/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java
index a06bdf1..e04b739 100644
--- a/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java
+++ b/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java
@@ -7,6 +7,8 @@
/**
* Created by brian on 16/12/26.
+ *
+ *
*/
public class FilteringApples {
public static void main(String[] args) {
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java
index 1dc21ba..13d0cd3 100644
--- a/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java
@@ -8,6 +8,9 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
+/**
+ * 斐波拉切数列的几种生成方法
+ */
public class BuildingStreams {
public static void main(String... args) throws Exception {
@@ -48,11 +51,8 @@ public static void main(String... args) throws Exception {
.limit(5)
.forEach(System.out::println);
- IntStream.generate(new IntSupplier() {
- public int getAsInt() {
- return 2;
- }
- }).limit(5)
+ IntStream.generate(() -> 2)
+ .limit(5)
.forEach(System.out::println);
IntSupplier fib = new IntSupplier() {
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/GroupingTransactions.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/GroupingTransactions.java
index 4a3a41f..35a122e 100644
--- a/java8/src/main/java/com/brianway/learning/java8/streamapi/GroupingTransactions.java
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/GroupingTransactions.java
@@ -8,6 +8,9 @@
import java.util.List;
import java.util.Map;
+/**
+ * 分别使用指令式和函数式进行分组
+ */
public class GroupingTransactions {
public static List transactions = Arrays.asList(
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/Laziness.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/Laziness.java
new file mode 100644
index 0000000..33d2a0e
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/Laziness.java
@@ -0,0 +1,30 @@
+package com.brianway.learning.java8.streamapi;
+
+import static java.util.stream.Collectors.toList;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 流操作-中间操作
+ */
+public class Laziness {
+
+ public static void main(String[] args) {
+ List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
+ List twoEvenSquares =
+ numbers.stream()
+ .filter(n -> {
+ System.out.println("filtering " + n); return n % 2 == 0;
+ })
+ .map(n -> {
+ System.out.println("mapping " + n);
+ return n * n;
+ })
+ .limit(2)
+ .collect(toList());
+
+ twoEvenSquares.stream().forEach(System.out::println);
+ }
+
+}
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/Mapping.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/Mapping.java
new file mode 100644
index 0000000..74f63c2
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/Mapping.java
@@ -0,0 +1,48 @@
+package com.brianway.learning.java8.streamapi;
+
+import static com.brianway.learning.java8.streamapi.Dish.menu;
+import static java.util.stream.Collectors.toList;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 使用流-映射
+ * 注意扁平映射
+ */
+public class Mapping {
+
+ public static void main(String... args) {
+
+ // map
+ List dishNames = menu.stream()
+ .map(Dish::getName)
+ .collect(toList());
+ System.out.println(dishNames);
+
+ // map
+ List words = Arrays.asList("Hello", "World");
+ List wordLengths = words.stream()
+ .map(String::length)
+ .collect(toList());
+ System.out.println(wordLengths);
+
+ // flatMap
+ words.stream()
+ .flatMap((String line) -> Arrays.stream(line.split("")))
+ .distinct()
+ .forEach(System.out::println);
+
+ // flatMap
+ List numbers1 = Arrays.asList(1, 2, 3, 4, 5);
+ List numbers2 = Arrays.asList(6, 7, 8);
+ List pairs =
+ numbers1.stream()
+ .flatMap((Integer i) -> numbers2.stream()
+ .map((Integer j) -> new int[] {i, j})
+ )
+ .filter(pair -> (pair[0] + pair[1]) % 3 == 0)
+ .collect(toList());
+ pairs.forEach(pair -> System.out.println("(" + pair[0] + ", " + pair[1] + ")"));
+ }
+}
diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/PartitionPrimeNumbers.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/PartitionPrimeNumbers.java
new file mode 100644
index 0000000..3d0e73e
--- /dev/null
+++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/PartitionPrimeNumbers.java
@@ -0,0 +1,121 @@
+package com.brianway.learning.java8.streamapi;
+
+import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH;
+import static java.util.stream.Collectors.partitioningBy;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+/**
+ * 分区:分类的特殊情况。分区函数返回一个布尔值
+ */
+public class PartitionPrimeNumbers {
+
+ public static void main(String... args) {
+ System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimes(100));
+ System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimesWithCustomCollector(100));
+
+ }
+
+ public static Map> partitionPrimes(int n) {
+ return IntStream.rangeClosed(2, n).boxed()
+ .collect(partitioningBy(PartitionPrimeNumbers::isPrime));
+ }
+
+ public static boolean isPrime(int candidate) {
+ return IntStream.rangeClosed(2, candidate - 1)
+ .limit((long) Math.floor(Math.sqrt((double) candidate)) - 1)
+ .noneMatch(i -> candidate % i == 0);
+ }
+
+ public static Map> partitionPrimesWithCustomCollector(int n) {
+ return IntStream.rangeClosed(2, n).boxed().collect(new PrimeNumbersCollector());
+ }
+
+ public static boolean isPrime(List primes, Integer candidate) {
+ double candidateRoot = Math.sqrt((double) candidate);
+ //return primes.stream().filter(p -> p < candidateRoot).noneMatch(p -> candidate % p == 0);
+ return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0);
+ }
+
+ public static List takeWhile(List list, Predicate p) {
+ int i = 0;
+ for (A item : list) {
+ if (!p.test(item)) {
+ return list.subList(0, i);
+ }
+ i++;
+ }
+ return list;
+ }
+
+ public static class PrimeNumbersCollector
+ implements Collector>, Map>> {
+
+ @Override
+ public Supplier