From 4db9c44d18dddbbfdb91272c0b7612924d4e0ec4 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Mon, 13 Mar 2023 18:23:14 +0800 Subject: [PATCH 01/18] =?UTF-8?q?[feature]=20=E6=96=B0=E5=A2=9EBooleanUtil?= =?UTF-8?q?.isJsFalsy=E4=BB=A5=E5=8F=8AisJsTruthy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/hutool/core/util/BooleanUtil.java | 26 +++++++++++++++++ .../cn/hutool/core/util/BooleanUtilTest.java | 28 ++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java index 6825f0c07..24bd72b1b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java @@ -17,6 +17,8 @@ public class BooleanUtil { private static final Set TRUE_SET = SetUtil.of("true", "yes", "y", "t", "ok", "1", "on", "是", "对", "真", "對", "√"); /** 表示为假的字符串 */ private static final Set FALSE_SET = SetUtil.of("false", "no", "n", "f", "0", "off", "否", "错", "假", "錯", "×"); + /** js中表示假值Falsy的部分值 false、0、-0、0n、""、null、undefined 和 NaN */ + public static final Set FALSY_SET = SetUtil.of(false, 0, -0, 0L, 0.0D, -0.0D, "", null); /** * 取相反值 @@ -522,4 +524,28 @@ public class BooleanUtil { public static boolean isBoolean(final Class clazz) { return (clazz == Boolean.class || clazz == boolean.class); } + + /** + * 是否为假值(定义来源js) + * + * @param value 参数 + * @return 是否为假值 + * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy} + */ + public static boolean isJsFalsy(Object value) { + return FALSY_SET.contains(value); + } + + /** + * 是否为真值(定义来源js) + * 所有除 false、0、-0、0n、""、null、undefined 和 NaN 以外的皆为真值 + * 由于java中无法使用值来代表undefined 和 NaN,因此此处不做判断 + * + * @param value 参数 + * @return 是否为真值 + * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy} + */ + public static boolean isJsTruthy(Object value) { + return false == isJsFalsy(value); + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java index d143ab03b..f6314eae6 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java @@ -86,7 +86,7 @@ public class BooleanUtilTest { @SuppressWarnings("ConstantConditions") @Test - public void toBooleanObjectTest(){ + public void toBooleanObjectTest() { Assert.assertTrue(BooleanUtil.toBooleanObject("yes")); Assert.assertTrue(BooleanUtil.toBooleanObject("真")); Assert.assertTrue(BooleanUtil.toBooleanObject("是")); @@ -95,4 +95,30 @@ public class BooleanUtilTest { Assert.assertNull(BooleanUtil.toBooleanObject(null)); Assert.assertNull(BooleanUtil.toBooleanObject("不识别")); } + + @Test + public void isJsFalsyTest() { + Assert.assertTrue(BooleanUtil.isJsFalsy(false)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0)); + Assert.assertTrue(BooleanUtil.isJsFalsy(-0)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0L)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0.0D)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0.00D)); + Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00D)); + Assert.assertTrue(BooleanUtil.isJsFalsy("")); + Assert.assertTrue(BooleanUtil.isJsFalsy(null)); + } + + @Test + public void isJsTruthyTest() { + Assert.assertTrue(BooleanUtil.isJsTruthy(true)); + Assert.assertTrue(BooleanUtil.isJsTruthy(1)); + Assert.assertTrue(BooleanUtil.isJsTruthy(-1)); + Assert.assertTrue(BooleanUtil.isJsTruthy("0")); + Assert.assertTrue(BooleanUtil.isJsTruthy("null")); + Assert.assertTrue(BooleanUtil.isJsTruthy("undefined")); + Assert.assertTrue(BooleanUtil.isJsTruthy(1L)); + Assert.assertTrue(BooleanUtil.isJsTruthy(0.1D)); + Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01D)); + } } From 4ccb44ee2694c1b0b514985465335d77be1fdb63 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Tue, 14 Mar 2023 11:06:28 +0800 Subject: [PATCH 02/18] =?UTF-8?q?[enhancement]=20=E6=94=AF=E6=8C=81Float?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/hutool/core/util/BooleanUtil.java | 2 +- .../src/test/java/cn/hutool/core/util/BooleanUtilTest.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java index 24bd72b1b..43119ee2e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java @@ -18,7 +18,7 @@ public class BooleanUtil { /** 表示为假的字符串 */ private static final Set FALSE_SET = SetUtil.of("false", "no", "n", "f", "0", "off", "否", "错", "假", "錯", "×"); /** js中表示假值Falsy的部分值 false、0、-0、0n、""、null、undefined 和 NaN */ - public static final Set FALSY_SET = SetUtil.of(false, 0, -0, 0L, 0.0D, -0.0D, "", null); + public static final Set FALSY_SET = SetUtil.of(false, 0, -0, 0L, 0.0D, -0.0D, 0.0F, -0.0F, "", null); /** * 取相反值 diff --git a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java index f6314eae6..7c4721720 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java @@ -105,6 +105,9 @@ public class BooleanUtilTest { Assert.assertTrue(BooleanUtil.isJsFalsy(0.0D)); Assert.assertTrue(BooleanUtil.isJsFalsy(0.00D)); Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00D)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0.0F)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0.00F)); + Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00F)); Assert.assertTrue(BooleanUtil.isJsFalsy("")); Assert.assertTrue(BooleanUtil.isJsFalsy(null)); } @@ -120,5 +123,6 @@ public class BooleanUtilTest { Assert.assertTrue(BooleanUtil.isJsTruthy(1L)); Assert.assertTrue(BooleanUtil.isJsTruthy(0.1D)); Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01D)); + Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01F)); } } From d620a72585f286f07cc7220a6651937b4f4a6972 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Tue, 14 Mar 2023 15:53:38 +0800 Subject: [PATCH 03/18] =?UTF-8?q?[enhancement]=20=E6=94=AF=E6=8C=81NaN?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/hutool/core/util/BooleanUtil.java | 10 ++++++++-- .../test/java/cn/hutool/core/util/BooleanUtilTest.java | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java index 43119ee2e..79f5a74ca 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java @@ -533,13 +533,19 @@ public class BooleanUtil { * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy} */ public static boolean isJsFalsy(Object value) { - return FALSY_SET.contains(value); + if (FALSY_SET.contains(value)) { + return true; + } + if (value instanceof Double) { + return Double.isNaN((Double) value); + } + return false; } /** * 是否为真值(定义来源js) * 所有除 false、0、-0、0n、""、null、undefined 和 NaN 以外的皆为真值 - * 由于java中无法使用值来代表undefined 和 NaN,因此此处不做判断 + * 由于java中无法使用值来代表undefined,因此此处不做判断 * * @param value 参数 * @return 是否为真值 diff --git a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java index 7c4721720..75120c36f 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java @@ -110,6 +110,7 @@ public class BooleanUtilTest { Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00F)); Assert.assertTrue(BooleanUtil.isJsFalsy("")); Assert.assertTrue(BooleanUtil.isJsFalsy(null)); + Assert.assertTrue(BooleanUtil.isJsFalsy(Math.sqrt(-1))); } @Test From 5cd64819535054d90c10c933104f35ba76f67ec1 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Tue, 14 Mar 2023 16:05:19 +0800 Subject: [PATCH 04/18] =?UTF-8?q?[enhancement]=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/hutool/core/util/BooleanUtil.java | 6 +-- .../cn/hutool/core/util/BooleanUtilTest.java | 50 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java index 79f5a74ca..47a23738e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java @@ -532,7 +532,7 @@ public class BooleanUtil { * @return 是否为假值 * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy} */ - public static boolean isJsFalsy(Object value) { + public static boolean isFalsy(Object value) { if (FALSY_SET.contains(value)) { return true; } @@ -551,7 +551,7 @@ public class BooleanUtil { * @return 是否为真值 * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy} */ - public static boolean isJsTruthy(Object value) { - return false == isJsFalsy(value); + public static boolean isTruthy(Object value) { + return false == isFalsy(value); } } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java index 75120c36f..a4c468575 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java @@ -97,33 +97,33 @@ public class BooleanUtilTest { } @Test - public void isJsFalsyTest() { - Assert.assertTrue(BooleanUtil.isJsFalsy(false)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0)); - Assert.assertTrue(BooleanUtil.isJsFalsy(-0)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0L)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0.0D)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0.00D)); - Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00D)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0.0F)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0.00F)); - Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00F)); - Assert.assertTrue(BooleanUtil.isJsFalsy("")); - Assert.assertTrue(BooleanUtil.isJsFalsy(null)); - Assert.assertTrue(BooleanUtil.isJsFalsy(Math.sqrt(-1))); + public void isFalsyTest() { + Assert.assertTrue(BooleanUtil.isFalsy(false)); + Assert.assertTrue(BooleanUtil.isFalsy(0)); + Assert.assertTrue(BooleanUtil.isFalsy(-0)); + Assert.assertTrue(BooleanUtil.isFalsy(0L)); + Assert.assertTrue(BooleanUtil.isFalsy(0.0D)); + Assert.assertTrue(BooleanUtil.isFalsy(0.00D)); + Assert.assertTrue(BooleanUtil.isFalsy(-0.00D)); + Assert.assertTrue(BooleanUtil.isFalsy(0.0F)); + Assert.assertTrue(BooleanUtil.isFalsy(0.00F)); + Assert.assertTrue(BooleanUtil.isFalsy(-0.00F)); + Assert.assertTrue(BooleanUtil.isFalsy("")); + Assert.assertTrue(BooleanUtil.isFalsy(null)); + Assert.assertTrue(BooleanUtil.isFalsy(Math.sqrt(-1))); } @Test - public void isJsTruthyTest() { - Assert.assertTrue(BooleanUtil.isJsTruthy(true)); - Assert.assertTrue(BooleanUtil.isJsTruthy(1)); - Assert.assertTrue(BooleanUtil.isJsTruthy(-1)); - Assert.assertTrue(BooleanUtil.isJsTruthy("0")); - Assert.assertTrue(BooleanUtil.isJsTruthy("null")); - Assert.assertTrue(BooleanUtil.isJsTruthy("undefined")); - Assert.assertTrue(BooleanUtil.isJsTruthy(1L)); - Assert.assertTrue(BooleanUtil.isJsTruthy(0.1D)); - Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01D)); - Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01F)); + public void isTruthyTest() { + Assert.assertTrue(BooleanUtil.isTruthy(true)); + Assert.assertTrue(BooleanUtil.isTruthy(1)); + Assert.assertTrue(BooleanUtil.isTruthy(-1)); + Assert.assertTrue(BooleanUtil.isTruthy("0")); + Assert.assertTrue(BooleanUtil.isTruthy("null")); + Assert.assertTrue(BooleanUtil.isTruthy("undefined")); + Assert.assertTrue(BooleanUtil.isTruthy(1L)); + Assert.assertTrue(BooleanUtil.isTruthy(0.1D)); + Assert.assertTrue(BooleanUtil.isTruthy(-0.01D)); + Assert.assertTrue(BooleanUtil.isTruthy(-0.01F)); } } From 50178ee1ab6794e6d59f9e3328af3bfb5318b621 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 15 Mar 2023 09:12:56 +0800 Subject: [PATCH 05/18] add NFA --- .../text/dfa/{Automaton.java => NFA.java} | 43 ++-- .../hutool/core/text/dfa/AutomatonTest.java | 225 ----------------- .../java/cn/hutool/core/text/dfa/NFATest.java | 228 ++++++++++++++++++ 3 files changed, 250 insertions(+), 246 deletions(-) rename hutool-core/src/main/java/cn/hutool/core/text/dfa/{Automaton.java => NFA.java} (73%) delete mode 100644 hutool-core/src/test/java/cn/hutool/core/text/dfa/AutomatonTest.java create mode 100644 hutool-core/src/test/java/cn/hutool/core/text/dfa/NFATest.java diff --git a/hutool-core/src/main/java/cn/hutool/core/text/dfa/Automaton.java b/hutool-core/src/main/java/cn/hutool/core/text/dfa/NFA.java similarity index 73% rename from hutool-core/src/main/java/cn/hutool/core/text/dfa/Automaton.java rename to hutool-core/src/main/java/cn/hutool/core/text/dfa/NFA.java index c34f8b676..468658a62 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/dfa/Automaton.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/dfa/NFA.java @@ -9,13 +9,13 @@ import java.util.*; * * @author renyp */ -public class Automaton { +public class NFA { private final Node root; /** * 默认构造 */ - public Automaton() { + public NFA() { this.root = new Node(); } @@ -24,7 +24,7 @@ public class Automaton { * * @param words 添加的新词 */ - public Automaton(String... words) { + public NFA(final String... words) { this(); this.insert(words); } @@ -34,14 +34,13 @@ public class Automaton { * * @param word 添加的新词 */ - public void insert(String word) { + public void insert(final String word) { Node p = root; - for (char curr : word.toCharArray()) { - int ind = curr; - if (p.next.get(ind) == null) { - p.next.put(ind, new Node()); + for (final char curr : word.toCharArray()) { + if (p.next.get((int) curr) == null) { + p.next.put((int) curr, new Node()); } - p = p.next.get(ind); + p = p.next.get((int) curr); } p.flag = true; p.str = word; @@ -52,8 +51,8 @@ public class Automaton { * * @param words 添加的新词 */ - public void insert(String... words) { - for (String word : words) { + public void insert(final String... words) { + for (final String word : words) { this.insert(word); } } @@ -62,15 +61,15 @@ public class Automaton { * 构建基于NFA模型的 AC自动机 */ public void buildAc() { - Queue queue = new LinkedList<>(); - Node p = root; - for (Integer key : p.next.keySet()) { + final Queue queue = new LinkedList<>(); + final Node p = root; + for (final Integer key : p.next.keySet()) { p.next.get(key).fail = root; queue.offer(p.next.get(key)); } while (!queue.isEmpty()) { - Node curr = queue.poll(); - for (Integer key : curr.next.keySet()) { + final Node curr = queue.poll(); + for (final Integer key : curr.next.keySet()) { Node fail = curr.fail; // 查找当前节点匹配失败,他对应等效匹配的节点是哪个 while (fail != null && fail.next.get(key) == null) { @@ -90,20 +89,22 @@ public class Automaton { /** * @param text 查询的文本(母串) + * @return 关键字列表 */ - public List find(String text) { + public List find(final String text) { return this.find(text, true); } /** * @param text 查找的文本(母串) * @param isDensityMatch 是否密集匹配 + * @return 关键字列表 */ - public List find(String text, boolean isDensityMatch) { - List ans = new ArrayList<>(); - Node p = root, k = null; + public List find(final String text, final boolean isDensityMatch) { + final List ans = new ArrayList<>(); + Node p = root, k; for (int i = 0, len = text.length(); i < len; i++) { - int ind = text.charAt(i); + final int ind = text.charAt(i); // 状态转移(沿着fail指针链接的链表,此处区别于DFA模型) while (p != null && p.next.get(ind) == null) { p = p.fail; diff --git a/hutool-core/src/test/java/cn/hutool/core/text/dfa/AutomatonTest.java b/hutool-core/src/test/java/cn/hutool/core/text/dfa/AutomatonTest.java deleted file mode 100644 index 9acdf13b9..000000000 --- a/hutool-core/src/test/java/cn/hutool/core/text/dfa/AutomatonTest.java +++ /dev/null @@ -1,225 +0,0 @@ -package cn.hutool.core.text.dfa; - -import cn.hutool.core.date.StopWatch; -import junit.framework.TestCase; -import org.junit.Assert; -import org.junit.Test; - -import java.util.List; -import java.util.stream.Collectors; - -public class AutomatonTest extends TestCase { - - /** - * 密集匹配 测试查找结果,并与WordTree对比效率 - */ - public void testFind() { - Automaton automaton = new Automaton(); - WordTree wordTree = new WordTree(); - automaton.insert("say", "her", "he", "she", "shr"); - automaton.buildAc(); - wordTree.addWords("say", "her", "he", "she", "shr"); - - StopWatch stopWatch = new StopWatch(); - String input = "sasherhsay"; - - stopWatch.start("automaton_char_find"); - List ans1 = automaton.find(input); - stopWatch.stop(); - assertEquals("she,he,her,say", ans1.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); - assertEquals(Integer.valueOf(2), ans1.get(0).getStartIndex()); - assertEquals(Integer.valueOf(4), ans1.get(0).getEndIndex()); - assertEquals(Integer.valueOf(3), ans1.get(1).getStartIndex()); - assertEquals(Integer.valueOf(4), ans1.get(1).getEndIndex()); - assertEquals(Integer.valueOf(3), ans1.get(2).getStartIndex()); - assertEquals(Integer.valueOf(5), ans1.get(2).getEndIndex()); - assertEquals(Integer.valueOf(7), ans1.get(3).getStartIndex()); - assertEquals(Integer.valueOf(9), ans1.get(3).getEndIndex()); - - stopWatch.start("wordtree_char_find"); - List ans2 = wordTree.matchAll(input, -1, true, true); - stopWatch.stop(); - assertEquals("she,he,her,say", String.join(",", ans2)); - - System.out.println(stopWatch.prettyPrint()); - } - - /** - * 非密集匹配 测试查找结果,并与WordTree对比效率 - */ - public void testFindNotDensity() { - Automaton automaton = new Automaton(); - WordTree wordTree = new WordTree(); - automaton.insert("say", "her", "he", "she", "shr"); - automaton.buildAc(); - wordTree.addWords("say", "her", "he", "she", "shr"); - - StopWatch stopWatch = new StopWatch(); - String input = "sasherhsay"; - - stopWatch.start("automaton_char_find_not_density"); - List ans1 = automaton.find(input, false); - stopWatch.stop(); - assertEquals("she,say", ans1.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); - assertEquals(Integer.valueOf(2), ans1.get(0).getStartIndex()); - assertEquals(Integer.valueOf(4), ans1.get(0).getEndIndex()); - assertEquals(Integer.valueOf(7), ans1.get(1).getStartIndex()); - assertEquals(Integer.valueOf(9), ans1.get(1).getEndIndex()); - - stopWatch.start("wordtree_char_find_not_density"); - List ans2 = wordTree.matchAll(input, -1, false, true); - stopWatch.stop(); - assertEquals("she,say", String.join(",", ans2)); - - System.out.println(stopWatch.prettyPrint()); - } - - /** - * 密集匹配 测试建树和查找,并与WordTree对比效率 - */ - public void testBuildAndFind() { - StopWatch stopWatch = new StopWatch(); - String input = "sasherhsay"; - - stopWatch.start("automaton_char_buid_find"); - Automaton automatonLocal = new Automaton(); - automatonLocal.insert("say", "her", "he", "she", "shr"); - automatonLocal.buildAc(); - List ans1 = automatonLocal.find(input); - stopWatch.stop(); - assertEquals("she,he,her,say", ans1.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); - assertEquals(Integer.valueOf(2), ans1.get(0).getStartIndex()); - assertEquals(Integer.valueOf(4), ans1.get(0).getEndIndex()); - assertEquals(Integer.valueOf(3), ans1.get(1).getStartIndex()); - assertEquals(Integer.valueOf(4), ans1.get(1).getEndIndex()); - assertEquals(Integer.valueOf(3), ans1.get(2).getStartIndex()); - assertEquals(Integer.valueOf(5), ans1.get(2).getEndIndex()); - assertEquals(Integer.valueOf(7), ans1.get(3).getStartIndex()); - assertEquals(Integer.valueOf(9), ans1.get(3).getEndIndex()); - - stopWatch.start("wordtree_char_build_find"); - WordTree wordTreeLocal = new WordTree(); - wordTreeLocal.addWords("say", "her", "he", "she", "shr"); - List ans2 = wordTreeLocal.matchAll(input, -1, true, true); - stopWatch.stop(); - assertEquals("she,he,her,say", String.join(",", ans2)); - - System.out.println(stopWatch.prettyPrint()); - } - - /** - * 密集匹配 构建树和查找 测试中文字符,并与wordTree对比效率 - */ - @Test - public void testBuildFindCnChar() { - StopWatch stopWatch = new StopWatch(); - String input = "赵啊三在做什么"; - - stopWatch.start("automaton_cn_build_find"); - Automaton automatonLocal = new Automaton(); - automatonLocal.insert("赵", "赵啊", "赵啊三"); - automatonLocal.buildAc(); - - final List result = automatonLocal.find(input); - stopWatch.stop(); - - Assert.assertEquals(3, result.size()); - Assert.assertEquals("赵,赵啊,赵啊三", result.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); - assertEquals(Integer.valueOf(0), result.get(0).getStartIndex()); - assertEquals(Integer.valueOf(0), result.get(0).getEndIndex()); - assertEquals(Integer.valueOf(0), result.get(1).getStartIndex()); - assertEquals(Integer.valueOf(1), result.get(1).getEndIndex()); - assertEquals(Integer.valueOf(0), result.get(2).getStartIndex()); - assertEquals(Integer.valueOf(2), result.get(2).getEndIndex()); - - stopWatch.start("wordtree_cn_build_find"); - WordTree wordTreeLocal = new WordTree(); - wordTreeLocal.addWords("赵", "赵啊", "赵啊三"); - - final List result1 = wordTreeLocal.matchAll(input, -1, true, true); - stopWatch.stop(); - - Assert.assertEquals(3, result1.size()); - Assert.assertEquals("赵,赵啊,赵啊三", String.join(",", result1)); - - System.out.println(stopWatch.prettyPrint()); - - } - - /** - * 密集匹配 测试构建树和查找 中文字符,并与wordTree对比效率 - */ - @Test - public void testFindCNChar() { - StopWatch stopWatch = new StopWatch(); - String input = "赵啊三在做什么"; - - Automaton automatonLocal = new Automaton(); - automatonLocal.insert("赵", "赵啊", "赵啊三"); - automatonLocal.buildAc(); - - stopWatch.start("automaton_cn_find"); - final List result = automatonLocal.find(input); - stopWatch.stop(); - - Assert.assertEquals(3, result.size()); - Assert.assertEquals("赵,赵啊,赵啊三", result.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); - assertEquals(Integer.valueOf(0), result.get(0).getStartIndex()); - assertEquals(Integer.valueOf(0), result.get(0).getEndIndex()); - assertEquals(Integer.valueOf(0), result.get(1).getStartIndex()); - assertEquals(Integer.valueOf(1), result.get(1).getEndIndex()); - assertEquals(Integer.valueOf(0), result.get(2).getStartIndex()); - assertEquals(Integer.valueOf(2), result.get(2).getEndIndex()); - - WordTree wordTreeLocal = new WordTree(); - wordTreeLocal.addWords("赵", "赵啊", "赵啊三"); - - stopWatch.start("wordtree_cn_find"); - final List result1 = wordTreeLocal.matchAllWords(input, -1, true, true).stream().map(FoundWord::getWord) - .collect(Collectors.toList()); - stopWatch.stop(); - - Assert.assertEquals(3, result1.size()); - Assert.assertEquals("赵,赵啊,赵啊三", String.join(",", result1)); - - System.out.println(stopWatch.prettyPrint()); - - } - - /** - * 非密集匹配 测试构建树和查找 中文字符,并与wordTree对比效率, - */ - @Test - public void testFindCNCharNotDensity() { - StopWatch stopWatch = new StopWatch(); - String input = "赵啊三在做什么"; - - Automaton automatonLocal = new Automaton(); - automatonLocal.insert("赵", "赵啊", "赵啊三"); - automatonLocal.buildAc(); - - stopWatch.start("automaton_cn_find_not_density"); - final List result = automatonLocal.find(input, false); - stopWatch.stop(); - - Assert.assertEquals(1, result.size()); - Assert.assertEquals("赵", result.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); - assertEquals(Integer.valueOf(0), result.get(0).getStartIndex()); - assertEquals(Integer.valueOf(0), result.get(0).getEndIndex()); - - WordTree wordTreeLocal = new WordTree(); - wordTreeLocal.addWords("赵", "赵啊", "赵啊三"); - - stopWatch.start("wordtree_cn_find_not_density"); - final List result1 = - wordTreeLocal.matchAllWords(input, -1, false, true).stream().map(FoundWord::getWord) - .collect(Collectors.toList()); - stopWatch.stop(); - - Assert.assertEquals(1, result1.size()); - Assert.assertEquals("赵", String.join(",", result1)); - - System.out.println(stopWatch.prettyPrint()); - - } -} diff --git a/hutool-core/src/test/java/cn/hutool/core/text/dfa/NFATest.java b/hutool-core/src/test/java/cn/hutool/core/text/dfa/NFATest.java new file mode 100644 index 000000000..e38be87f3 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/text/dfa/NFATest.java @@ -0,0 +1,228 @@ +package cn.hutool.core.text.dfa; + +import cn.hutool.core.date.StopWatch; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; +import java.util.stream.Collectors; + +public class NFATest { + + /** + * 密集匹配 测试查找结果,并与WordTree对比效率 + */ + @Test + public void testFind() { + final NFA NFA = new NFA(); + NFA.insert("say", "her", "he", "she", "shr"); + NFA.buildAc(); + + final WordTree wordTree = new WordTree(); + wordTree.addWords("say", "her", "he", "she", "shr"); + + final StopWatch stopWatch = new StopWatch(); + final String input = "sasherhsay"; + + stopWatch.start("automaton_char_find"); + final List ans1 = NFA.find(input); + stopWatch.stop(); + + Assert.assertEquals("she,he,her,say", ans1.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); + Assert.assertEquals(2, ans1.get(0).getBeginIndex().intValue()); + Assert.assertEquals(4, ans1.get(0).getEndIndex().intValue()); + Assert.assertEquals(3, ans1.get(1).getBeginIndex().intValue()); + Assert.assertEquals(4, ans1.get(1).getEndIndex().intValue()); + Assert.assertEquals(3, ans1.get(2).getBeginIndex().intValue()); + Assert.assertEquals(5, ans1.get(2).getEndIndex().intValue()); + Assert.assertEquals(7, ans1.get(3).getBeginIndex().intValue()); + Assert.assertEquals(9, ans1.get(3).getEndIndex().intValue()); + + stopWatch.start("wordtree_char_find"); + final List ans2 = wordTree.matchAll(input, -1, true, true); + stopWatch.stop(); + Assert.assertEquals("she,he,her,say", String.join(",", ans2)); + + //Console.log(stopWatch.prettyPrint()); + } + + /** + * 非密集匹配 测试查找结果,并与WordTree对比效率 + */ + @Test + public void testFindNotDensity() { + final NFA NFA = new NFA(); + NFA.insert("say", "her", "he", "she", "shr"); + NFA.buildAc(); + + final WordTree wordTree = new WordTree(); + wordTree.addWords("say", "her", "he", "she", "shr"); + + final StopWatch stopWatch = new StopWatch(); + final String input = "sasherhsay"; + + stopWatch.start("automaton_char_find_not_density"); + final List ans1 = NFA.find(input, false); + stopWatch.stop(); + Assert.assertEquals("she,say", ans1.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); + Assert.assertEquals(2, ans1.get(0).getBeginIndex().intValue()); + Assert.assertEquals(4, ans1.get(0).getEndIndex().intValue()); + Assert.assertEquals(7, ans1.get(1).getBeginIndex().intValue()); + Assert.assertEquals(9, ans1.get(1).getEndIndex().intValue()); + + stopWatch.start("wordtree_char_find_not_density"); + final List ans2 = wordTree.matchAll(input, -1, false, true); + stopWatch.stop(); + Assert.assertEquals("she,say", String.join(",", ans2)); + + //Console.log(stopWatch.prettyPrint()); + } + + /** + * 密集匹配 测试建树和查找,并与WordTree对比效率 + */ + @Test + public void testBuildAndFind() { + final StopWatch stopWatch = new StopWatch(); + final String input = "sasherhsay"; + + stopWatch.start("automaton_char_buid_find"); + final NFA NFALocal = new NFA(); + NFALocal.insert("say", "her", "he", "she", "shr"); + NFALocal.buildAc(); + final List ans1 = NFALocal.find(input); + stopWatch.stop(); + + Assert.assertEquals("she,he,her,say", ans1.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); + Assert.assertEquals(2, ans1.get(0).getBeginIndex().intValue()); + Assert.assertEquals(4, ans1.get(0).getEndIndex().intValue()); + Assert.assertEquals(3, ans1.get(1).getBeginIndex().intValue()); + Assert.assertEquals(4, ans1.get(1).getEndIndex().intValue()); + Assert.assertEquals(3, ans1.get(2).getBeginIndex().intValue()); + Assert.assertEquals(5, ans1.get(2).getEndIndex().intValue()); + Assert.assertEquals(7, ans1.get(3).getBeginIndex().intValue()); + Assert.assertEquals(9, ans1.get(3).getEndIndex().intValue()); + + stopWatch.start("wordtree_char_build_find"); + final WordTree wordTreeLocal = new WordTree(); + wordTreeLocal.addWords("say", "her", "he", "she", "shr"); + final List ans2 = wordTreeLocal.matchAll(input, -1, true, true); + stopWatch.stop(); + Assert.assertEquals("she,he,her,say", String.join(",", ans2)); + + //Console.log(stopWatch.prettyPrint()); + } + + /** + * 密集匹配 构建树和查找 测试中文字符,并与wordTree对比效率 + */ + @Test + public void buildFindCnCharTest() { + final StopWatch stopWatch = new StopWatch(); + final String input = "赵啊三在做什么"; + + stopWatch.start("automaton_cn_build_find"); + final NFA NFALocal = new NFA(); + NFALocal.insert("赵", "赵啊", "赵啊三"); + NFALocal.buildAc(); + + final List result = NFALocal.find(input); + stopWatch.stop(); + + Assert.assertEquals(3, result.size()); + Assert.assertEquals("赵,赵啊,赵啊三", result.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); + Assert.assertEquals(Integer.valueOf(0), result.get(0).getBeginIndex()); + Assert.assertEquals(Integer.valueOf(0), result.get(0).getEndIndex()); + Assert.assertEquals(Integer.valueOf(0), result.get(1).getBeginIndex()); + Assert.assertEquals(Integer.valueOf(1), result.get(1).getEndIndex()); + Assert.assertEquals(Integer.valueOf(0), result.get(2).getBeginIndex()); + Assert.assertEquals(Integer.valueOf(2), result.get(2).getEndIndex()); + + stopWatch.start("wordtree_cn_build_find"); + final WordTree wordTreeLocal = new WordTree(); + wordTreeLocal.addWords("赵", "赵啊", "赵啊三"); + + final List result1 = wordTreeLocal.matchAll(input, -1, true, true); + stopWatch.stop(); + + Assert.assertEquals(3, result1.size()); + Assert.assertEquals("赵,赵啊,赵啊三", String.join(",", result1)); + + //Console.log(stopWatch.prettyPrint()); + } + + /** + * 密集匹配 测试构建树和查找 中文字符,并与wordTree对比效率 + */ + @Test + public void testFindCNChar() { + final StopWatch stopWatch = new StopWatch(); + final String input = "赵啊三在做什么"; + + final NFA NFALocal = new NFA(); + NFALocal.insert("赵", "赵啊", "赵啊三"); + NFALocal.buildAc(); + + stopWatch.start("automaton_cn_find"); + final List result = NFALocal.find(input); + stopWatch.stop(); + + Assert.assertEquals(3, result.size()); + Assert.assertEquals("赵,赵啊,赵啊三", result.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); + Assert.assertEquals(Integer.valueOf(0), result.get(0).getBeginIndex()); + Assert.assertEquals(Integer.valueOf(0), result.get(0).getEndIndex()); + Assert.assertEquals(Integer.valueOf(0), result.get(1).getBeginIndex()); + Assert.assertEquals(Integer.valueOf(1), result.get(1).getEndIndex()); + Assert.assertEquals(Integer.valueOf(0), result.get(2).getBeginIndex()); + Assert.assertEquals(Integer.valueOf(2), result.get(2).getEndIndex()); + + final WordTree wordTreeLocal = new WordTree(); + wordTreeLocal.addWords("赵", "赵啊", "赵啊三"); + + stopWatch.start("wordtree_cn_find"); + final List result1 = wordTreeLocal.matchAllWords(input, -1, true, true).stream().map(FoundWord::getWord) + .collect(Collectors.toList()); + stopWatch.stop(); + + Assert.assertEquals(3, result1.size()); + Assert.assertEquals("赵,赵啊,赵啊三", String.join(",", result1)); + + //Console.log(stopWatch.prettyPrint()); + } + + /** + * 非密集匹配 测试构建树和查找 中文字符,并与wordTree对比效率, + */ + @Test + public void testFindCNCharNotDensity() { + final StopWatch stopWatch = new StopWatch(); + final String input = "赵啊三在做什么"; + + final NFA NFALocal = new NFA(); + NFALocal.insert("赵", "赵啊", "赵啊三"); + NFALocal.buildAc(); + + stopWatch.start("automaton_cn_find_not_density"); + final List result = NFALocal.find(input, false); + stopWatch.stop(); + + Assert.assertEquals(1, result.size()); + Assert.assertEquals("赵", result.stream().map(FoundWord::getWord).collect(Collectors.joining(","))); + Assert.assertEquals(Integer.valueOf(0), result.get(0).getBeginIndex()); + Assert.assertEquals(Integer.valueOf(0), result.get(0).getEndIndex()); + + final WordTree wordTreeLocal = new WordTree(); + wordTreeLocal.addWords("赵", "赵啊", "赵啊三"); + + stopWatch.start("wordtree_cn_find_not_density"); + final List result1 = + wordTreeLocal.matchAllWords(input, -1, false, true).stream().map(FoundWord::getWord) + .collect(Collectors.toList()); + stopWatch.stop(); + + Assert.assertEquals(1, result1.size()); + Assert.assertEquals("赵", String.join(",", result1)); + + //Console.log(stopWatch.prettyPrint()); + } +} From 5a4ed96e0dca88c53596a3d162dab64dc27496e5 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Wed, 15 Mar 2023 09:59:44 +0800 Subject: [PATCH 06/18] =?UTF-8?q?Revert=20"[enhancement]=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=96=B9=E6=B3=95=E5=90=8D"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 5cd64819535054d90c10c933104f35ba76f67ec1. --- .../java/cn/hutool/core/util/BooleanUtil.java | 6 +-- .../cn/hutool/core/util/BooleanUtilTest.java | 50 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java index 47a23738e..79f5a74ca 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java @@ -532,7 +532,7 @@ public class BooleanUtil { * @return 是否为假值 * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy} */ - public static boolean isFalsy(Object value) { + public static boolean isJsFalsy(Object value) { if (FALSY_SET.contains(value)) { return true; } @@ -551,7 +551,7 @@ public class BooleanUtil { * @return 是否为真值 * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy} */ - public static boolean isTruthy(Object value) { - return false == isFalsy(value); + public static boolean isJsTruthy(Object value) { + return false == isJsFalsy(value); } } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java index a4c468575..75120c36f 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java @@ -97,33 +97,33 @@ public class BooleanUtilTest { } @Test - public void isFalsyTest() { - Assert.assertTrue(BooleanUtil.isFalsy(false)); - Assert.assertTrue(BooleanUtil.isFalsy(0)); - Assert.assertTrue(BooleanUtil.isFalsy(-0)); - Assert.assertTrue(BooleanUtil.isFalsy(0L)); - Assert.assertTrue(BooleanUtil.isFalsy(0.0D)); - Assert.assertTrue(BooleanUtil.isFalsy(0.00D)); - Assert.assertTrue(BooleanUtil.isFalsy(-0.00D)); - Assert.assertTrue(BooleanUtil.isFalsy(0.0F)); - Assert.assertTrue(BooleanUtil.isFalsy(0.00F)); - Assert.assertTrue(BooleanUtil.isFalsy(-0.00F)); - Assert.assertTrue(BooleanUtil.isFalsy("")); - Assert.assertTrue(BooleanUtil.isFalsy(null)); - Assert.assertTrue(BooleanUtil.isFalsy(Math.sqrt(-1))); + public void isJsFalsyTest() { + Assert.assertTrue(BooleanUtil.isJsFalsy(false)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0)); + Assert.assertTrue(BooleanUtil.isJsFalsy(-0)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0L)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0.0D)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0.00D)); + Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00D)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0.0F)); + Assert.assertTrue(BooleanUtil.isJsFalsy(0.00F)); + Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00F)); + Assert.assertTrue(BooleanUtil.isJsFalsy("")); + Assert.assertTrue(BooleanUtil.isJsFalsy(null)); + Assert.assertTrue(BooleanUtil.isJsFalsy(Math.sqrt(-1))); } @Test - public void isTruthyTest() { - Assert.assertTrue(BooleanUtil.isTruthy(true)); - Assert.assertTrue(BooleanUtil.isTruthy(1)); - Assert.assertTrue(BooleanUtil.isTruthy(-1)); - Assert.assertTrue(BooleanUtil.isTruthy("0")); - Assert.assertTrue(BooleanUtil.isTruthy("null")); - Assert.assertTrue(BooleanUtil.isTruthy("undefined")); - Assert.assertTrue(BooleanUtil.isTruthy(1L)); - Assert.assertTrue(BooleanUtil.isTruthy(0.1D)); - Assert.assertTrue(BooleanUtil.isTruthy(-0.01D)); - Assert.assertTrue(BooleanUtil.isTruthy(-0.01F)); + public void isJsTruthyTest() { + Assert.assertTrue(BooleanUtil.isJsTruthy(true)); + Assert.assertTrue(BooleanUtil.isJsTruthy(1)); + Assert.assertTrue(BooleanUtil.isJsTruthy(-1)); + Assert.assertTrue(BooleanUtil.isJsTruthy("0")); + Assert.assertTrue(BooleanUtil.isJsTruthy("null")); + Assert.assertTrue(BooleanUtil.isJsTruthy("undefined")); + Assert.assertTrue(BooleanUtil.isJsTruthy(1L)); + Assert.assertTrue(BooleanUtil.isJsTruthy(0.1D)); + Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01D)); + Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01F)); } } From 8efe8fb2fda6610a6fe6505a69f54652f1444079 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Wed, 15 Mar 2023 09:59:48 +0800 Subject: [PATCH 07/18] =?UTF-8?q?Revert=20"[enhancement]=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81NaN=E7=B1=BB=E5=9E=8B"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit d620a72585f286f07cc7220a6651937b4f4a6972. --- .../src/main/java/cn/hutool/core/util/BooleanUtil.java | 10 ++-------- .../test/java/cn/hutool/core/util/BooleanUtilTest.java | 1 - 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java index 79f5a74ca..43119ee2e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java @@ -533,19 +533,13 @@ public class BooleanUtil { * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy} */ public static boolean isJsFalsy(Object value) { - if (FALSY_SET.contains(value)) { - return true; - } - if (value instanceof Double) { - return Double.isNaN((Double) value); - } - return false; + return FALSY_SET.contains(value); } /** * 是否为真值(定义来源js) * 所有除 false、0、-0、0n、""、null、undefined 和 NaN 以外的皆为真值 - * 由于java中无法使用值来代表undefined,因此此处不做判断 + * 由于java中无法使用值来代表undefined 和 NaN,因此此处不做判断 * * @param value 参数 * @return 是否为真值 diff --git a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java index 75120c36f..7c4721720 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java @@ -110,7 +110,6 @@ public class BooleanUtilTest { Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00F)); Assert.assertTrue(BooleanUtil.isJsFalsy("")); Assert.assertTrue(BooleanUtil.isJsFalsy(null)); - Assert.assertTrue(BooleanUtil.isJsFalsy(Math.sqrt(-1))); } @Test From 2919749c8f1c23961fff9e4cf76e02aed888803f Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Wed, 15 Mar 2023 09:59:53 +0800 Subject: [PATCH 08/18] =?UTF-8?q?Revert=20"[enhancement]=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81Float=E7=B1=BB=E5=9E=8B"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4ccb44ee2694c1b0b514985465335d77be1fdb63. --- .../src/main/java/cn/hutool/core/util/BooleanUtil.java | 2 +- .../src/test/java/cn/hutool/core/util/BooleanUtilTest.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java index 43119ee2e..24bd72b1b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java @@ -18,7 +18,7 @@ public class BooleanUtil { /** 表示为假的字符串 */ private static final Set FALSE_SET = SetUtil.of("false", "no", "n", "f", "0", "off", "否", "错", "假", "錯", "×"); /** js中表示假值Falsy的部分值 false、0、-0、0n、""、null、undefined 和 NaN */ - public static final Set FALSY_SET = SetUtil.of(false, 0, -0, 0L, 0.0D, -0.0D, 0.0F, -0.0F, "", null); + public static final Set FALSY_SET = SetUtil.of(false, 0, -0, 0L, 0.0D, -0.0D, "", null); /** * 取相反值 diff --git a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java index 7c4721720..f6314eae6 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java @@ -105,9 +105,6 @@ public class BooleanUtilTest { Assert.assertTrue(BooleanUtil.isJsFalsy(0.0D)); Assert.assertTrue(BooleanUtil.isJsFalsy(0.00D)); Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00D)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0.0F)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0.00F)); - Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00F)); Assert.assertTrue(BooleanUtil.isJsFalsy("")); Assert.assertTrue(BooleanUtil.isJsFalsy(null)); } @@ -123,6 +120,5 @@ public class BooleanUtilTest { Assert.assertTrue(BooleanUtil.isJsTruthy(1L)); Assert.assertTrue(BooleanUtil.isJsTruthy(0.1D)); Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01D)); - Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01F)); } } From a1144f5228df187431bb6b9e4af1c755a2e1923c Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Wed, 15 Mar 2023 09:59:58 +0800 Subject: [PATCH 09/18] =?UTF-8?q?Revert=20"[feature]=20=E6=96=B0=E5=A2=9EB?= =?UTF-8?q?ooleanUtil.isJsFalsy=E4=BB=A5=E5=8F=8AisJsTruthy"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4db9c44d18dddbbfdb91272c0b7612924d4e0ec4. --- .../java/cn/hutool/core/util/BooleanUtil.java | 26 ----------------- .../cn/hutool/core/util/BooleanUtilTest.java | 28 +------------------ 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java index 24bd72b1b..6825f0c07 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/BooleanUtil.java @@ -17,8 +17,6 @@ public class BooleanUtil { private static final Set TRUE_SET = SetUtil.of("true", "yes", "y", "t", "ok", "1", "on", "是", "对", "真", "對", "√"); /** 表示为假的字符串 */ private static final Set FALSE_SET = SetUtil.of("false", "no", "n", "f", "0", "off", "否", "错", "假", "錯", "×"); - /** js中表示假值Falsy的部分值 false、0、-0、0n、""、null、undefined 和 NaN */ - public static final Set FALSY_SET = SetUtil.of(false, 0, -0, 0L, 0.0D, -0.0D, "", null); /** * 取相反值 @@ -524,28 +522,4 @@ public class BooleanUtil { public static boolean isBoolean(final Class clazz) { return (clazz == Boolean.class || clazz == boolean.class); } - - /** - * 是否为假值(定义来源js) - * - * @param value 参数 - * @return 是否为假值 - * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy} - */ - public static boolean isJsFalsy(Object value) { - return FALSY_SET.contains(value); - } - - /** - * 是否为真值(定义来源js) - * 所有除 false、0、-0、0n、""、null、undefined 和 NaN 以外的皆为真值 - * 由于java中无法使用值来代表undefined 和 NaN,因此此处不做判断 - * - * @param value 参数 - * @return 是否为真值 - * 定义{@see https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy} - */ - public static boolean isJsTruthy(Object value) { - return false == isJsFalsy(value); - } } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java index f6314eae6..d143ab03b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/BooleanUtilTest.java @@ -86,7 +86,7 @@ public class BooleanUtilTest { @SuppressWarnings("ConstantConditions") @Test - public void toBooleanObjectTest() { + public void toBooleanObjectTest(){ Assert.assertTrue(BooleanUtil.toBooleanObject("yes")); Assert.assertTrue(BooleanUtil.toBooleanObject("真")); Assert.assertTrue(BooleanUtil.toBooleanObject("是")); @@ -95,30 +95,4 @@ public class BooleanUtilTest { Assert.assertNull(BooleanUtil.toBooleanObject(null)); Assert.assertNull(BooleanUtil.toBooleanObject("不识别")); } - - @Test - public void isJsFalsyTest() { - Assert.assertTrue(BooleanUtil.isJsFalsy(false)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0)); - Assert.assertTrue(BooleanUtil.isJsFalsy(-0)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0L)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0.0D)); - Assert.assertTrue(BooleanUtil.isJsFalsy(0.00D)); - Assert.assertTrue(BooleanUtil.isJsFalsy(-0.00D)); - Assert.assertTrue(BooleanUtil.isJsFalsy("")); - Assert.assertTrue(BooleanUtil.isJsFalsy(null)); - } - - @Test - public void isJsTruthyTest() { - Assert.assertTrue(BooleanUtil.isJsTruthy(true)); - Assert.assertTrue(BooleanUtil.isJsTruthy(1)); - Assert.assertTrue(BooleanUtil.isJsTruthy(-1)); - Assert.assertTrue(BooleanUtil.isJsTruthy("0")); - Assert.assertTrue(BooleanUtil.isJsTruthy("null")); - Assert.assertTrue(BooleanUtil.isJsTruthy("undefined")); - Assert.assertTrue(BooleanUtil.isJsTruthy(1L)); - Assert.assertTrue(BooleanUtil.isJsTruthy(0.1D)); - Assert.assertTrue(BooleanUtil.isJsTruthy(-0.01D)); - } } From bd83fbd973c5b09137c855e4ce0107c167ba3450 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Wed, 15 Mar 2023 10:47:52 +0800 Subject: [PATCH 10/18] =?UTF-8?q?[enhancement]=20=E4=BD=BFLambdaFactory.bu?= =?UTF-8?q?ild=E6=94=AF=E6=8C=81=E6=9E=84=E9=80=A0=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/lang/func/LambdaFactory.java | 38 ++++++++++++------- .../core/lang/func/LambdaFactoryTest.java | 17 ++++++--- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java index 38401bc96..b3b534c90 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java @@ -7,9 +7,12 @@ import cn.hutool.core.lang.mutable.MutableEntry; import cn.hutool.core.map.WeakConcurrentMap; import cn.hutool.core.reflect.LookupFactory; import cn.hutool.core.reflect.MethodUtil; +import cn.hutool.core.reflect.ReflectUtil; import java.io.Serializable; import java.lang.invoke.*; +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; @@ -31,7 +34,7 @@ public class LambdaFactory { throw new IllegalAccessException(); } - private static final Map, Method>, Object> CACHE = new WeakConcurrentMap<>(); + private static final Map, Executable>, Object> CACHE = new WeakConcurrentMap<>(); /** * 构建Lambda @@ -61,30 +64,37 @@ public class LambdaFactory { * 构建Lambda * * @param functionInterfaceType 接受Lambda的函数式接口类型 - * @param method 方法对象 + * @param executable 方法对象 + * @param Function类型 * @return 接受Lambda的函数式接口对象 - * @param Function类型 */ @SuppressWarnings("unchecked") - public static F build(final Class functionInterfaceType, final Method method) { + public static F build(final Class functionInterfaceType, final Executable executable) { Assert.notNull(functionInterfaceType); - Assert.notNull(method); - final MutableEntry, Method> cacheKey = new MutableEntry<>(functionInterfaceType, method); + Assert.notNull(executable); + final MutableEntry, Executable> cacheKey = new MutableEntry<>(functionInterfaceType, executable); return (F) CACHE.computeIfAbsent(cacheKey, key -> { final List abstractMethods = Arrays.stream(functionInterfaceType.getMethods()) .filter(m -> Modifier.isAbstract(m.getModifiers())) .collect(Collectors.toList()); Assert.equals(abstractMethods.size(), 1, "不支持非函数式接口"); - if (!method.isAccessible()) { - method.setAccessible(true); - } + ReflectUtil.setAccessible(executable); final Method invokeMethod = abstractMethods.get(0); - final MethodHandles.Lookup caller = LookupFactory.lookup(method.getDeclaringClass()); + final MethodHandles.Lookup caller = LookupFactory.lookup(executable.getDeclaringClass()); final String invokeName = invokeMethod.getName(); final MethodType invokedType = methodType(functionInterfaceType); final MethodType samMethodType = methodType(invokeMethod.getReturnType(), invokeMethod.getParameterTypes()); - final MethodHandle implMethod = Opt.ofTry(() -> caller.unreflect(method)).get(); - final MethodType insMethodType = methodType(method.getReturnType(), method.getDeclaringClass(), method.getParameterTypes()); + final MethodHandle implMethod; + final MethodType instantiatedMethodType; + if (executable instanceof Method) { + final Method method = (Method) executable; + implMethod = ((SerSupplier) () -> MethodHandles.lookup().unreflect(method)).get(); + instantiatedMethodType = MethodType.methodType(method.getReturnType(), method.getDeclaringClass(), method.getParameterTypes()); + } else { + final Constructor constructor = (Constructor) executable; + implMethod = ((SerSupplier) () -> MethodHandles.lookup().unreflectConstructor(constructor)).get(); + instantiatedMethodType = MethodType.methodType(constructor.getDeclaringClass(), constructor.getParameterTypes()); + } final boolean isSerializable = Serializable.class.isAssignableFrom(functionInterfaceType); try { final CallSite callSite = isSerializable ? @@ -94,7 +104,7 @@ public class LambdaFactory { invokedType, samMethodType, implMethod, - insMethodType, + instantiatedMethodType, FLAG_SERIALIZABLE ) : LambdaMetafactory.metafactory( @@ -103,7 +113,7 @@ public class LambdaFactory { invokedType, samMethodType, implMethod, - insMethodType + instantiatedMethodType ); //noinspection unchecked return (F) callSite.getTarget().invoke(); diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaFactoryTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaFactoryTest.java index 83f65ee41..db3f68ab3 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaFactoryTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaFactoryTest.java @@ -12,11 +12,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.lang.invoke.LambdaConversionException; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandleProxies; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; +import java.lang.invoke.*; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collection; @@ -24,6 +21,7 @@ import java.util.Comparator; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.function.Supplier; /** * @author nasodaengineer @@ -160,6 +158,15 @@ public class LambdaFactoryTest { loop(count, tasks); } + @Test + public void testConstructor() { + Constructor constructor = ((SerSupplier>) Something.class::getConstructor).get(); + Supplier constructorLambda = LambdaFactory.build(Supplier.class, constructor); + // constructorLambda can be cache or transfer + Something something = constructorLambda.get(); + Assert.assertEquals(Something.class, something.getClass()); + } + /** *

hardCode 运行1次耗时 7600 NANOSECONDS *

lambda 运行1次耗时 12400 NANOSECONDS From 94f3920bc25e0e30081ef947d5e9bdf3f0def257 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Wed, 15 Mar 2023 10:51:25 +0800 Subject: [PATCH 11/18] =?UTF-8?q?[enhancement]=20=E4=BD=BFLambdaFactory.bu?= =?UTF-8?q?ild=E6=94=AF=E6=8C=81=E6=9E=84=E9=80=A0=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/hutool/core/lang/func/LambdaFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java index b3b534c90..f425c83b2 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java @@ -64,7 +64,7 @@ public class LambdaFactory { * 构建Lambda * * @param functionInterfaceType 接受Lambda的函数式接口类型 - * @param executable 方法对象 + * @param executable 方法对象,支持构造器 * @param Function类型 * @return 接受Lambda的函数式接口对象 */ From 0797ceb12d7928a243993a217b148c1399e2714a Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 15 Mar 2023 16:22:10 +0800 Subject: [PATCH 12/18] fix test --- .../src/main/java/cn/hutool/core/io/SerializeUtil.java | 2 +- hutool-db/src/test/java/cn/hutool/db/CRUDTest.java | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/SerializeUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/SerializeUtil.java index 1cf940bde..9d80f0961 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/SerializeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/SerializeUtil.java @@ -44,7 +44,7 @@ public class SerializeUtil { return null; } final FastByteArrayOutputStream byteOut = new FastByteArrayOutputStream(); - IoUtil.writeObjects(byteOut, false, (Serializable) obj); + IoUtil.writeObjects(byteOut, false, obj); return byteOut.toByteArray(); } diff --git a/hutool-db/src/test/java/cn/hutool/db/CRUDTest.java b/hutool-db/src/test/java/cn/hutool/db/CRUDTest.java index 2005ca077..91847cf65 100644 --- a/hutool-db/src/test/java/cn/hutool/db/CRUDTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/CRUDTest.java @@ -99,6 +99,13 @@ public class CRUDTest { Assert.assertEquals(2, results.size()); } + @Test + public void findInTest4() { + final List results = db.findAll(Entity.of("user") + .set("id", new String[]{"1", "2", "3"})); + Assert.assertEquals(2, results.size()); + } + @Test public void findAllTest() { final List results = db.findAll("user"); From e611adc884cfb1ce63dc3413fce28b8bb7bdc52e Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 16 Mar 2023 23:06:05 +0800 Subject: [PATCH 13/18] fix code --- hutool-json/src/main/java/cn/hutool/json/JSONUtil.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java index df799b09b..4a47d9f80 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java @@ -2,6 +2,7 @@ package cn.hutool.json; import cn.hutool.core.io.file.FileUtil; import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.lang.Assert; import cn.hutool.core.reflect.TypeReference; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ObjUtil; @@ -364,6 +365,7 @@ public class JSONUtil { * @since 4.6.2 */ public static T toBean(final Object json, final TypeReference typeReference) { + Assert.notNull(typeReference); return toBean(json, typeReference.getType()); } From 569512fb5609ec20d575a37b7cc915ac8df78f40 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 17 Mar 2023 00:06:44 +0800 Subject: [PATCH 14/18] fix code --- .../cn/hutool/core/collection/ListUtil.java | 2 +- .../{math => lang/page}/NavigatePageInfo.java | 36 +++++++++----- .../core/{math => lang/page}/PageInfo.java | 14 ++++-- .../hutool/core/lang/page/package-info.java | 10 ++++ .../hutool/core/collection/ListUtilTest.java | 2 +- .../core/lang/page/NavigatePageInfoTest.java | 37 ++++++++++++++ .../{math => lang/page}/PageInfoTest.java | 2 +- .../cn/hutool/core/tree/IssueI6NR2ZTest.java | 48 +++++++++++++++++++ .../src/main/java/cn/hutool/db/Page.java | 2 +- .../main/java/cn/hutool/db/PageResult.java | 2 +- 10 files changed, 134 insertions(+), 21 deletions(-) rename hutool-core/src/main/java/cn/hutool/core/{math => lang/page}/NavigatePageInfo.java (63%) rename hutool-core/src/main/java/cn/hutool/core/{math => lang/page}/PageInfo.java (89%) create mode 100644 hutool-core/src/main/java/cn/hutool/core/lang/page/package-info.java create mode 100644 hutool-core/src/test/java/cn/hutool/core/lang/page/NavigatePageInfoTest.java rename hutool-core/src/test/java/cn/hutool/core/{math => lang/page}/PageInfoTest.java (96%) create mode 100644 hutool-core/src/test/java/cn/hutool/core/tree/IssueI6NR2ZTest.java diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java index d05b98999..cfdca2ada 100755 --- a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java @@ -8,7 +8,7 @@ import cn.hutool.core.collection.partition.RandomAccessPartition; import cn.hutool.core.comparator.PinyinComparator; import cn.hutool.core.comparator.PropertyComparator; import cn.hutool.core.lang.Assert; -import cn.hutool.core.math.PageInfo; +import cn.hutool.core.lang.page.PageInfo; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjUtil; diff --git a/hutool-core/src/main/java/cn/hutool/core/math/NavigatePageInfo.java b/hutool-core/src/main/java/cn/hutool/core/lang/page/NavigatePageInfo.java similarity index 63% rename from hutool-core/src/main/java/cn/hutool/core/math/NavigatePageInfo.java rename to hutool-core/src/main/java/cn/hutool/core/lang/page/NavigatePageInfo.java index cee14bc65..d605be398 100644 --- a/hutool-core/src/main/java/cn/hutool/core/math/NavigatePageInfo.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/page/NavigatePageInfo.java @@ -1,12 +1,13 @@ -package cn.hutool.core.math; +package cn.hutool.core.lang.page; -public class NavigatePageInfo extends PageInfo{ +public class NavigatePageInfo extends PageInfo { - private final int navigatePages = 8; //导航页码数 + private final int navigatePages; //导航页码数 private int[] navigatePageNumbers; //所有导航页号 - public NavigatePageInfo(final int total, final int pageSize) { + public NavigatePageInfo(final int total, final int pageSize, int navigatePages) { super(total, pageSize); + this.navigatePages = navigatePages; //基本参数设定之后进行导航页面的计算 calcNavigatePageNumbers(); @@ -22,17 +23,30 @@ public class NavigatePageInfo extends PageInfo{ } public String toString() { - final StringBuilder str = new StringBuilder(super.toString()); - str.append(", {navigatePageNumbers="); - final int len = navigatePageNumbers.length; - if (len > 0) str.append(navigatePageNumbers[0]); - for (int i = 1; i < len; i++) { - str.append(" ").append(navigatePageNumbers[i]); + final StringBuilder str = new StringBuilder(); + + if(false == isFirstPage()){ + str.append("<< "); + } + if (navigatePageNumbers.length > 0) { + str.append(wrap(navigatePageNumbers[0])); + } + for (int i = 1; i < navigatePageNumbers.length; i++) { + str.append(" ").append(wrap(navigatePageNumbers[i])); + } + if(false == isLastPage()){ + str.append(" >>"); } - str.append("}"); return str.toString(); } + private String wrap(final int pageNumber){ + if(this.pageNo == pageNumber){ + return "[" + pageNumber + "]"; + } + return String.valueOf(pageNumber); + } + /** * 计算导航页 */ diff --git a/hutool-core/src/main/java/cn/hutool/core/math/PageInfo.java b/hutool-core/src/main/java/cn/hutool/core/lang/page/PageInfo.java similarity index 89% rename from hutool-core/src/main/java/cn/hutool/core/math/PageInfo.java rename to hutool-core/src/main/java/cn/hutool/core/lang/page/PageInfo.java index a84079fff..461d1f87e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/math/PageInfo.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/page/PageInfo.java @@ -1,4 +1,4 @@ -package cn.hutool.core.math; +package cn.hutool.core.lang.page; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.DefaultSegment; @@ -227,7 +227,8 @@ public class PageInfo { /** * 设置首页编号,即以数字几为第一页标志
- * 如设置0,则0表示第一页,1表示第二页 + * 如设置0,则0表示第一页,1表示第二页
+ * 设置此参数后,须调用{@link #setPageNo(int)} 重新设置当前页的页码 * * @param firstPageNo 首页编号 * @return this @@ -238,7 +239,9 @@ public class PageInfo { } /** - * 设置当前页码 + * 设置当前页码,具体这个页码代表实际页,取决于{@link #setFirstPageNo(int)}设置的值。 + * 例如当{@link #setFirstPageNo(int)}设置为1时,1表示首页;设置为0时,0表示首页,依次类推。
+ * 当设置页码小于{@link #getFirstPageNo()}值时,始终为{@link #getFirstPageNo()} * * @param pageNo 当前页码 * @return this @@ -251,7 +254,8 @@ public class PageInfo { } /** - * 下一页,即当前页码+1 + * 下一页,即当前页码+1
+ * 当超过末页时,此方法指向的页码值始终为{@link #getPages()} + 1,即最后一页后的空白页。 * * @return this */ @@ -264,7 +268,7 @@ public class PageInfo { * * @return this */ - public PageInfo PreviousPage() { + public PageInfo previousPage() { return setPageNo(this.pageNo - 1); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/page/package-info.java b/hutool-core/src/main/java/cn/hutool/core/lang/page/package-info.java new file mode 100644 index 000000000..66d7723fe --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/lang/page/package-info.java @@ -0,0 +1,10 @@ +/** + * 提供分页信息封装,主要包括: + *

    + *
  • {@link cn.hutool.core.lang.page.PageInfo}: 提供分页信息。
  • + *
  • {@link cn.hutool.core.lang.page.NavigatePageInfo}: 提供分页导航信息。
  • + *
+ * + * @author looly + */ +package cn.hutool.core.lang.page; diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java index e4e40d0ac..d54714b4b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java @@ -2,7 +2,7 @@ package cn.hutool.core.collection; import cn.hutool.core.date.StopWatch; import cn.hutool.core.lang.Console; -import cn.hutool.core.math.PageInfo; +import cn.hutool.core.lang.page.PageInfo; import cn.hutool.core.util.RandomUtil; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/page/NavigatePageInfoTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/page/NavigatePageInfoTest.java new file mode 100644 index 000000000..775d6daf0 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/lang/page/NavigatePageInfoTest.java @@ -0,0 +1,37 @@ +package cn.hutool.core.lang.page; + +import org.junit.Assert; +import org.junit.Test; + +public class NavigatePageInfoTest { + + @Test + public void naviTest1(){ + // 首页 + final NavigatePageInfo navigatePageInfo = new NavigatePageInfo(10, 2, 6); + Assert.assertEquals("[1] 2 3 4 5 >>", navigatePageInfo.toString()); + + // 中间页 + navigatePageInfo.nextPage(); + Assert.assertEquals("<< 1 [2] 3 4 5 >>", navigatePageInfo.toString()); + + // 尾页 + navigatePageInfo.setPageNo(5); + Assert.assertEquals("<< 1 2 3 4 [5]", navigatePageInfo.toString()); + } + + @Test + public void naviTest2(){ + // 首页 + final NavigatePageInfo navigatePageInfo = new NavigatePageInfo(10, 2, 4); + Assert.assertEquals("[1] 2 3 4 >>", navigatePageInfo.toString()); + + // 中间页 + navigatePageInfo.nextPage(); + Assert.assertEquals("<< 1 [2] 3 4 >>", navigatePageInfo.toString()); + + // 尾页 + navigatePageInfo.setPageNo(5); + Assert.assertEquals("<< 2 3 4 [5]", navigatePageInfo.toString()); + } +} diff --git a/hutool-core/src/test/java/cn/hutool/core/math/PageInfoTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/page/PageInfoTest.java similarity index 96% rename from hutool-core/src/test/java/cn/hutool/core/math/PageInfoTest.java rename to hutool-core/src/test/java/cn/hutool/core/lang/page/PageInfoTest.java index a5778a98f..eca662cca 100644 --- a/hutool-core/src/test/java/cn/hutool/core/math/PageInfoTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/page/PageInfoTest.java @@ -1,4 +1,4 @@ -package cn.hutool.core.math; +package cn.hutool.core.lang.page; import org.junit.Assert; import org.junit.Test; diff --git a/hutool-core/src/test/java/cn/hutool/core/tree/IssueI6NR2ZTest.java b/hutool-core/src/test/java/cn/hutool/core/tree/IssueI6NR2ZTest.java new file mode 100644 index 000000000..3acbcea4b --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/tree/IssueI6NR2ZTest.java @@ -0,0 +1,48 @@ +package cn.hutool.core.tree; + +import cn.hutool.core.lang.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +public class IssueI6NR2ZTest { + @Test + public void getNodeTest() { + final List> list = new ArrayList<>(); + + final TreeNode treeNode1 = new TreeNode<>(); + treeNode1.setId(1); + treeNode1.setParentId(0); + list.add(treeNode1); + + final TreeNode treeNode2 = new TreeNode<>(); + treeNode2.setId(2); + treeNode2.setParentId(1); + list.add(treeNode2); + + final TreeNode treeNode3 = new TreeNode<>(); + treeNode3.setId(3); + treeNode3.setParentId(1); + list.add(treeNode3); + + final TreeNode treeNode4 = new TreeNode<>(); + treeNode4.setId(21); + treeNode4.setParentId(2); + list.add(treeNode4); + + final TreeNode treeNode5 = new TreeNode<>(); + treeNode5.setId(31); + treeNode5.setParentId(3); + list.add(treeNode5); + + final TreeNode treeNode6 = new TreeNode<>(); + treeNode6.setId(211); + treeNode6.setParentId(21); + list.add(treeNode6); + + final List> build = TreeUtil.build(list); + final MapTree node = TreeUtil.getNode(build.get(0), 31); + Assert.notNull(node); + } +} diff --git a/hutool-db/src/main/java/cn/hutool/db/Page.java b/hutool-db/src/main/java/cn/hutool/db/Page.java index 176d7f42d..b5c7b877c 100644 --- a/hutool-db/src/main/java/cn/hutool/db/Page.java +++ b/hutool-db/src/main/java/cn/hutool/db/Page.java @@ -1,7 +1,7 @@ package cn.hutool.db; import cn.hutool.core.lang.Segment; -import cn.hutool.core.math.PageInfo; +import cn.hutool.core.lang.page.PageInfo; import cn.hutool.core.util.ArrayUtil; import cn.hutool.db.sql.Order; diff --git a/hutool-db/src/main/java/cn/hutool/db/PageResult.java b/hutool-db/src/main/java/cn/hutool/db/PageResult.java index 70118f2a6..c495f650e 100644 --- a/hutool-db/src/main/java/cn/hutool/db/PageResult.java +++ b/hutool-db/src/main/java/cn/hutool/db/PageResult.java @@ -1,6 +1,6 @@ package cn.hutool.db; -import cn.hutool.core.math.PageInfo; +import cn.hutool.core.lang.page.PageInfo; import java.util.ArrayList; From ed512e3377384c5187c9de781a3dcf6427c51a0c Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 17 Mar 2023 00:35:27 +0800 Subject: [PATCH 15/18] fix code --- .../core/lang/page/NavigatePageInfo.java | 87 ++++++++++++++----- .../cn/hutool/core/lang/page/PageInfo.java | 18 ++-- .../hutool/core/lang/page/PageInfoTest.java | 4 +- .../main/java/cn/hutool/db/PageResult.java | 2 +- 4 files changed, 77 insertions(+), 34 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/page/NavigatePageInfo.java b/hutool-core/src/main/java/cn/hutool/core/lang/page/NavigatePageInfo.java index d605be398..6edbd22a1 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/page/NavigatePageInfo.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/page/NavigatePageInfo.java @@ -1,13 +1,31 @@ package cn.hutool.core.lang.page; +/** + * 导航分页信息类
+ * 根据提供的总页数、每页记录数、导航页码数等信息,生成导航数组。 + *
+ *     [1] 2 3 4 5 >>
+ *     << 1 [2] 3 4 5 >>
+ *     << 1 2 3 4 [5]
+ * 
+ * + * @author 莫取网名 + */ public class NavigatePageInfo extends PageInfo { - private final int navigatePages; //导航页码数 + private final int navigatePageCount; //导航页码数 private int[] navigatePageNumbers; //所有导航页号 - public NavigatePageInfo(final int total, final int pageSize, int navigatePages) { + /** + * 构造 + * + * @param total 总记录数 + * @param pageSize 每页显示记录数 + * @param navigatePageCount 导航页码数 + */ + public NavigatePageInfo(final int total, final int pageSize, final int navigatePageCount) { super(total, pageSize); - this.navigatePages = navigatePages; + this.navigatePageCount = navigatePageCount; //基本参数设定之后进行导航页面的计算 calcNavigatePageNumbers(); @@ -22,26 +40,50 @@ public class NavigatePageInfo extends PageInfo { return navigatePageNumbers; } + @Override + public NavigatePageInfo setFirstPageNo(final int firstPageNo) { + super.setFirstPageNo(firstPageNo); + return this; + } + + @Override + public NavigatePageInfo setPageNo(final int pageNo) { + super.setPageNo(pageNo); + // 重新计算导航 + calcNavigatePageNumbers(); + return this; + } + + @Override public String toString() { final StringBuilder str = new StringBuilder(); - if(false == isFirstPage()){ + if (false == isFirstPage()) { str.append("<< "); } if (navigatePageNumbers.length > 0) { - str.append(wrap(navigatePageNumbers[0])); + str.append(wrapForDisplay(navigatePageNumbers[0])); } for (int i = 1; i < navigatePageNumbers.length; i++) { - str.append(" ").append(wrap(navigatePageNumbers[i])); + str.append(" ").append(wrapForDisplay(navigatePageNumbers[i])); } - if(false == isLastPage()){ + if (false == isLastPage()) { str.append(" >>"); } return str.toString(); } - private String wrap(final int pageNumber){ - if(this.pageNo == pageNumber){ + // region ----- private methods + + /** + * 用于显示的包装
+ * 当前页显示'[pageNumber]',否则直接显示 + * + * @param pageNumber 页码 + * @return 包装的页码 + */ + private String wrapForDisplay(final int pageNumber) { + if (this.pageNo == pageNumber) { return "[" + pageNumber + "]"; } return String.valueOf(pageNumber); @@ -51,35 +93,36 @@ public class NavigatePageInfo extends PageInfo { * 计算导航页 */ private void calcNavigatePageNumbers() { - //当总页数小于或等于导航页码数时 - if (pages <= navigatePages) { - navigatePageNumbers = new int[pages]; - for (int i = 0; i < pages; i++) { + //当总页数小于或等于导航页码数时,全部显示 + if (pageCount <= navigatePageCount) { + navigatePageNumbers = new int[pageCount]; + for (int i = 0; i < pageCount; i++) { navigatePageNumbers[i] = i + 1; } - } else { //当总页数大于导航页码数时 - navigatePageNumbers = new int[navigatePages]; - int startNum = pageNo - navigatePages / 2; - int endNum = pageNo + navigatePages / 2; + } else { //当总页数大于导航页码数时,部分显示 + navigatePageNumbers = new int[navigatePageCount]; + int startNum = pageNo - navigatePageCount / 2; + int endNum = pageNo + navigatePageCount / 2; if (startNum < 1) { startNum = 1; //(最前navPageCount页 - for (int i = 0; i < navigatePages; i++) { + for (int i = 0; i < navigatePageCount; i++) { navigatePageNumbers[i] = startNum++; } - } else if (endNum > pages) { - endNum = pages; + } else if (endNum > pageCount) { + endNum = pageCount; //最后navPageCount页 - for (int i = navigatePages - 1; i >= 0; i--) { + for (int i = navigatePageCount - 1; i >= 0; i--) { navigatePageNumbers[i] = endNum--; } } else { //所有中间页 - for (int i = 0; i < navigatePages; i++) { + for (int i = 0; i < navigatePageCount; i++) { navigatePageNumbers[i] = startNum++; } } } } + // endregion } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/page/PageInfo.java b/hutool-core/src/main/java/cn/hutool/core/lang/page/PageInfo.java index 461d1f87e..86c06bd17 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/page/PageInfo.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/page/PageInfo.java @@ -36,7 +36,7 @@ public class PageInfo { /** * 总页数 */ - int pages; + int pageCount; /** * 首页标识 */ @@ -74,7 +74,7 @@ public class PageInfo { this.pageSize = pageSize; // 因为总条数除以页大小的最大余数是页大小数-1, // 因此加一个最大余数,保证舍弃的余数与最大余数凑1.x,就是一旦有余数则+1页 - this.pages = (total + pageSize - 1) / pageSize; + this.pageCount = (total + pageSize - 1) / pageSize; } /** @@ -100,8 +100,8 @@ public class PageInfo { * * @return {int} */ - public int getPages() { - return pages; + public int getPageCount() { + return pageCount; } /** @@ -129,7 +129,7 @@ public class PageInfo { * @return 是否尾页 */ public boolean isLastPage() { - return getPageIndexBase1() == this.pages; + return getPageIndexBase1() == this.pageCount; } /** @@ -147,7 +147,7 @@ public class PageInfo { * @return 是否有下一页 */ public boolean hasNextPage() { - return getBeginIndex() < this.pages; + return getBeginIndex() < this.pageCount; } /** @@ -155,7 +155,7 @@ public class PageInfo { * @return 是否可用 */ public boolean isValidPage(){ - return this.getPageIndexBase1() <= this.pages; + return this.getPageIndexBase1() <= this.pageCount; } /** @@ -255,7 +255,7 @@ public class PageInfo { /** * 下一页,即当前页码+1
- * 当超过末页时,此方法指向的页码值始终为{@link #getPages()} + 1,即最后一页后的空白页。 + * 当超过末页时,此方法指向的页码值始终为{@link #getPageCount()} + 1,即最后一页后的空白页。 * * @return this */ @@ -275,7 +275,7 @@ public class PageInfo { public String toString() { return "{" + "total=" + total + - ",pages=" + pages + + ",pages=" + pageCount + ",pageNumber=" + pageNo + ",limit=" + pageSize + ",isFirstPage=" + isFirstPage() + diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/page/PageInfoTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/page/PageInfoTest.java index eca662cca..de4002884 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/page/PageInfoTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/page/PageInfoTest.java @@ -7,10 +7,10 @@ public class PageInfoTest { @Test public void pagesTest() { PageInfo pageInfo = new PageInfo(20, 3); - Assert.assertEquals(7, pageInfo.getPages()); + Assert.assertEquals(7, pageInfo.getPageCount()); pageInfo = new PageInfo(20, 4); - Assert.assertEquals(5, pageInfo.getPages()); + Assert.assertEquals(5, pageInfo.getPageCount()); } @Test diff --git a/hutool-db/src/main/java/cn/hutool/db/PageResult.java b/hutool-db/src/main/java/cn/hutool/db/PageResult.java index c495f650e..e47cc7a92 100644 --- a/hutool-db/src/main/java/cn/hutool/db/PageResult.java +++ b/hutool-db/src/main/java/cn/hutool/db/PageResult.java @@ -65,7 +65,7 @@ public class PageResult extends ArrayList { this(page, pageSize); this.total = total; - this.totalPage = PageInfo.of(total, pageSize).getPages(); + this.totalPage = PageInfo.of(total, pageSize).getPageCount(); } //---------------------------------------------------------- Constructor end From bcb83e87de0745d9028e42f62d0ac8a5213346c4 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 17 Mar 2023 00:55:08 +0800 Subject: [PATCH 16/18] fix code --- .../hutool/core/convert/impl/StringConverter.java | 2 +- hutool-db/src/test/java/cn/hutool/db/DbTest.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java index 536a5fc7a..5c8c36a41 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java @@ -35,7 +35,7 @@ public class StringConverter extends AbstractConverter { * @param stringFunction 序列化函数 * @return this */ - public StringConverter putStringer(Class clazz, Function stringFunction){ + public StringConverter putStringer(final Class clazz, final Function stringFunction){ if(null == stringer){ stringer = new HashMap<>(); } diff --git a/hutool-db/src/test/java/cn/hutool/db/DbTest.java b/hutool-db/src/test/java/cn/hutool/db/DbTest.java index 49d8da933..5e3019570 100644 --- a/hutool-db/src/test/java/cn/hutool/db/DbTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/DbTest.java @@ -55,6 +55,19 @@ public class DbTest { Assert.assertEquals(1, page1.size()); } + @Test + public void pageBySqlWithInTest() { + // in和其他条件混用 + final String sql = "select * from user where age > :age and name in (:names) order by name"; + // 测试数据库中一共4条数据,第0页有3条,第1页有1条 + final List page0 = Db.of().page( + sql, Page.of(0, 3), + Entity.of().set("age", 12) + .set("names", new String[]{"张三", "王五"}) + ); + Assert.assertEquals(1, page0.size()); + } + @Test public void pageWithParamsTest() { final String sql = "select * from user where name = ?"; From 562308127865a0ac07fd8776548e89dc1b891c16 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 17 Mar 2023 01:31:59 +0800 Subject: [PATCH 17/18] fix code --- .../main/java/cn/hutool/db/AbstractDb.java | 21 ++++++++++++++++--- .../cn/hutool/http/client/ClientConfig.java | 4 +++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java b/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java index 359bc153e..0143b4dc2 100755 --- a/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java +++ b/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java @@ -51,6 +51,7 @@ public abstract class AbstractDb> extends DefaultConnect } // ------------------------------------------------------- Constructor end + // region ----- query /** * 查询 * @@ -189,7 +190,9 @@ public abstract class AbstractDb> extends DefaultConnect this.closeConnection(conn); } } + // endregion + // region ----- execute /** * 执行非查询语句
* 语句包括 插入、更新、删除 @@ -282,9 +285,11 @@ public abstract class AbstractDb> extends DefaultConnect this.closeConnection(conn); } } + // endregion // ---------------------------------------------------------------------------- CRUD start + // region ----- insert /** * 插入数据 * @@ -395,7 +400,9 @@ public abstract class AbstractDb> extends DefaultConnect this.closeConnection(conn); } } + // endregion + // region ----- del /** * 删除数据 * @@ -425,7 +432,9 @@ public abstract class AbstractDb> extends DefaultConnect this.closeConnection(conn); } } + // endregion + // region ----- update /** * 更新数据
* 更新条件为多个key value对表示,默认key = value,如果使用其它条件可以使用:where.put("key", " > 1"),value也可以传Condition对象,key被忽略 @@ -444,8 +453,9 @@ public abstract class AbstractDb> extends DefaultConnect this.closeConnection(conn); } } + // endregion - // ------------------------------------------------------------- Get start + // region ----- get /** * 根据某个字段(最好是唯一字段)查询单个记录
@@ -473,8 +483,9 @@ public abstract class AbstractDb> extends DefaultConnect return find(where.getFieldNames(), where, new EntityHandler(this.caseInsensitive)); } - // ------------------------------------------------------------- Get end + // endregion + // region ----- find /** * 查询
* 查询条件为多个key value对表示,默认key = value,如果使用其它条件可以使用:where.put("key", " > 1"),value也可以传Condition对象,key被忽略 @@ -652,7 +663,9 @@ public abstract class AbstractDb> extends DefaultConnect public List findLike(final String tableName, final String field, final String value, final LikeType likeType) throws DbRuntimeException { return findAll(Entity.of(tableName).set(field, SqlUtil.buildLikeValue(value, likeType, true))); } + // endregion + // region ----- count /** * 结果的条目数 * @@ -705,7 +718,9 @@ public abstract class AbstractDb> extends DefaultConnect this.closeConnection(conn); } } + // endregion + // region ----- page /** * 分页查询,结果为Entity列表,不计算总数
* 查询条件为多个key value对表示,默认key = value,如果使用其它条件可以使用:where.put("key", " > 1"),value也可以传Condition对象,key被忽略 @@ -867,7 +882,7 @@ public abstract class AbstractDb> extends DefaultConnect public PageResult page(final Entity where, final Page page) throws DbRuntimeException { return this.page(where.getFieldNames(), where, page); } - // ---------------------------------------------------------------------------- CRUD end + // endregion // ---------------------------------------------------------------------------- Getters and Setters start diff --git a/hutool-http/src/main/java/cn/hutool/http/client/ClientConfig.java b/hutool-http/src/main/java/cn/hutool/http/client/ClientConfig.java index 2e1fcde6c..b4b412809 100755 --- a/hutool-http/src/main/java/cn/hutool/http/client/ClientConfig.java +++ b/hutool-http/src/main/java/cn/hutool/http/client/ClientConfig.java @@ -30,7 +30,9 @@ public class ClientConfig { * 默认读取超时 */ private int readTimeout; - + /** + * SSL相关配置 + */ private SSLInfo sslInfo; /** * 是否禁用缓存 From a8a8c09ae835d7db41c48f8a906d86428da421d9 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 17 Mar 2023 02:04:13 +0800 Subject: [PATCH 18/18] fix code --- hutool-db/README.md | 40 +++++++++++++++++++ .../main/java/cn/hutool/db/AbstractDb.java | 8 +--- .../cn/hutool/db/DefaultConnectionHolder.java | 7 +++- .../main/java/cn/hutool/db/StatementUtil.java | 2 +- .../java/cn/hutool/db/sql/SqlBuilder.java | 9 +++++ 5 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 hutool-db/README.md diff --git a/hutool-db/README.md b/hutool-db/README.md new file mode 100644 index 000000000..c8f6086da --- /dev/null +++ b/hutool-db/README.md @@ -0,0 +1,40 @@ +

+ +

+

+ 🍬A set of tools that keep Java sweet. +

+

+ 👉 https://hutool.cn/ 👈 +

+ +## 📚Hutool-db 模块介绍 + +`Hutool-db`是一个在JDBC基础上封装的数据库操作工具类。通过包装,使用ActiveRecord思想操作数据库。 +在Hutool-db中,使用Entity(本质上是个Map)代替Bean来使数据库操作更加灵活,同时提供Bean和Entity的转换提供传统ORM的兼容支持。 + +------------------------------------------------------------------------------- + +## 🛠️包含内容 + +### 数据库方言(dialect) +通过抽象CRUD方法,针对不同数据库,封装对应的查询、分页等SQL转换功能,入口为`DialectFactory`。 + +### 数据源(ds) +提供常用数据库连接池的门面支持,支持顺序为: + +- Hikari > Druid > Tomcat > BeeCP > Dbcp > C3p0 > Hutool Pooled + +### SQL相关工具(sql) +提供SQL相关功能,包括SQL变量替换(NamedSql),通过对象完成SQL构建(SqlBuilder)等。 + +`SqlSqlExecutor`提供SQL执行的静态方法。 + +### 数据库元信息(meta) +通过`MetaUtil`提供数据库表、字段等信息的读取操作。 + +### 增删改查(Db、Session) +提供增删改查的汇总方法类。 + +### 结果转换(handler) +通过封装`RsHandler`,提供将ResultSet转换为需要的对象的功能。 \ No newline at end of file diff --git a/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java b/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java index 0143b4dc2..3c5b376e7 100755 --- a/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java +++ b/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java @@ -498,13 +498,7 @@ public abstract class AbstractDb> extends DefaultConnect * @throws DbRuntimeException SQL执行异常 */ public T find(final Collection fields, final Entity where, final RsHandler rsh) throws DbRuntimeException { - Connection conn = null; - try { - conn = this.getConnection(); - return runner.find(conn, Query.of(where).setFields(fields), rsh); - } finally { - this.closeConnection(conn); - } + return find(Query.of(where).setFields(fields), rsh); } /** diff --git a/hutool-db/src/main/java/cn/hutool/db/DefaultConnectionHolder.java b/hutool-db/src/main/java/cn/hutool/db/DefaultConnectionHolder.java index 8321636b5..103889556 100644 --- a/hutool-db/src/main/java/cn/hutool/db/DefaultConnectionHolder.java +++ b/hutool-db/src/main/java/cn/hutool/db/DefaultConnectionHolder.java @@ -13,7 +13,12 @@ public class DefaultConnectionHolder implements ConnectionHolder { protected final DataSource ds; - public DefaultConnectionHolder(DataSource ds) { + /** + * 构造 + * + * @param ds {@link DataSource} + */ + public DefaultConnectionHolder(final DataSource ds) { this.ds = ds; } diff --git a/hutool-db/src/main/java/cn/hutool/db/StatementUtil.java b/hutool-db/src/main/java/cn/hutool/db/StatementUtil.java index ad8e63825..ed85d43a6 100644 --- a/hutool-db/src/main/java/cn/hutool/db/StatementUtil.java +++ b/hutool-db/src/main/java/cn/hutool/db/StatementUtil.java @@ -118,7 +118,7 @@ public class StatementUtil { * * @param conn 数据库连接 * @param sql SQL语句,使用"?"做为占位符 - * @param params "?"对应参数列表 + * @param params "?"对应参数列表或者Map表示命名参数 * @return {@link PreparedStatement} * @throws SQLException SQL异常 * @since 3.2.3 diff --git a/hutool-db/src/main/java/cn/hutool/db/sql/SqlBuilder.java b/hutool-db/src/main/java/cn/hutool/db/sql/SqlBuilder.java index 050e56410..bac080088 100644 --- a/hutool-db/src/main/java/cn/hutool/db/sql/SqlBuilder.java +++ b/hutool-db/src/main/java/cn/hutool/db/sql/SqlBuilder.java @@ -115,9 +115,18 @@ public class SqlBuilder implements Builder { private QuoteWrapper quoteWrapper; // --------------------------------------------------------------- Constructor start + + /** + * 构造 + */ public SqlBuilder() { } + /** + * 构造 + * + * @param quoteWrapper 包装器 + */ public SqlBuilder(final QuoteWrapper quoteWrapper) { this.quoteWrapper = quoteWrapper; }