diff --git a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
index 09211ad10..3a6119bd1 100755
--- a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
@@ -303,53 +303,6 @@ public class CharSequenceUtil extends StrChecker {
return c == str.charAt(0);
}
- /**
- * 是否以指定字符串开头
- * 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
- *
- * @param str 被监测字符串
- * @param prefix 开头字符串
- * @param ignoreCase 是否忽略大小写
- * @return 是否以指定字符串开头
- * @since 5.4.3
- */
- public static boolean startWith(final CharSequence str, final CharSequence prefix, final boolean ignoreCase) {
- return startWith(str, prefix, ignoreCase, false);
- }
-
- /**
- * 是否以指定字符串开头
- * 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
- *
- * CharSequenceUtil.startWith("123", "123", false, true); -- false
- * CharSequenceUtil.startWith("ABCDEF", "abc", true, true); -- true
- * CharSequenceUtil.startWith("abc", "abc", true, true); -- false
- *
- *
- * @param str 被监测字符串
- * @param prefix 开头字符串
- * @param ignoreCase 是否忽略大小写
- * @param ignoreEquals 是否忽略字符串相等的情况
- * @return 是否以指定字符串开头
- * @since 5.4.3
- */
- public static boolean startWith(final CharSequence str, final CharSequence prefix, final boolean ignoreCase, final boolean ignoreEquals) {
- if (null == str || null == prefix) {
- if (ignoreEquals) {
- return false;
- }
- return null == str && null == prefix;
- }
-
- final boolean isStartWith = str.toString()
- .regionMatches(ignoreCase, 0, prefix.toString(), 0, prefix.length());
-
- if (isStartWith) {
- return (false == ignoreEquals) || (false == equals(str, prefix, ignoreCase));
- }
- return false;
- }
-
/**
* 是否以指定字符串开头
*
@@ -426,6 +379,41 @@ public class CharSequenceUtil extends StrChecker {
}
return false;
}
+
+ /**
+ * 是否以指定字符串开头
+ * 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
+ *
+ * @param str 被监测字符串
+ * @param prefix 开头字符串
+ * @param ignoreCase 是否忽略大小写
+ * @return 是否以指定字符串开头
+ * @since 5.4.3
+ */
+ public static boolean startWith(final CharSequence str, final CharSequence prefix, final boolean ignoreCase) {
+ return startWith(str, prefix, ignoreCase, false);
+ }
+
+ /**
+ * 是否以指定字符串开头
+ * 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
+ *
+ * CharSequenceUtil.startWith("123", "123", false, true); -- false
+ * CharSequenceUtil.startWith("ABCDEF", "abc", true, true); -- true
+ * CharSequenceUtil.startWith("abc", "abc", true, true); -- false
+ *
+ *
+ * @param str 被监测字符串
+ * @param prefix 开头字符串
+ * @param ignoreCase 是否忽略大小写
+ * @param ignoreEquals 是否忽略字符串相等的情况
+ * @return 是否以指定字符串开头
+ * @since 5.4.3
+ */
+ public static boolean startWith(final CharSequence str, final CharSequence prefix, final boolean ignoreCase, final boolean ignoreEquals) {
+ return new StrRegionMatcher(ignoreCase, ignoreEquals, true)
+ .test(str, prefix);
+ }
// endregion
// region ----- endWith
@@ -444,48 +432,6 @@ public class CharSequenceUtil extends StrChecker {
return c == str.charAt(str.length() - 1);
}
- /**
- * 是否以指定字符串结尾
- * 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
- *
- * @param str 被监测字符串
- * @param suffix 结尾字符串
- * @param ignoreCase 是否忽略大小写
- * @return 是否以指定字符串结尾
- */
- public static boolean endWith(final CharSequence str, final CharSequence suffix, final boolean ignoreCase) {
- return endWith(str, suffix, ignoreCase, false);
- }
-
- /**
- * 是否以指定字符串结尾
- * 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
- *
- * @param str 被监测字符串
- * @param suffix 结尾字符串
- * @param ignoreCase 是否忽略大小写
- * @param ignoreEquals 是否忽略字符串相等的情况
- * @return 是否以指定字符串结尾
- * @since 5.8.0
- */
- public static boolean endWith(final CharSequence str, final CharSequence suffix, final boolean ignoreCase, final boolean ignoreEquals) {
- if (null == str || null == suffix) {
- if (ignoreEquals) {
- return false;
- }
- return null == str && null == suffix;
- }
-
- final int strOffset = str.length() - suffix.length();
- final boolean isEndWith = str.toString()
- .regionMatches(ignoreCase, strOffset, suffix.toString(), 0, suffix.length());
-
- if (isEndWith) {
- return (false == ignoreEquals) || (false == equals(str, suffix, ignoreCase));
- }
- return false;
- }
-
/**
* 是否以指定字符串结尾
*
@@ -551,6 +497,35 @@ public class CharSequenceUtil extends StrChecker {
}
return false;
}
+
+ /**
+ * 是否以指定字符串结尾
+ * 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
+ *
+ * @param str 被监测字符串
+ * @param suffix 结尾字符串
+ * @param ignoreCase 是否忽略大小写
+ * @return 是否以指定字符串结尾
+ */
+ public static boolean endWith(final CharSequence str, final CharSequence suffix, final boolean ignoreCase) {
+ return endWith(str, suffix, ignoreCase, false);
+ }
+
+ /**
+ * 是否以指定字符串结尾
+ * 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
+ *
+ * @param str 被监测字符串
+ * @param suffix 结尾字符串
+ * @param ignoreCase 是否忽略大小写
+ * @param ignoreEquals 是否忽略字符串相等的情况
+ * @return 是否以指定字符串结尾
+ * @since 5.8.0
+ */
+ public static boolean endWith(final CharSequence str, final CharSequence suffix, final boolean ignoreCase, final boolean ignoreEquals) {
+ return new StrRegionMatcher(ignoreCase, ignoreEquals, false)
+ .test(str, suffix);
+ }
// endregion
// region ----- contains
diff --git a/hutool-core/src/main/java/cn/hutool/core/text/StrRegionMatcher.java b/hutool-core/src/main/java/cn/hutool/core/text/StrRegionMatcher.java
new file mode 100644
index 000000000..ae9b3a4f9
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/text/StrRegionMatcher.java
@@ -0,0 +1,50 @@
+package cn.hutool.core.text;
+
+import java.io.Serializable;
+import java.util.function.BiPredicate;
+
+/**
+ * 字符串区域匹配器,用于匹配字串是头部匹配还是尾部匹配
+ *
+ * @author looly
+ * @since 6.0.0
+ */
+public class StrRegionMatcher implements BiPredicate, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private final boolean ignoreCase;
+ private final boolean ignoreEquals;
+ private final boolean isPrefix;
+
+ /**
+ * 构造
+ *
+ * @param ignoreCase 是否忽略大小写
+ * @param ignoreEquals 是否忽略字符串相等的情况
+ * @param isPrefix {@code true}表示检查开头匹配,{@code false}检查末尾匹配
+ */
+ public StrRegionMatcher(final boolean ignoreCase, final boolean ignoreEquals, final boolean isPrefix) {
+ this.ignoreCase = ignoreCase;
+ this.ignoreEquals = ignoreEquals;
+ this.isPrefix = isPrefix;
+ }
+
+ @Override
+ public boolean test(final CharSequence str, final CharSequence strToCheck) {
+ if (null == str || null == strToCheck) {
+ if (ignoreEquals) {
+ return false;
+ }
+ return null == str && null == strToCheck;
+ }
+
+ final int toffset = isPrefix ? 0 : str.length() - strToCheck.length();
+ final boolean matches = str.toString()
+ .regionMatches(ignoreCase, toffset, strToCheck.toString(), 0, strToCheck.length());
+
+ if (matches) {
+ return (false == ignoreEquals) || (false == StrUtil.equals(str, strToCheck, ignoreCase));
+ }
+ return false;
+ }
+}