This commit is contained in:
Looly 2023-03-25 11:36:23 +08:00
parent af1ac9c121
commit bece00d176
6 changed files with 156 additions and 81 deletions

View File

@ -45,6 +45,16 @@ public class CharSequenceUtil extends StrChecker {
*/
public static final String SPACE = " ";
/**
* {@link CharSequence} 转为字符串null安全
*
* @param cs {@link CharSequence}
* @return 字符串
*/
public static String str(final CharSequence cs) {
return null == cs ? null : cs.toString();
}
/**
* 当给定字符串为null时转换为Empty
*
@ -144,7 +154,7 @@ public class CharSequenceUtil extends StrChecker {
return handler.apply(str);
}
// ------------------------------------------------------------------------ Trim
// region ----- trim
/**
* 除去字符串头尾部的空白如果字符串是{@code null}依然返回{@code null}
@ -297,8 +307,9 @@ public class CharSequenceUtil extends StrChecker {
return result;
}
// endregion
// ------------------------------------------------------------------------ startWith
// region ----- startWith
/**
* 字符串是否以给定字符开始
@ -437,8 +448,9 @@ public class CharSequenceUtil extends StrChecker {
}
return false;
}
// endregion
// ------------------------------------------------------------------------ endWith
// region ----- endWith
/**
* 字符串是否以给定字符结尾
@ -561,8 +573,9 @@ public class CharSequenceUtil extends StrChecker {
}
return false;
}
// endregion
// ------------------------------------------------------------------------ contains
// region ----- contains
/**
* 指定字符是否在字符串中出现过
@ -761,8 +774,9 @@ public class CharSequenceUtil extends StrChecker {
}
return true;
}
// endregion
// ------------------------------------------------------------------------ indexOf
// region ----- indexOf
/**
* 指定范围内查找指定字符
@ -895,7 +909,7 @@ public class CharSequenceUtil extends StrChecker {
return INDEX_NOT_FOUND;
}
}
return new StrFinder(searchStr, ignoreCase).setText(text).start(from);
return StrFinder.of(searchStr, ignoreCase).setText(text).start(from);
}
/**
@ -943,7 +957,7 @@ public class CharSequenceUtil extends StrChecker {
return INDEX_NOT_FOUND;
}
}
return new StrFinder(searchStr, ignoreCase)
return StrFinder.of(searchStr, ignoreCase)
.setText(text).setNegative(true).start(from);
}
@ -994,8 +1008,9 @@ public class CharSequenceUtil extends StrChecker {
} while (found < ordinal);
return index;
}
// endregion
// ------------------------------------------------------------------------ remove
// region ----- remove
/**
* 移除字符串中所有给定字符串<br>
@ -1206,8 +1221,9 @@ public class CharSequenceUtil extends StrChecker {
public static String cleanBlank(final CharSequence str) {
return filter(str, c -> false == CharUtil.isBlankChar(c));
}
// endregion
// ------------------------------------------------------------------------ strip
// region ----- strip
/**
* 去除两边的指定字符串
@ -1290,8 +1306,9 @@ public class CharSequenceUtil extends StrChecker {
}
return str2.substring(from, to);
}
// endregion
// ------------------------------------------------------------------------ add
// region ----- add
/**
* 如果给定字符串不是以prefix开头的在开头补充 prefix
@ -1316,8 +1333,9 @@ public class CharSequenceUtil extends StrChecker {
public static String addSuffixIfNot(final CharSequence str, final CharSequence suffix) {
return appendIfMissing(str, suffix, suffix);
}
// endregion
// ------------------------------------------------------------------------ split
// region ----- split
/**
* 切分字符串为long数组
@ -1606,6 +1624,7 @@ public class CharSequenceUtil extends StrChecker {
}
return array;
}
// endregion
// region ----- sub
@ -2462,7 +2481,7 @@ public class CharSequenceUtil extends StrChecker {
}
// endregion
// ------------------------------------------------------------------------ wrap
// region ----- wrap
/**
* 包装指定字符串<br>
@ -2679,8 +2698,9 @@ public class CharSequenceUtil extends StrChecker {
return str.charAt(0) == prefixChar && str.charAt(str.length() - 1) == suffixChar;
}
// endregion
// ------------------------------------------------------------------------ pad
// region ----- pad
/**
* 补充字符串以满足指定长度如果提供的字符串大于指定长度截断之
@ -2802,8 +2822,9 @@ public class CharSequenceUtil extends StrChecker {
return str.toString().concat(repeatByLength(padStr, length - strLen));
}
// region
// ------------------------------------------------------------------------ center
// region ----- center
/**
* 居中字符串两边补充指定字符串如果指定长度小于字符串则返回原字符串
@ -2896,18 +2917,7 @@ public class CharSequenceUtil extends StrChecker {
str = padAfter(str, size, padStr);
return str.toString();
}
// ------------------------------------------------------------------------ str
/**
* {@link CharSequence} 转为字符串null安全
*
* @param cs {@link CharSequence}
* @return 字符串
*/
public static String str(final CharSequence cs) {
return null == cs ? null : cs.toString();
}
// endregion
// ------------------------------------------------------------------------ count
@ -2966,7 +2976,7 @@ public class CharSequenceUtil extends StrChecker {
return count;
}
// ------------------------------------------------------------------------ compare
// region ----- compare
/**
* 比较两个字符串用于排序
@ -3061,8 +3071,9 @@ public class CharSequenceUtil extends StrChecker {
public static int compareVersion(final CharSequence version1, final CharSequence version2) {
return VersionComparator.INSTANCE.compare(str(version1), str(version2));
}
// endregion
// ------------------------------------------------------------------------ append and prepend
// region ----- append and prepend
/**
* 如果给定字符串不是以给定的一个或多个字符串为结尾则在尾部添加结尾字符串<br>
@ -3167,8 +3178,9 @@ public class CharSequenceUtil extends StrChecker {
}
return prefix.toString().concat(str.toString());
}
// endregion
// ------------------------------------------------------------------------ replace
// region ----- replace
/**
* 替换字符串中第一个指定字符串
@ -3511,8 +3523,9 @@ public class CharSequenceUtil extends StrChecker {
}
return builder.toString();
}
// endregion
// ------------------------------------------------------------------------ length
// region ----- length
/**
* 获取字符串的长度如果为null返回0
@ -3571,8 +3584,9 @@ public class CharSequenceUtil extends StrChecker {
}
return sub(string, 0, length) + "...";
}
// endregion
// ------------------------------------------------------------------------ firstXXX
// region ----- firstXXX
/**
* 返回第一个非{@code null} 元素
@ -3614,8 +3628,9 @@ public class CharSequenceUtil extends StrChecker {
public static <T extends CharSequence> T firstNonBlank(final T... strs) {
return ArrayUtil.firstMatch(StrUtil::isNotBlank, strs);
}
// endregion
// ------------------------------------------------------------------------ lower and upper
// region ----- lower and upper
/**
* 原字符串首字母大写并在其首部添加指定字符串 例如str=name, preString=get = return getName
@ -3670,8 +3685,9 @@ public class CharSequenceUtil extends StrChecker {
}
return str.toString();
}
// endregion
// ------------------------------------------------------------------------ filter
// region ----- filter
/**
* 过滤字符串
@ -3697,8 +3713,9 @@ public class CharSequenceUtil extends StrChecker {
}
return sb.toString();
}
// endregion
// ------------------------------------------------------------------------ case
// region ----- case
/**
* 给定字符串中的字母是否全部为大写判断依据如下
@ -3713,16 +3730,7 @@ public class CharSequenceUtil extends StrChecker {
* @since 4.2.2
*/
public static boolean isUpperCase(final CharSequence str) {
if (null == str) {
return false;
}
final int len = str.length();
for (int i = 0; i < len; i++) {
if (Character.isLowerCase(str.charAt(i))) {
return false;
}
}
return true;
return NamingCase.isUpperCase(str);
}
/**
@ -3738,16 +3746,7 @@ public class CharSequenceUtil extends StrChecker {
* @since 4.2.2
*/
public static boolean isLowerCase(final CharSequence str) {
if (null == str) {
return false;
}
final int len = str.length();
for (int i = 0; i < len; i++) {
if (Character.isUpperCase(str.charAt(i))) {
return false;
}
}
return true;
return NamingCase.isLowerCase(str);
}
/**
@ -3764,23 +3763,7 @@ public class CharSequenceUtil extends StrChecker {
* @since 4.3.2
*/
public static String swapCase(final String str) {
if (isEmpty(str)) {
return str;
}
final char[] buffer = str.toCharArray();
for (int i = 0; i < buffer.length; i++) {
final char ch = buffer[i];
if (Character.isUpperCase(ch)) {
buffer[i] = Character.toLowerCase(ch);
} else if (Character.isTitleCase(ch)) {
buffer[i] = Character.toLowerCase(ch);
} else if (Character.isLowerCase(ch)) {
buffer[i] = Character.toUpperCase(ch);
}
}
return new String(buffer);
return NamingCase.swapCase(str);
}
/**
@ -3838,6 +3821,7 @@ public class CharSequenceUtil extends StrChecker {
public static String toCamelCase(final CharSequence name, final char symbol) {
return NamingCase.toCamelCase(name, symbol);
}
// endregion
// ------------------------------------------------------------------------ isSurround

View File

@ -188,4 +188,84 @@ public class NamingCase {
}
}
/**
* 给定字符串中的字母是否全部为大写判断依据如下
*
* <pre>
* 1. 大写字母包括A-Z
* 2. 其它非字母的Unicode符都算作大写
* </pre>
*
* @param str 被检查的字符串
* @return 是否全部为大写
* @since 4.2.2
*/
public static boolean isUpperCase(final CharSequence str) {
if (null == str) {
return false;
}
final int len = str.length();
for (int i = 0; i < len; i++) {
if (Character.isLowerCase(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 给定字符串中的字母是否全部为小写判断依据如下
*
* <pre>
* 1. 小写字母包括a-z
* 2. 其它非字母的Unicode符都算作小写
* </pre>
*
* @param str 被检查的字符串
* @return 是否全部为小写
* @since 4.2.2
*/
public static boolean isLowerCase(final CharSequence str) {
if (null == str) {
return false;
}
final int len = str.length();
for (int i = 0; i < len; i++) {
if (Character.isUpperCase(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 切换给定字符串中的大小写大写转小写小写转大写
*
* <pre>
* StrUtil.swapCase(null) = null
* StrUtil.swapCase("") = ""
* StrUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
* </pre>
*
* @param str 字符串
* @return 交换后的字符串
* @since 4.3.2
*/
public static String swapCase(final String str) {
if (StrUtil.isEmpty(str)) {
return str;
}
final char[] buffer = str.toCharArray();
for (int i = 0; i < buffer.length; i++) {
final char ch = buffer[i];
if (Character.isUpperCase(ch) || Character.isTitleCase(ch)) {
buffer[i] = Character.toLowerCase(ch);
} else if (Character.isLowerCase(ch)) {
buffer[i] = Character.toUpperCase(ch);
}
}
return new String(buffer);
}
}

View File

@ -12,13 +12,24 @@ import cn.hutool.core.text.CharSequenceUtil;
public class StrFinder extends TextFinder {
private static final long serialVersionUID = 1L;
/**
* 创建查找器构造后须调用{@link #setText(CharSequence)} 设置被查找的文本
*
* @param strToFind 查找的字符串
* @param caseInsensitive 是否忽略大小写
* @return {@code StrFinder}
*/
public static StrFinder of(final CharSequence strToFind, final boolean caseInsensitive) {
return new StrFinder(strToFind, caseInsensitive);
}
private final CharSequence strToFind;
private final boolean caseInsensitive;
/**
* 构造
*
* @param strToFind 被查找的字符串
* @param strToFind 查找的字符串
* @param caseInsensitive 是否忽略大小写
*/
public StrFinder(final CharSequence strToFind, final boolean caseInsensitive) {

View File

@ -15,18 +15,18 @@ public class LookupReplacer extends StrReplacer {
private static final long serialVersionUID = 1L;
private final Map<String, String> lookupMap;
private final Set<Character> prefixSet;
private final Set<Character> keyPrefixSkeyet;
private final int minLength;
private final int maxLength;
/**
* 构造
*
* @param lookup 被查找的键值对
* @param lookup 被查找的键值对每个String[]表示一个键值对
*/
public LookupReplacer(final String[]... lookup) {
this.lookupMap = new HashMap<>();
this.prefixSet = new HashSet<>();
this.lookupMap = new HashMap<>(lookup.length, 1);
this.keyPrefixSkeyet = new HashSet<>(lookup.length, 1);
int minLength = Integer.MAX_VALUE;
int maxLength = 0;
@ -35,7 +35,7 @@ public class LookupReplacer extends StrReplacer {
for (final String[] pair : lookup) {
key = pair[0];
lookupMap.put(key, pair[1]);
this.prefixSet.add(key.charAt(0));
this.keyPrefixSkeyet.add(key.charAt(0));
keySize = key.length();
if (keySize > maxLength) {
maxLength = keySize;
@ -50,7 +50,7 @@ public class LookupReplacer extends StrReplacer {
@Override
protected int replace(final CharSequence str, final int pos, final StringBuilder out) {
if (prefixSet.contains(str.charAt(pos))) {
if (keyPrefixSkeyet.contains(str.charAt(pos))) {
int max = this.maxLength;
if (pos + this.maxLength > str.length()) {
max = str.length() - pos;

View File

@ -321,7 +321,7 @@ public class SplitUtil {
} else if (0 == text.length()) {
return ignoreEmpty ? new ArrayList<>(0) : ListUtil.of(StrUtil.EMPTY);
}
final SplitIter splitIter = new SplitIter(text, new StrFinder(separator, ignoreCase), limit, ignoreEmpty);
final SplitIter splitIter = new SplitIter(text, StrFinder.of(separator, ignoreCase), limit, ignoreEmpty);
return splitIter.toList(isTrim);
}

View File

@ -74,7 +74,7 @@ public class SplitIterTest {
final String str1 = "a, ,,efedsfs, ddf,";
final SplitIter splitIter = new SplitIter(str1,
new StrFinder("e", false),
StrFinder.of("e", false),
Integer.MAX_VALUE,
true
);
@ -141,7 +141,7 @@ public class SplitIterTest {
public void splitByEmptyTest(){
final String text = "aa,bb,cc";
final SplitIter splitIter = new SplitIter(text,
new StrFinder("", false),
StrFinder.of("", false),
3,
false
);