From fc667e5c72e32b4fc681f7eff1eb45aca3c29c59 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 00:07:19 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E9=87=8D=E5=86=99=20RegexUtil=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plusone/commons/util/RegexUtil.java | 273 +++++++++++++++--- 1 file changed, 240 insertions(+), 33 deletions(-) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/RegexUtil.java b/src/main/java/xyz/zhouxy/plusone/commons/util/RegexUtil.java index 3db7630..abd7d82 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/RegexUtil.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/RegexUtil.java @@ -16,42 +16,132 @@ package xyz.zhouxy.plusone.commons.util; -import javax.annotation.Nullable; - -import xyz.zhouxy.plusone.commons.collection.SafeConcurrentHashMap; - -import java.util.Map; -import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Matcher; import java.util.regex.Pattern; -public class RegexUtil { +import javax.annotation.Nullable; - private static final Map PATTERN_CACHE = new SafeConcurrentHashMap<>(); +import com.google.common.base.Preconditions; - public static Pattern getPattern(final String regex) { - Objects.requireNonNull(regex); - return PATTERN_CACHE.computeIfAbsent(regex, Pattern::compile); +/** + * 封装一些常用的正则操作,并可以缓存 {@link Pattern} 实例以复用(最多缓存 256 个)。 + * + * @author ZhouXY + * + */ +public final class RegexUtil { + + private static final int DEFAULT_CACHE_INITIAL_CAPACITY = 64; + private static final int MAX_CACHE_SIZE = 256; + private static final ConcurrentHashMap PATTERN_CACHE = new ConcurrentHashMap<>( + DEFAULT_CACHE_INITIAL_CAPACITY); + + /** + * 获取 {@link Pattern} 实例。 + * + * @param pattern 正则表达式 + * @param cachePattern 是否缓存 {@link Pattern} 实例 + * @return {@link Pattern} 实例 + */ + public static Pattern getPattern(final String pattern, final boolean cachePattern) { + Preconditions.checkNotNull(pattern, "The pattern can not be null."); + Pattern result = PATTERN_CACHE.get(pattern); + if (result == null) { + result = Pattern.compile(pattern); + if (cachePattern && PATTERN_CACHE.size() < MAX_CACHE_SIZE) { + PATTERN_CACHE.putIfAbsent(pattern, result); + result = PATTERN_CACHE.get(pattern); + } + } + return result; } - public static boolean matches(@Nullable CharSequence input, String regex) { - return matches(input, getPattern(regex)); + /** + * 获取 {@link Pattern} 实例,不缓存。 + * + * @param pattern 正则表达式 + * @return {@link Pattern} 实例 + */ + public static Pattern getPattern(final String pattern) { + Preconditions.checkNotNull(pattern, "The pattern can not be null."); + Pattern result = PATTERN_CACHE.get(pattern); + if (result == null) { + result = Pattern.compile(pattern); + } + return result; } - public static boolean matches(@Nullable CharSequence input, Pattern pattern) { - Assert.notNull(pattern, "Pattern must not be null."); + /** + * 将各个正则表达式转为 {@link Pattern} 实例。 + * + * @param patterns 正则表达式 + * @param cachePattern 是否缓存 {@link Pattern} 实例 + * @return Pattern 实例数组 + */ + public static Pattern[] getPatterns(final String[] patterns, final boolean cachePattern) { + Preconditions.checkNotNull(patterns, "The patterns can not be null."); + final Pattern[] result = new Pattern[patterns.length]; + for (int i = 0; i < patterns.length; i++) { + result[i] = getPattern(patterns[i], cachePattern); + } + return result; + } + + /** + * 将各个正则表达式转为 {@link Pattern} 实例,不缓存。 + * + * @param patterns 正则表达式 + * @return {@link Pattern} 实例数组 + */ + public static Pattern[] getPatterns(final String[] patterns) { + Preconditions.checkNotNull(patterns, "The patterns can not be null."); + final Pattern[] result = new Pattern[patterns.length]; + for (int i = 0; i < patterns.length; i++) { + result[i] = getPattern(patterns[i]); + } + return result; + } + + /** + * 手动缓存 Pattern 实例。 + * + * @param pattern 要缓存的 {@link Pattern} 实例 + * @return 缓存的 Pattern 实例。如果缓存已满,则返回 {@code null}。 + */ + public static Pattern cachePattern(final Pattern pattern) { + if (PATTERN_CACHE.size() >= MAX_CACHE_SIZE) { + return null; + } + final String patternStr = pattern.pattern(); + PATTERN_CACHE.putIfAbsent(patternStr, pattern); + return PATTERN_CACHE.get(patternStr); + } + + /** + * 判断 {@code input} 是否匹配 {@code pattern}。 + * + * @param input 输入 + * @param pattern 正则 + * @return 判断结果 + */ + public static boolean matches(@Nullable final CharSequence input, final Pattern pattern) { + Preconditions.checkNotNull(pattern, "The pattern can not be null."); return input != null && pattern.matcher(input).matches(); } - public static boolean matchesOr(@Nullable CharSequence input, String... regexes) { - for (String regex : regexes) { - if (matches(input, regex)) { - return true; - } + /** + * 判断 {@code input} 是否匹配 {@code patterns} 中的一个。 + * + * @param input 输入 + * @param patterns 正则 + * @return 判断结果 + */ + public static boolean matchOne(@Nullable final CharSequence input, final Pattern[] patterns) { + Preconditions.checkNotNull(patterns, "The patterns can not be null."); + if (input == null) { + return false; } - return false; - } - - public static boolean matchesOr(@Nullable CharSequence input, Pattern... patterns) { for (Pattern pattern : patterns) { if (matches(input, pattern)) { return true; @@ -60,16 +150,18 @@ public class RegexUtil { return false; } - public static boolean matchesAnd(@Nullable CharSequence input, String... regexes) { - for (String regex : regexes) { - if (!matches(input, regex)) { - return false; - } + /** + * 判断 {@code input} 是否匹配全部正则。 + * + * @param input 输入 + * @param patterns 正则 + * @return 判断结果 + */ + public static boolean matchAll(@Nullable final CharSequence input, final Pattern[] patterns) { + Preconditions.checkNotNull(patterns, "The patterns can not be null."); + if (input == null) { + return false; } - return true; - } - - public static boolean matchesAnd(@Nullable CharSequence input, Pattern... patterns) { for (Pattern pattern : patterns) { if (!matches(input, pattern)) { return false; @@ -78,7 +170,122 @@ public class RegexUtil { return true; } + /** + * 判断 {@code input} 是否匹配 {@code pattern}。 + * + * @param input 输入 + * @param pattern 正则表达式 + * @param cachePattern 是否缓存 {@link Pattern} 实例 + * @return 判断结果 + */ + public static boolean matches(@Nullable final CharSequence input, final String pattern, + final boolean cachePattern) { + return matches(input, getPattern(pattern, cachePattern)); + } + + /** + * 判断 {@code input} 是否匹配 {@code pattern}。不缓存 {@link Pattern} 实例。 + * + * @param input 输入 + * @param pattern 正则表达式 + * @return 判断结果 + */ + public static boolean matches(@Nullable final CharSequence input, final String pattern) { + return matches(input, getPattern(pattern)); + } + + /** + * 判断 {@code input} 是否匹配 {@code patterns} 中的一个。 + * + * @param input 输入 + * @param patterns 正则表达式 + * @param cachePattern 是否缓存 {@link Pattern} 实例 + * @return 判断结果 + */ + public static boolean matchOne(@Nullable final CharSequence input, final String[] patterns, + final boolean cachePattern) { + final Pattern[] patternSet = getPatterns(patterns, cachePattern); + return matchOne(input, patternSet); + } + + /** + * 判断 {@code input} 是否匹配 {@code patterns} 中的一个。不缓存 {@link Pattern} 实例。 + * + * @param input 输入 + * @param patterns 正则表达式 + * @return 判断结果 + */ + public static boolean matchOne(@Nullable final CharSequence input, final String[] patterns) { + final Pattern[] patternSet = getPatterns(patterns); + return matchOne(input, patternSet); + } + + /** + * 判断 {@code input} 是否匹配全部正则。 + * + * @param input 输入 + * @param patterns 正则表达式 + * @param cachePattern 是否缓存 {@link Pattern} 实例 + * @return 判断结果 + */ + public static boolean matchAll(@Nullable final CharSequence input, final String[] patterns, + final boolean cachePattern) { + final Pattern[] patternSet = getPatterns(patterns, cachePattern); + return matchAll(input, patternSet); + } + + /** + * 判断 {@code input} 是否匹配全部正则。不缓存 {@link Pattern} 实例。 + * + * @param input 输入 + * @param patterns 正则表达式 + * @return 判断结果 + */ + public static boolean matchAll(@Nullable final CharSequence input, final String[] patterns) { + final Pattern[] patternSet = getPatterns(patterns); + return matchAll(input, patternSet); + } + + /** + * 生成匹配器。 + * + * @param input 输入 + * @param pattern 正则 + * @return 结果 + */ + public static Matcher getMatcher(final CharSequence input, final Pattern pattern) { + Preconditions.checkNotNull(input, "The input can not be null"); + Preconditions.checkNotNull(pattern, "The pattern can not be null"); + return pattern.matcher(input); + } + + /** + * 生成匹配器。 + * + * @param input 输入 + * @param pattern 正则表达式 + * @param cachePattern 是否缓存 {@link Pattern} 实例 + * @return 结果 + */ + public static Matcher getMatcher(final CharSequence input, final String pattern, boolean cachePattern) { + Preconditions.checkNotNull(input, "The input can not be null"); + return getPattern(pattern, cachePattern).matcher(input); + } + + /** + * 生成匹配器。不缓存 {@link Pattern} 实例。 + * + * @param input 输入 + * @param pattern 正则表达式 + * @return 结果 + */ + public static Matcher getMatcher(final CharSequence input, final String pattern) { + Preconditions.checkNotNull(input, "The input can not be null"); + return getPattern(pattern).matcher(input); + } + private RegexUtil() { + // 不允许实例化 throw new IllegalStateException("Utility class"); } } From 3439e6450d30c781a7320ee716fc704f6e43af31 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 00:24:22 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plusone/commons/util/RegexUtil.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/RegexUtil.java b/src/main/java/xyz/zhouxy/plusone/commons/util/RegexUtil.java index abd7d82..1c2f887 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/RegexUtil.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/RegexUtil.java @@ -16,7 +16,8 @@ package xyz.zhouxy.plusone.commons.util; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Arrays; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -24,6 +25,8 @@ import javax.annotation.Nullable; import com.google.common.base.Preconditions; +import xyz.zhouxy.plusone.commons.collection.SafeConcurrentHashMap; + /** * 封装一些常用的正则操作,并可以缓存 {@link Pattern} 实例以复用(最多缓存 256 个)。 * @@ -34,7 +37,7 @@ public final class RegexUtil { private static final int DEFAULT_CACHE_INITIAL_CAPACITY = 64; private static final int MAX_CACHE_SIZE = 256; - private static final ConcurrentHashMap PATTERN_CACHE = new ConcurrentHashMap<>( + private static final Map PATTERN_CACHE = new SafeConcurrentHashMap<>( DEFAULT_CACHE_INITIAL_CAPACITY); /** @@ -77,15 +80,13 @@ public final class RegexUtil { * * @param patterns 正则表达式 * @param cachePattern 是否缓存 {@link Pattern} 实例 - * @return Pattern 实例数组 + * @return {@link Pattern} 实例数组 */ public static Pattern[] getPatterns(final String[] patterns, final boolean cachePattern) { Preconditions.checkNotNull(patterns, "The patterns can not be null."); - final Pattern[] result = new Pattern[patterns.length]; - for (int i = 0; i < patterns.length; i++) { - result[i] = getPattern(patterns[i], cachePattern); - } - return result; + return Arrays.stream(patterns) + .map(pattern -> getPattern(pattern, cachePattern)) + .toArray(Pattern[]::new); } /** @@ -96,11 +97,9 @@ public final class RegexUtil { */ public static Pattern[] getPatterns(final String[] patterns) { Preconditions.checkNotNull(patterns, "The patterns can not be null."); - final Pattern[] result = new Pattern[patterns.length]; - for (int i = 0; i < patterns.length; i++) { - result[i] = getPattern(patterns[i]); - } - return result; + return Arrays.stream(patterns) + .map(RegexUtil::getPattern) + .toArray(Pattern[]::new); } /** From 1a0b91c5a76cf3589de0a5d10f8e5a5937eebbe5 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 00:47:39 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20serialVersionUID=20?= =?UTF-8?q?=E5=92=8C=20Javadoc=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plusone/commons/collection/SafeConcurrentHashMap.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/collection/SafeConcurrentHashMap.java b/src/main/java/xyz/zhouxy/plusone/commons/collection/SafeConcurrentHashMap.java index 7a23d12..e7719a2 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/collection/SafeConcurrentHashMap.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/collection/SafeConcurrentHashMap.java @@ -6,6 +6,8 @@ import java.util.function.Function; public class SafeConcurrentHashMap extends ConcurrentHashMap { + private static final long serialVersionUID = 4352954948768449595L; + /** * Creates a new, empty map with the default initial table size (16). */ @@ -75,6 +77,7 @@ public class SafeConcurrentHashMap extends ConcurrentHashMap { super(initialCapacity, loadFactor, concurrencyLevel); } + /** {@inheritDoc} */ @Override public V computeIfAbsent(K key, Function mappingFunction) { V v = get(key); From 9ec5d0a1c166f90aca0dd2cd9e922b2e41b33134 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 00:48:16 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E5=88=A0=E9=99=A4=20DbException=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/exception/DbException.java | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/main/java/xyz/zhouxy/plusone/commons/exception/DbException.java diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/DbException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/DbException.java deleted file mode 100644 index a0b0d02..0000000 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/DbException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xyz.zhouxy.plusone.commons.exception; - -import com.google.common.annotations.Beta; - -@Beta -public class DbException extends RuntimeException { - - public DbException(String message) { - super(message); - } - - public DbException(Throwable cause) { - super(cause); - } - - public DbException(String message, Throwable cause) { - super(message, cause); - } -} From f1dcf0beba66948763f32d653d87d4bd35288e37 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 01:09:04 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20NumberUtil=20?= =?UTF-8?q?=E4=B8=BA=20Numbers=E3=80=82=E6=B7=BB=E5=8A=A0=20between=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zhouxy/plusone/commons/util/Assert.java | 27 ++++++------------ .../util/{NumberUtil.java => Numbers.java} | 28 +++++++++++++++++-- 2 files changed, 35 insertions(+), 20 deletions(-) rename src/main/java/xyz/zhouxy/plusone/commons/util/{NumberUtil.java => Numbers.java} (72%) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/Assert.java b/src/main/java/xyz/zhouxy/plusone/commons/util/Assert.java index 8e06b29..fbfc17d 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/Assert.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/Assert.java @@ -78,54 +78,45 @@ public class Assert { } // between - int - private static boolean between(int value, int min, int max) { - return value >= min && value < max; - } public static void between(int value, int min, int max, Supplier e) throws E { - Assert.isTrue(between(value, min, max), e); + Assert.isTrue(Numbers.between(value, min, max), e); } public static void between(int value, int min, int max, String errorMessage) { - Assert.isTrue(between(value, min, max), errorMessage); + Assert.isTrue(Numbers.between(value, min, max), errorMessage); } public static void between(int value, int min, int max, String errorMessageTemplate, Object... args) { - Assert.isTrue(between(value, min, max), errorMessageTemplate, args); + Assert.isTrue(Numbers.between(value, min, max), errorMessageTemplate, args); } // between - long - private static boolean between(long value, long min, long max) { - return value >= min && value < max; - } public static void between(long value, long min, long max, Supplier e) throws E { - Assert.isTrue(between(value, min, max), e); + Assert.isTrue(Numbers.between(value, min, max), e); } public static void between(long value, long min, long max, String errorMessage) { - Assert.isTrue(between(value, min, max), errorMessage); + Assert.isTrue(Numbers.between(value, min, max), errorMessage); } public static void between(long value, long min, long max, String errorMessageTemplate, Object... args) { - Assert.isTrue(between(value, min, max), errorMessageTemplate, args); + Assert.isTrue(Numbers.between(value, min, max), errorMessageTemplate, args); } // between - double - private static boolean between(double value, double min, double max) { - return value >= min && value < max; - } public static void between(double value, double min, double max, Supplier e) throws E { - Assert.isTrue(between(value, min, max), e); + Assert.isTrue(Numbers.between(value, min, max), e); } public static void between(double value, double min, double max, String errorMessage) { - Assert.isTrue(between(value, min, max), errorMessage); + Assert.isTrue(Numbers.between(value, min, max), errorMessage); } public static void between(double value, double min, double max, String errorMessageTemplate, Object... args) { - Assert.isTrue(between(value, min, max), errorMessageTemplate, args); + Assert.isTrue(Numbers.between(value, min, max), errorMessageTemplate, args); } // notNull diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/NumberUtil.java b/src/main/java/xyz/zhouxy/plusone/commons/util/Numbers.java similarity index 72% rename from src/main/java/xyz/zhouxy/plusone/commons/util/NumberUtil.java rename to src/main/java/xyz/zhouxy/plusone/commons/util/Numbers.java index 7d8a9a4..365e0fd 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/NumberUtil.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/Numbers.java @@ -21,12 +21,14 @@ package xyz.zhouxy.plusone.commons.util; * * @author ZhouXY */ -public class NumberUtil { +public class Numbers { - private NumberUtil() { + private Numbers() { throw new IllegalStateException("Utility class"); } + // sum + public static int sum(final short... numbers) { int result = 0; for (short number : numbers) { @@ -66,4 +68,26 @@ public class NumberUtil { } return result; } + + // between + + public static boolean between(short value, short min, short max) { + return value >= min && value < max; + } + + public static boolean between(int value, int min, int max) { + return value >= min && value < max; + } + + public static boolean between(long value, long min, long max) { + return value >= min && value < max; + } + + public static boolean between(float value, float min, float max) { + return value >= min && value < max; + } + + public static boolean between(double value, double min, double max) { + return value >= min && value < max; + } } From bc80be1b892f104d07f7d7ee64213f560460f41b Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 01:09:20 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java index 120d26e..a57327c 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java @@ -39,11 +39,11 @@ import xyz.zhouxy.plusone.commons.util.OptionalUtil; public class DbRecord extends AbstractMapWrapper { public DbRecord() { - super(new HashMap<>(), k -> Assert.isNotBlank(k, "Key can not be null."), null); + super(new HashMap<>(), k -> Assert.isNotBlank(k, "Key must has text."), null); } public DbRecord(Map map) { - super(map, k -> Assert.isNotBlank(k, "Key can not be null."), null); + super(map, k -> Assert.isNotBlank(k, "Key must has text."), null); } public Optional getValueAsString(String key) { From d5ee8700d261aa501776dfc75632bad1da7ec97a Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 01:09:41 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xyz/zhouxy/plusone/commons/function/FunctionTests.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/xyz/zhouxy/plusone/commons/function/FunctionTests.java b/src/test/java/xyz/zhouxy/plusone/commons/function/FunctionTests.java index 00e5825..2f5eade 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/function/FunctionTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/function/FunctionTests.java @@ -1,11 +1,12 @@ package xyz.zhouxy.plusone.commons.function; +import static org.junit.jupiter.api.Assertions.assertFalse; + import java.util.Objects; import java.util.function.Predicate; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; -import xyz.zhouxy.plusone.commons.util.Assert; class FunctionTests { @@ -14,6 +15,6 @@ class FunctionTests { String str = ""; Predicate predicate = Predicates.of(Objects::nonNull) .and(StringUtils::isNotBlank); - Assert.isFalse(predicate.test(str), "校验应是不通过"); + assertFalse(predicate.test(str), "校验应是不通过"); } } From 3a46e2e60c6282d5d8d9a64e5d1dac5130252784 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 01:11:00 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=90=8D=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/jdbc/SimpleJdbcTemplate.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java index 51d274f..9200c7b 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java @@ -51,23 +51,23 @@ public class SimpleJdbcTemplate { public static Object[] buildParams(final Object... params) { return Arrays.stream(params) - .map(p -> { - if (p instanceof Optional) { - return OptionalUtil.orElseNull((Optional) p); + .map(param -> { + if (param instanceof Optional) { + return OptionalUtil.orElseNull((Optional) param); } - if (p instanceof OptionalInt) { - OptionalInt _p = ((OptionalInt) p); - return _p.isPresent() ? _p.getAsInt() : null; + if (param instanceof OptionalInt) { + OptionalInt p = ((OptionalInt) param); + return p.isPresent() ? p.getAsInt() : null; } - if (p instanceof OptionalLong) { - OptionalLong _p = ((OptionalLong) p); - return _p.isPresent() ? _p.getAsLong() : null; + if (param instanceof OptionalLong) { + OptionalLong p = ((OptionalLong) param); + return p.isPresent() ? p.getAsLong() : null; } - if (p instanceof OptionalDouble) { - OptionalDouble _p = ((OptionalDouble) p); - return _p.isPresent() ? _p.getAsDouble() : null; + if (param instanceof OptionalDouble) { + OptionalDouble p = ((OptionalDouble) param); + return p.isPresent() ? p.getAsDouble() : null; } - return p; + return param; }) .toArray(); } From 759ad5fcbef94975c8e3cb4c2a47be1781252dcb Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 01:32:48 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20OptionalInt=E3=80=81?= =?UTF-8?q?OptionalLong=E3=80=81OptionalDouble=20=E8=BD=AC=E5=8C=85?= =?UTF-8?q?=E8=A3=85=E7=B1=BB=E5=AE=9E=E4=BE=8B=E7=9A=84=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zhouxy/plusone/commons/util/OptionalUtil.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/OptionalUtil.java b/src/main/java/xyz/zhouxy/plusone/commons/util/OptionalUtil.java index 05808a7..4c852fa 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/OptionalUtil.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/OptionalUtil.java @@ -134,6 +134,21 @@ public class OptionalUtil { return optionalObj.orElse(null); } + @Beta + public static Integer toInteger(OptionalInt optionalObj) { + return optionalObj.isPresent() ? optionalObj.getAsInt() : null; + } + + @Beta + public static Long toLong(OptionalLong optionalObj) { + return optionalObj.isPresent() ? optionalObj.getAsLong() : null; + } + + @Beta + public static Double toDouble(OptionalDouble optionalObj) { + return optionalObj.isPresent() ? optionalObj.getAsDouble() : null; + } + private OptionalUtil() { throw new IllegalStateException("Utility class"); } From f4a12f16952027a4bd749e4002a3ae60c6b690de Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 01:57:30 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E5=99=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/jdbc/SimpleJdbcTemplate.java | 72 +++++++++++-------- .../commons/util/SimpleJdbcTemplateTests.java | 3 +- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java index 9200c7b..e0bab36 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java @@ -25,6 +25,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -35,11 +36,14 @@ import java.util.OptionalLong; import java.util.function.Function; import java.util.stream.Collectors; +import org.apache.commons.lang3.ArrayUtils; + import com.google.common.annotations.Beta; import com.google.common.collect.Lists; import xyz.zhouxy.plusone.commons.util.Assert; import xyz.zhouxy.plusone.commons.util.MoreArrays; +import xyz.zhouxy.plusone.commons.util.MoreCollections; import xyz.zhouxy.plusone.commons.util.OptionalUtil; @Beta @@ -49,33 +53,6 @@ public class SimpleJdbcTemplate { return new JdbcExecutor(conn); } - public static Object[] buildParams(final Object... params) { - return Arrays.stream(params) - .map(param -> { - if (param instanceof Optional) { - return OptionalUtil.orElseNull((Optional) param); - } - if (param instanceof OptionalInt) { - OptionalInt p = ((OptionalInt) param); - return p.isPresent() ? p.getAsInt() : null; - } - if (param instanceof OptionalLong) { - OptionalLong p = ((OptionalLong) param); - return p.isPresent() ? p.getAsLong() : null; - } - if (param instanceof OptionalDouble) { - OptionalDouble p = ((OptionalDouble) param); - return p.isPresent() ? p.getAsDouble() : null; - } - return param; - }) - .toArray(); - } - - public static List buildBatchParams(final Collection c, Function function) { - return c.stream().map(function).collect(Collectors.toList()); - } - public static String paramsToString(Object[] params) { return Arrays.toString(params); } @@ -213,7 +190,7 @@ public class SimpleJdbcTemplate { int executeCount = params.size() / batchSize; executeCount = (params.size() % batchSize == 0) ? executeCount : (executeCount + 1); List result = Lists.newArrayListWithCapacity(executeCount); - + try (PreparedStatement stmt = this.conn.prepareStatement(sql)) { int i = 0; for (Object[] ps : params) { @@ -252,4 +229,43 @@ public class SimpleJdbcTemplate { void execute() throws SQLException, T; } } + + public static class ParamBuilder { + + public static Object[] buildParams(final Object... params) { + if (ArrayUtils.isEmpty(params)) { + return ArrayUtils.EMPTY_OBJECT_ARRAY; + } + return Arrays.stream(params) + .map(param -> { + if (param instanceof Optional) { + return OptionalUtil.orElseNull((Optional) param); + } + if (param instanceof OptionalInt) { + return OptionalUtil.toInteger(((OptionalInt) param)); + } + if (param instanceof OptionalLong) { + return OptionalUtil.toLong(((OptionalLong) param)); + } + if (param instanceof OptionalDouble) { + return OptionalUtil.toDouble(((OptionalDouble) param)); + } + return param; + }) + .toArray(); + } + + public static List buildBatchParams(final Collection c, final Function function) { + Assert.notNull(c, "The collection can not be null."); + Assert.notNull(function, "The function can not be null."); + if (MoreCollections.isEmpty(c)) { + return Collections.emptyList(); + } + return c.stream().map(function).collect(Collectors.toList()); + } + + private ParamBuilder() { + throw new IllegalStateException("Utility class"); + } + } } diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/SimpleJdbcTemplateTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/SimpleJdbcTemplateTests.java index 02a87ab..247cd4b 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/util/SimpleJdbcTemplateTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/SimpleJdbcTemplateTests.java @@ -3,6 +3,7 @@ package xyz.zhouxy.plusone.commons.util; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static xyz.zhouxy.plusone.commons.jdbc.JdbcSql.IN; +import static xyz.zhouxy.plusone.commons.jdbc.SimpleJdbcTemplate.ParamBuilder.*; import java.sql.Connection; import java.sql.SQLException; @@ -49,7 +50,7 @@ class SimpleJdbcTemplateTests { @Test void testQuery() throws SQLException { try (Connection conn = this.dataSource.getConnection()) { - Object[] params = SimpleJdbcTemplate.buildParams("501533", "501554", "544599"); + Object[] params = buildParams("501533", "501554", "544599"); String sql = SQL.newJdbcSql() .SELECT("*") .FROM("test_table") From 13fc8e40b51ed1cd5a1fb10d717091597a9a37cc Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 27 Jun 2023 01:57:43 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/util/AbstractMapWrapper.java | 35 +++++++++++++------ .../plusone/commons/util/MapWrapper.java | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/AbstractMapWrapper.java b/src/main/java/xyz/zhouxy/plusone/commons/util/AbstractMapWrapper.java index dea4355..31623e5 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/AbstractMapWrapper.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/AbstractMapWrapper.java @@ -70,10 +70,25 @@ public abstract class AbstractMapWrapper get(K key) { - if (this.map.containsKey(key)) { - return Optional.ofNullable(this.map.get(key)); + if (!this.map.containsKey(key)) { + throw new IllegalArgumentException("Key does not exist"); } - throw new IllegalArgumentException("Key does not exist"); + return Optional.ofNullable(this.map.get(key)); + } + + /** + * 获取 {@code map} 中的值。如果 {@code key} 不存在,则抛出异常。 + * + * @param key 键 + * @return 值 + * @throws IllegalArgumentException key 不存在时抛出。 + */ + @Nullable + public V getOrNull(K key) { + if (!this.map.containsKey(key)) { + throw new IllegalArgumentException("Key does not exist"); + } + return this.map.get(key); } @SuppressWarnings("unchecked") @@ -149,7 +164,7 @@ public abstract class AbstractMapWrapper { + protected abstract static class Builder> { protected final Map map; protected Consumer keyChecker; protected Consumer valueChecker; @@ -158,17 +173,17 @@ public abstract class AbstractMapWrapper keyChecker(@Nullable Consumer keyChecker) { + public Builder keyChecker(@Nullable Consumer keyChecker) { this.keyChecker = keyChecker; return this; } - public Builder valueChecker(@Nullable Consumer valueChecker) { + public Builder valueChecker(@Nullable Consumer valueChecker) { this.valueChecker = valueChecker; return this; } - public Builder put(K key, V value) { + public Builder put(K key, V value) { if (this.keyChecker != null) { this.keyChecker.accept(key); } @@ -179,15 +194,15 @@ public abstract class AbstractMapWrapper putAll(Map m) { + public Builder putAll(Map m) { for (Entry entry : m.entrySet()) { put(entry.getKey(), entry.getValue()); } return this; } - public abstract MapWrapper build(); + public abstract T build(); - public abstract MapWrapper buildUnmodifiableMap(); + public abstract T buildUnmodifiableMap(); } } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/MapWrapper.java b/src/main/java/xyz/zhouxy/plusone/commons/util/MapWrapper.java index 62a936f..151b0a9 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/MapWrapper.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/MapWrapper.java @@ -61,7 +61,7 @@ public final class MapWrapper extends AbstractMapWrapper(new TreeMap<>(comparator)); } - public static final class Builder extends AbstractMapWrapper.Builder { + public static final class Builder extends AbstractMapWrapper.Builder> { private Builder(Map map) { super(map);