diff --git a/.gitignore b/.gitignore index 57822d6..168a863 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,10 @@ target .factorypath .asciidoctor/ *.ttf +*.otf +/cfg/gems fonts.ttf.tgz *.icloud + + diff --git a/cfg/fonts/download-fonts.sh b/cfg/fonts/download-fonts.sh deleted file mode 100755 index 66f010d..0000000 --- a/cfg/fonts/download-fonts.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -# -# Download the fonts - -wget https://github.com/diguage/jdk-source-analysis/releases/download/source-fonts.ttf/fonts.ttf.tgz - -tar -zxvf fonts.ttf.tgz - - -# Backup download URL: https://github.com/adobe-fonts/source-han-serif/archive/1.001R.zip - -# Maybe you have to convert the OTF fonts to TTF fonts by the otf2ttf tools of AFDKO(https://github.com/adobe-type-tools/afdko/) diff --git a/cfg/gems/.gitkeep b/cfg/gems/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/cfg/theme/Source-theme.yml b/cfg/theme/Source-theme.yml index 3800769..98b1019 100644 --- a/cfg/theme/Source-theme.yml +++ b/cfg/theme/Source-theme.yml @@ -2,19 +2,21 @@ font: catalog: merge: true Source Han Serif SC: - normal: SourceHanSerifSC-Regular.ttf - bold: SourceHanSerifSC-Bold.ttf - italic: SourceHanSerifSC-Medium.ttf - bold_italic: SourceHanSerifSC-SemiBold.ttf + normal: SourceHanSerifSC-Regular.otf + bold: SourceHanSerifSC-Bold.otf + italic: SourceHanSerifSC-Medium.otf + bold_italic: SourceHanSerifSC-SemiBold.otf #SourceHanSerifSC-Heavy.otf #SourceHanSerifSC-ExtraLight.otf #SourceHanSerifSC-Light.otf Source Code Pro: - normal: SourceCodePro-Regular.ttf - bold: SourceCodePro-Semibold.ttf - italic: SourceCodePro-It.ttf - bold_italic: SourceCodePro-BoldIt.ttf - Emoji: Symbola.ttf + normal: SourceCodePro-Regular.otf + bold: SourceCodePro-Semibold.otf + italic: SourceCodePro-It.otf + bold_italic: SourceCodePro-BoldIt.otf +# Emoji: NotoColorEmoji.ttf + Emoji: NotoEmoji-Regular.ttf +# Emoji: Symbola.ttf #SourceCodePro-Black.ttf #SourceCodePro-BlackIt.ttf #SourceCodePro-ExtraLight.ttf diff --git a/docs/diagram/ack.puml b/docs/diagram/ack.puml new file mode 100644 index 0000000..83e971f --- /dev/null +++ b/docs/diagram/ack.puml @@ -0,0 +1,4 @@ +@startuml + + +@enduml diff --git a/docs/java.lang.String.adoc b/docs/java.lang.String.adoc index f3fe69e..d527555 100644 --- a/docs/java.lang.String.adoc +++ b/docs/java.lang.String.adoc @@ -10,3 +10,9 @@ include::{sourcedir}/StringUtils.java[] ---- include::{sourcedir}/StringUtilTest.java[] ---- + + +[{java_src_attr}] +---- +include::{sourcedir}/StringTest.java[] +---- diff --git a/docs/java.util.Iterator.adoc b/docs/java.util.Iterator.adoc index f30100b..ccdabcb 100644 --- a/docs/java.util.Iterator.adoc +++ b/docs/java.util.Iterator.adoc @@ -26,9 +26,10 @@ ____ .... @startuml 'skinparam nodesep 70 +skinparam titleFontSize 30 skinparam defaultFontName Hiragino Sans GB -title 迭代器模式 +title **迭代器模式** abstract class Iterator { + {abstract} first() :Object @@ -64,6 +65,9 @@ Iterator <|-- ConcreteIterator ConcreteIterator -left-> ConcreteAggregate ConcreteIterator <.. ConcreteAggregate +skinparam footerFontSize 20 +footer D瓜哥 · https://www.diguage.com · 出品 + @enduml .... diff --git a/docs/java.util.concurrent.CompletableFuture.adoc b/docs/java.util.concurrent.CompletableFuture.adoc index 1702ed0..daec70f 100644 --- a/docs/java.util.concurrent.CompletableFuture.adoc +++ b/docs/java.util.concurrent.CompletableFuture.adoc @@ -9,6 +9,13 @@ Java 中的 Promise。 include::{sourcedir}/concurrent/CompletableFutureTest.java[] ---- +`CompletableFuture` 实现了 `Future` 和 `CompletionStage` 两个接口。 + +`CompletionStage` 接口声明了大量方法, `thenApply*` 接受 `Function` 对象,可以实现将任务的结果转化成另外一个对象,类似 Java Stream API 中的 `map` 操作; `thenAccept` 接受 `Consumer` 对象,见文知意,就是“消费”异步任务的结果值,类似 Java Stream API 的“终止操作”。 + + + == 参考资料 . https://www.baeldung.com/java-completablefuture[Guide To CompletableFuture | Baeldung] +. https://xie.infoq.cn/article/12fb1f7f825bb27795679ad13[Java 8 的异步利器:CompletableFuture源码解析^] diff --git a/pom.xml b/pom.xml index 9f06787..af6134b 100644 --- a/pom.xml +++ b/pom.xml @@ -13,29 +13,37 @@ https://www.diguage.com/ - 0.16 - 1.35 - 2.8.9 + 0.17 + 1.36 + 2.10.1 2.10.13 - 1.12.10 - 4.1.77.Final - 3.21.1 + 1.14.4 + 4.1.92.Final + 3.23.1 31.1-jre 4.4 11.0.0 1.7.36 - 1.2.11 + 1.2.12 5.8.2 3.23.1 - 2.5.4 - 2.0.6 + 2.5.8 + 2.3.7 1.5.1 - 2.2.3 - 2.2.2 - 9.3.4.0 + 2.2.8 + 0.0.16 + 0.0.1 + 2.2.3 + 9.3.10.0 + ${project.basedir}/cfg/gems + ${project.basedir}/cfg/fonts + https://github.com/diguage/open-fonts/releases/download/latest + 1.0.3 + 2.0.1 + 1.7.0 17 17 UTF-8 @@ -141,9 +149,233 @@ assertj-core ${assertj.version} + + + rubygems + asciidoctor-multipage + ${asciidoctor-multipage.version} + gem + + + rubygems + asciidoctor + + + + + rubygems + asciidoctor-comment-links + ${asciidoctor-comment-links.version} + gem + + + rubygems + asciidoctor + + + + + + org.torquebox.mojo + mavengem-wagon + ${mavengem-wagon.version} + + + + de.saumya.mojo + gem-maven-plugin + ${gem-maven-plugin.version} + + ${jruby.version} + + + ${gem.path} + + + ${gem.path} + + + + + install-gems + + initialize + + initialize + + + + + com.googlecode.maven-download-plugin + download-maven-plugin + ${download-maven-plugin.version} + + + install-font-NotoEmoji-Regular + initialize + + wget + + + ${pdf-fonts.baseuri}/NotoEmoji-Regular.ttf + ${pdf-fonts.path} + f224032937e77448b2586b171ed7d031 + + + + + + install-font-SourceCodePro-Regular + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceCodePro-Regular.otf + ${pdf-fonts.path} + 881bfa23a0fc625abe2a8c38b2a72180 + + + + install-font-SourceCodePro-Semibold + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceCodePro-Semibold.otf + ${pdf-fonts.path} + e09d6d82c6e77726b03f3929dd2b6961 + + + + install-font-SourceCodePro-It + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceCodePro-It.otf + ${pdf-fonts.path} + 6fc0b73a8f4b42cc9ecb5154e3b45dcd + + + + install-font-SourceCodePro-BoldIt + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceCodePro-BoldIt.otf + ${pdf-fonts.path} + 5b7d949c95111f4a7166553db479e5e1 + + + + + + install-font-SourceHanSerifSC-Regular + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceHanSerifSC-Regular.otf + ${pdf-fonts.path} + 3990fae1c68e4144013f92273fca41a9 + + + + install-font-SourceHanSerifSC-Bold + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceHanSerifSC-Bold.otf + ${pdf-fonts.path} + 9bb66a8d136498b323b3549f95a53935 + + + + install-font-SourceHanSerifSC-Medium + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceHanSerifSC-Medium.otf + ${pdf-fonts.path} + 46f15d8b48f93010232fbdb46c36006b + + + + install-font-SourceHanSerifSC-SemiBold + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceHanSerifSC-SemiBold.otf + ${pdf-fonts.path} + c27bc5f59edac6bd68d7a15d4f6a05f8 + + + + + install-font-SourceHanSansSC-Regular + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceHanSansSC-Regular.otf + ${pdf-fonts.path} + 56195441817e7172c4cd914388710f20 + + + + install-font-SourceHanSansSC-Bold + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceHanSansSC-Bold.otf + ${pdf-fonts.path} + c76f8a8f08293d0e1c5dc8302f7062aa + + + + install-font-SourceHanSansSC-Medium + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceHanSansSC-Medium.otf + ${pdf-fonts.path} + ebc3cd485fe89cc90b38be33464894ae + + + + install-font-SourceHanSansSC-Heavy + initialize + + wget + + + ${pdf-fonts.baseuri}/SourceHanSansSC-Heavy.otf + ${pdf-fonts.path} + 2dbb493c201153533bc0f92e93cee6af + + + + org.asciidoctor asciidoctor-maven-plugin @@ -168,7 +400,7 @@ 3 true /usr/local/bin/dot - linenums,indent=0,subs="attributes,verbatim,quotes" + indent=0,subs="attributes,verbatim,quotes" source%nowrap,java,{source_attr} source%nowrap,html,{source_attr} align="center",width=100% @@ -176,6 +408,31 @@ + + generate-multipage + package + + process-asciidoc + + + multipage_html5 + book + + ${gem.path} + + asciidoctor-diagram + asciidoctor-multipage + asciidoctor-comment-links + + + ${project.build.directory}/docs/multipage + + + left + indent=0,subs="attributes,verbatim,quotes" + + + generate-html package @@ -189,6 +446,7 @@ left true + indent=0,subs="attributes,verbatim,quotes" @@ -294,4 +552,12 @@ + + + + mavengems + + mavengem:https://gems.ruby-china.com + + diff --git a/src/main/java/com/diguage/truman/ComparatorTest.java b/src/main/java/com/diguage/truman/ComparatorTest.java new file mode 100644 index 0000000..7efb5de --- /dev/null +++ b/src/main/java/com/diguage/truman/ComparatorTest.java @@ -0,0 +1,52 @@ +package com.diguage.truman; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class ComparatorTest { + public static class User { + public User(String name, int age, int sex) { + this.name = name; + this.age = age; + this.sex = sex; + } + + String name; + int age; + + int sex; + + @Override + public String toString() { + return "User{" + + "name='" + name + '\'' + + ", age=" + age + + ", sex=" + sex + + '}'; + } + } + + @Test + public void test() { + List users = Arrays.asList( + new User("u4", 4, 1), + new User("u2", 2, 1), + new User("u1", 1, 0), + new User("u3", 2, 0)); + List result = users.stream() + .sorted((a, b) -> { + if (0 == a.sex) { + return -1; + } + if (0 == b.sex) { + return 1; + } + return 0; + }) + .collect(Collectors.toList()); + System.out.println(Arrays.toString(result.toArray())); + } +} diff --git a/src/main/java/com/diguage/truman/HashMapTest.java b/src/main/java/com/diguage/truman/HashMapTest.java new file mode 100644 index 0000000..6ddcde4 --- /dev/null +++ b/src/main/java/com/diguage/truman/HashMapTest.java @@ -0,0 +1,18 @@ +package com.diguage.truman; + +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class HashMapTest { + @Test + public void test() { + Map map = new HashMap<>(); + map.put("123", null); + assertThat(map.getOrDefault("123", "456")).isNull(); + } +} diff --git a/src/main/java/com/diguage/truman/LongTest.java b/src/main/java/com/diguage/truman/LongTest.java new file mode 100644 index 0000000..f8953da --- /dev/null +++ b/src/main/java/com/diguage/truman/LongTest.java @@ -0,0 +1,12 @@ +package com.diguage.truman; + +import org.junit.jupiter.api.Test; + +public class LongTest { + @Test + public void test() { + System.out.println(Long.toHexString(Long.MAX_VALUE)); + System.out.println(Long.toHexString(System.nanoTime())); + System.out.println(Long.toHexString(System.currentTimeMillis())); + } +} diff --git a/src/main/java/com/diguage/truman/StringTest.java b/src/main/java/com/diguage/truman/StringTest.java new file mode 100644 index 0000000..96db0b4 --- /dev/null +++ b/src/main/java/com/diguage/truman/StringTest.java @@ -0,0 +1,52 @@ +package com.diguage.truman; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class StringTest { + + @Test + public void testSplit() { + String s = "abc"; + System.out.println(Arrays.toString(s.split("\\|"))); + + + // 调用 split 方法,如果参数为 null 时,则抛异常 + assertThatThrownBy(() -> s.split(null)).isInstanceOf(NullPointerException.class); + } + + @Test + public void testReplaceAll() { + String value = "${abc} 是一个占位符,${abc}"; + Set placeholders = getAllPlaceholders(value); + + for (String placeholder : placeholders) { + System.out.println(value.replaceAll(placeholder, "ABC")); + } + } + + /** + * 占位符正则表达式:${\w*} + */ + private static final Pattern PH_PATTERN = Pattern.compile("(\\u0024\\{\\w*\\})+"); + private static Set getAllPlaceholders(String value) { + Matcher matcher = PH_PATTERN.matcher(value); + Set placeholders = new HashSet<>(); + int matcherStart = 0; + while (matcher.find(matcherStart)) { + String group = matcher.group(); + placeholders.add(group); + matcherStart = matcher.end(); + } + System.out.println(Arrays.toString(placeholders.toArray(new String[0]))); + return placeholders; + } + +} diff --git a/src/main/java/com/diguage/truman/concurrent/CompletedFutureTest.java b/src/main/java/com/diguage/truman/concurrent/CompletedFutureTest.java new file mode 100644 index 0000000..515b022 --- /dev/null +++ b/src/main/java/com/diguage/truman/concurrent/CompletedFutureTest.java @@ -0,0 +1,126 @@ +package com.diguage.truman.concurrent; + +import org.junit.jupiter.api.Test; + +import java.time.LocalTime; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.LockSupport; + +public class CompletedFutureTest { + + + /** + * 入门 + */ + @Test + public void testIntro() throws ExecutionException, InterruptedException { + CompletableFuture future = new CompletableFuture<>(); + new Thread(() -> { + System.out.println("CompletableFuture 可以监控任务执行情况"); + future.complete("Result: https://www.diguage.com"); + }).start(); + System.out.println(future.get()); + } + + + @Test + public void test3() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> { +// try { +// TimeUnit.SECONDS.sleep(5); +// } catch (InterruptedException e) { +// } + return 0; + }); + try { + future.get(1, TimeUnit.SECONDS); + } catch (TimeoutException e) { + System.out.println("timeout"); + } catch (Throwable e) { + } + try { + System.out.println("get task1: " + future.get()); + } catch (Throwable e) { + } + future.thenComposeAsync(r -> CompletableFuture.supplyAsync(() -> { + System.out.println("get task1 result=" + r); + return 1; + })); + } + + + @Test + public void test2() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> { + monteCarloMethod(Long.MAX_VALUE); + return 0; + }); + + try { + future.get(1, TimeUnit.SECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + while (true) { + System.out.println("timeout, and then throw an error."); + } + } + LockSupport.park(); + } + + + @Test + public void test() throws ExecutionException, InterruptedException { + AtomicInteger cnt = new AtomicInteger(0); + + CompletableFuture cf1 = CompletableFuture.supplyAsync(() -> monteCarloMethod(10000)); + CompletableFuture cf2 = CompletableFuture.supplyAsync(() -> monteCarloMethod(100000)); + CompletableFuture all = CompletableFuture.allOf(cf1, cf2); + + + System.out.println("start to get result"); + System.out.println(LocalTime.now() + " : " + cf1.get()); + System.out.println("got the result"); +// LockSupport.park(); + } + + /** + * 蒙特卡罗算法 + */ + private static double monteCarloMethod(long count) { + double pi = 0; + int circles = 0; + int squares = 0; + + // Total Random numbers generated = possible x + // values * possible y values + while (squares < count) { + + // Randomly generated x and y values in the range [-1,1] + double x = Math.random() * 2 - 1; + double y = Math.random() * 2 - 1; + + // Distance between (x, y) from the origin + double dist = x * x + y * y; + + // Checking if (x, y) lies inside the define + // circle with R=1 + if (dist <= 1) { + circles++; + } + + // Total number of points generated + squares++; + + // estimated pi after this iteration + pi = (4.0 * circles) / squares; + if (squares % 10 == 0) { + System.out.println(circles + " " + squares + " - " + pi); + } + } + + return pi; + } +} diff --git a/src/main/java/com/diguage/truman/stream/CollectorsTest.java b/src/main/java/com/diguage/truman/stream/CollectorsTest.java new file mode 100644 index 0000000..04fc53c --- /dev/null +++ b/src/main/java/com/diguage/truman/stream/CollectorsTest.java @@ -0,0 +1,19 @@ +package com.diguage.truman.stream; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class CollectorsTest { + @Test + public void testToList() { + List ints = Arrays.asList(1, 2, 3); + List filtered = ints.stream() + .filter(i -> i > 5) + .collect(Collectors.toList()); + System.out.println(Objects.isNull(filtered)); + } +}