All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.litongjava.tio.utils.hutool.StrUtil Maven / Gradle / Ivy

There is a newer version: 3.7.3.v202400213-RELEASE
Show newest version
package com.litongjava.tio.utils.hutool;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Date;

public class StrUtil {

  public static final int INDEX_NOT_FOUND = -1;
  public static final String EMPTY = "";

  private static int cacheSize = 2048;
  private static String[] caches = new String[cacheSize];
  static {
    for (int i = 0; i < cacheSize; i++) {
      caches[i] = String.valueOf(i);
    }
  }

  /**
   * 用缓存将int转成str
   * 
   * @param data
   * @return
   */
  public static String int2Str(int data) {
    if (data < cacheSize) {
      return caches[data];
    } else {
      return String.valueOf(data);
    }
  }

  /**
   * 去除字符串两边空白符,传入null也返回null
   * 
   * @param value 值
   * @return 去除空白符的值
   */
  public static String trim(String value) {
    return (null == value) ? null : value.trim();
  }

  /**
   * 字符串是否为空,空的定义如下:
* 1、为null
* 2、为""
* * @param str 被检测的字符串 * @return 是否为空 */ public static boolean isEmpty(CharSequence str) { return str == null || str.length() == 0; } /** * 字符串是否为非空白 空白的定义如下:
* 1、不为null
* 2、不为不可见字符(如空格)
* 3、不为""
* * @param str 被检测的字符串 * @return 是否为非空 */ public static boolean isNotBlank(CharSequence str) { return false == isBlank(str); } public static boolean notBlank(CharSequence str) { return false == isBlank(str); } /** * 字符串是否为空白 空白的定义如下:
* 1、为null
* 2、为不可见字符(如空格)
* 3、""
* * @param str 被检测的字符串 * @return 是否为空 */ public static boolean isBlank(CharSequence str) { int length; if ((str == null) || ((length = str.length()) == 0)) { return true; } for (int i = 0; i < length; i++) { // 只要有一个非空字符即为非空字符串 if (false == isBlankChar(str.charAt(i))) { return false; } } return true; } /** * 数组或集合转String * * @param obj 集合或数组对象 * @return 数组字符串,与集合转字符串格式相同 */ public static String arrayToString(Object obj) { if (null == obj) { return null; } if (isArray(obj)) { try { return Arrays.deepToString((Object[]) obj); } catch (Exception e) { final String className = obj.getClass().getComponentType().getName(); switch (className) { case "long": return Arrays.toString((long[]) obj); case "int": return Arrays.toString((int[]) obj); case "short": return Arrays.toString((short[]) obj); case "char": return Arrays.toString((char[]) obj); case "byte": return Arrays.toString((byte[]) obj); case "boolean": return Arrays.toString((boolean[]) obj); case "float": return Arrays.toString((float[]) obj); case "double": return Arrays.toString((double[]) obj); default: throw new RuntimeException(e); } } } return obj.toString(); } /** * 是否以指定字符串开头,忽略大小写 * * @param str 被监测字符串 * @param prefix 开头字符串 * @return 是否以指定字符串开头 */ public static boolean startWithIgnoreCase(CharSequence str, CharSequence prefix) { return startWith(str, prefix, true); } /** * 是否以指定字符串开头
* 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false * * @param str 被监测字符串 * @param prefix 开头字符串 * @param isIgnoreCase 是否忽略大小写 * @return 是否以指定字符串开头 */ public static boolean startWith(CharSequence str, CharSequence prefix, boolean isIgnoreCase) { if (null == str || null == prefix) { if (null == str && null == prefix) { return true; } return false; } if (isIgnoreCase) { return str.toString().toLowerCase().startsWith(prefix.toString().toLowerCase()); } else { return str.toString().startsWith(prefix.toString()); } } /** * 比较两个字符串(大小写敏感)。 * *
   * equals(null, null)   = true
   * equals(null, "abc")  = false
   * equals("abc", null)  = false
   * equals("abc", "abc") = true
   * equals("abc", "ABC") = false
   * 
* * @param str1 要比较的字符串1 * @param str2 要比较的字符串2 * * @return 如果两个字符串相同,或者都是null,则返回true */ public static boolean equals(CharSequence str1, CharSequence str2) { return equals(str1, str2, false); } /** * 比较两个字符串(大小写不敏感)。 * *
   * equalsIgnoreCase(null, null)   = true
   * equalsIgnoreCase(null, "abc")  = false
   * equalsIgnoreCase("abc", null)  = false
   * equalsIgnoreCase("abc", "abc") = true
   * equalsIgnoreCase("abc", "ABC") = true
   * 
* * @param str1 要比较的字符串1 * @param str2 要比较的字符串2 * * @return 如果两个字符串相同,或者都是null,则返回true */ public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) { return equals(str1, str2, true); } /** * 比较两个字符串是否相等。 * * @param str1 要比较的字符串1 * @param str2 要比较的字符串2 * @param ignoreCase 是否忽略大小写 * @return 如果两个字符串相同,或者都是null,则返回true * @since 3.2.0 */ public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase) { if (null == str1) { // 只有两个都为null才判断相等 return str2 == null; } if (null == str2) { // 字符串2空,字符串1非空,直接false return false; } if (ignoreCase) { return str1.toString().equalsIgnoreCase(str2.toString()); } else { return str1.equals(str2); } } /** * 将已有字符串填充为规定长度,如果已有字符串超过这个长度则返回这个字符串
* 字符填充于字符串后 * * @param str 被填充的字符串 * @param filledChar 填充的字符 * @param len 填充长度 * @return 填充后的字符串 * @since 3.1.2 */ public static String fillAfter(String str, char filledChar, int len) { return fill(str, filledChar, len, false); } /** * 将已有字符串填充为规定长度,如果已有字符串超过这个长度则返回这个字符串 * * @param str 被填充的字符串 * @param filledChar 填充的字符 * @param len 填充长度 * @param isPre 是否填充在前 * @return 填充后的字符串 * @since 3.1.2 */ public static String fill(String str, char filledChar, int len, boolean isPre) { final int strLen = str.length(); if (strLen > len) { return str; } String filledStr = repeat(filledChar, len - strLen); return isPre ? filledStr.concat(str) : str.concat(filledStr); } /** * 重复某个字符 * * @param c 被重复的字符 * @param count 重复的数目,如果小于等于0则返回"" * @return 重复字符字符串 */ public static String repeat(char c, int count) { if (count <= 0) { return ""; } char[] result = new char[count]; for (int i = 0; i < count; i++) { result[i] = c; } return new String(result); } /** * 除去字符串头部的空白,如果字符串是null,则返回null。 * *

* 注意,和String.trim不同,此方法使用CharUtil.isBlankChar 来判定空白, * 因而可以除去英文字符集之外的其它空白,如中文空格。 * *

   * trimStart(null)         = null
   * trimStart("")           = ""
   * trimStart("abc")        = "abc"
   * trimStart("  abc")      = "abc"
   * trimStart("abc  ")      = "abc  "
   * trimStart(" abc ")      = "abc "
   * 
* * @param str 要处理的字符串 * * @return 除去空白的字符串,如果原字串为null或结果字符串为"",则返回 * null */ public static String trimStart(CharSequence str) { return trim(str, -1); } /** * 除去字符串尾部的空白,如果字符串是null,则返回null。 * *

* 注意,和String.trim不同,此方法使用CharUtil.isBlankChar 来判定空白, * 因而可以除去英文字符集之外的其它空白,如中文空格。 * *

   * trimEnd(null)       = null
   * trimEnd("")         = ""
   * trimEnd("abc")      = "abc"
   * trimEnd("  abc")    = "  abc"
   * trimEnd("abc  ")    = "abc"
   * trimEnd(" abc ")    = " abc"
   * 
* * @param str 要处理的字符串 * * @return 除去空白的字符串,如果原字串为null或结果字符串为"",则返回 * null */ public static String trimEnd(CharSequence str) { return trim(str, 1); } /** * 除去字符串头尾部的空白符,如果字符串是null,依然返回null。 * * @param str 要处理的字符串 * @param mode -1表示trimStart,0表示trim全部, * 1表示trimEnd * * @return 除去指定字符后的的字符串,如果原字串为null,则返回null */ private static String trim(CharSequence str, int mode) { if (str == null) { return null; } int length = str.length(); int start = 0; int end = length; // 扫描字符串头部 if (mode <= 0) { while ((start < end) && (isBlankChar(str.charAt(start)))) { start++; } } // 扫描字符串尾部 if (mode >= 0) { while ((start < end) && (isBlankChar(str.charAt(end - 1)))) { end--; } } if ((start > 0) || (end < length)) { return str.toString().substring(start, end); } return str.toString(); } /** * 对象是否为数组对象 * * @param obj 对象 * @return 是否为数组对象,如果为{@code null} 返回false */ private static boolean isArray(Object obj) { if (null == obj) { // throw new NullPointerException("Object check for isArray is null"); return false; } return obj.getClass().isArray(); } /** * 是否空白符
* 空白符包括空格、制表符、全角空格和不间断空格
* * @see Character#isWhitespace(int) * @see Character#isSpaceChar(int) * @param c 字符 * @return 是否空白符 * @since 4.0.10 */ private static boolean isBlankChar(char c) { return Character.isWhitespace(c) || Character.isSpaceChar(c) || c == '\ufeff' || c == '\u202a'; } /** * 指定范围内查找指定字符 * * @param str 字符串 * @param searchChar 被查找的字符 * @return 位置 */ public static int indexOf(final CharSequence str, char searchChar) { return indexOf(str, searchChar, 0); } /** * 指定范围内查找指定字符 * * @param str 字符串 * @param searchChar 被查找的字符 * @param start 起始位置,如果小于0,从0开始查找 * @return 位置 */ public static int indexOf(final CharSequence str, char searchChar, int start) { if (str instanceof String) { return ((String) str).indexOf(searchChar, start); } else { return indexOf(str, searchChar, start, -1); } } /** * 指定范围内查找指定字符 * * @param str 字符串 * @param searchChar 被查找的字符 * @param start 起始位置,如果小于0,从0开始查找 * @param end 终止位置,如果超过str.length()则默认查找到字符串末尾 * @return 位置 */ public static int indexOf(final CharSequence str, char searchChar, int start, int end) { final int len = str.length(); if (start < 0 || start > len) { start = 0; } if (end > len || end < 0) { end = len; } for (int i = start; i < end; i++) { if (str.charAt(i) == searchChar) { return i; } } return -1; } /** * 指定范围内查找字符串,忽略大小写
* *
   * StrUtil.indexOfIgnoreCase(null, *, *)          = -1
   * StrUtil.indexOfIgnoreCase(*, null, *)          = -1
   * StrUtil.indexOfIgnoreCase("", "", 0)           = 0
   * StrUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
   * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
   * StrUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
   * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
   * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
   * StrUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
   * StrUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
   * StrUtil.indexOfIgnoreCase("abc", "", 9)        = -1
   * 
* * @param str 字符串 * @param searchStr 需要查找位置的字符串 * @return 位置 * @since 3.2.1 */ public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) { return indexOfIgnoreCase(str, searchStr, 0); } /** * 指定范围内查找字符串 * *
   * StrUtil.indexOfIgnoreCase(null, *, *)          = -1
   * StrUtil.indexOfIgnoreCase(*, null, *)          = -1
   * StrUtil.indexOfIgnoreCase("", "", 0)           = 0
   * StrUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
   * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
   * StrUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
   * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
   * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
   * StrUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
   * StrUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
   * StrUtil.indexOfIgnoreCase("abc", "", 9)        = -1
   * 
* * @param str 字符串 * @param searchStr 需要查找位置的字符串 * @param fromIndex 起始位置 * @return 位置 * @since 3.2.1 */ public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) { return indexOf(str, searchStr, fromIndex, true); } /** * 指定范围内反向查找字符串 * * @param str 字符串 * @param searchStr 需要查找位置的字符串 * @param fromIndex 起始位置 * @param ignoreCase 是否忽略大小写 * @return 位置 * @since 3.2.1 */ public static int indexOf(final CharSequence str, CharSequence searchStr, int fromIndex, boolean ignoreCase) { if (str == null || searchStr == null) { return INDEX_NOT_FOUND; } if (fromIndex < 0) { fromIndex = 0; } final int endLimit = str.length() - searchStr.length() + 1; if (fromIndex > endLimit) { return INDEX_NOT_FOUND; } if (searchStr.length() == 0) { return fromIndex; } if (false == ignoreCase) { // 不忽略大小写调用JDK方法 return str.toString().indexOf(searchStr.toString(), fromIndex); } for (int i = fromIndex; i < endLimit; i++) { if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) { return i; } } return INDEX_NOT_FOUND; } /** * 指定范围内查找字符串,忽略大小写
* * @param str 字符串 * @param searchStr 需要查找位置的字符串 * @return 位置 * @since 3.2.1 */ public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) { return lastIndexOfIgnoreCase(str, searchStr, str.length()); } /** * 指定范围内查找字符串,忽略大小写
* * @param str 字符串 * @param searchStr 需要查找位置的字符串 * @param fromIndex 起始位置,从后往前计数 * @return 位置 * @since 3.2.1 */ public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) { return lastIndexOf(str, searchStr, fromIndex, true); } /** * 指定范围内查找字符串
* * @param str 字符串 * @param searchStr 需要查找位置的字符串 * @param fromIndex 起始位置,从后往前计数 * @param ignoreCase 是否忽略大小写 * @return 位置 * @since 3.2.1 */ public static int lastIndexOf(final CharSequence str, final CharSequence searchStr, int fromIndex, boolean ignoreCase) { if (str == null || searchStr == null) { return INDEX_NOT_FOUND; } if (fromIndex < 0) { fromIndex = 0; } fromIndex = Math.min(fromIndex, str.length()); if (searchStr.length() == 0) { return fromIndex; } if (false == ignoreCase) { // 不忽略大小写调用JDK方法 return str.toString().lastIndexOf(searchStr.toString(), fromIndex); } for (int i = fromIndex; i > 0; i--) { if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) { return i; } } return INDEX_NOT_FOUND; } /** * 截取两个字符串的不同部分(长度一致),判断截取的子串是否相同
* 任意一个字符串为null返回false * * @param str1 第一个字符串 * @param start1 第一个字符串开始的位置 * @param str2 第二个字符串 * @param start2 第二个字符串开始的位置 * @param length 截取长度 * @param ignoreCase 是否忽略大小写 * @return 子串是否相同 * @since 3.2.1 */ public static boolean isSubEquals(CharSequence str1, int start1, CharSequence str2, int start2, int length, boolean ignoreCase) { if (null == str1 || null == str2) { return false; } return str1.toString().regionMatches(ignoreCase, start1, str2.toString(), start2, length); } /** * 字符串是否以给定字符开始 * * @param str 字符串 * @param c 字符 * @return 是否开始 */ public static boolean startWith(CharSequence str, char c) { return c == str.charAt(0); } /** * 是否以指定字符串开头 * * @param str 被监测字符串 * @param prefix 开头字符串 * @return 是否以指定字符串开头 */ public static boolean startWith(CharSequence str, CharSequence prefix) { return startWith(str, prefix, false); } /** * 字符串是否以给定字符结尾 * * @param str 字符串 * @param c 字符 * @return 是否结尾 */ public static boolean endWith(CharSequence str, char c) { return c == str.charAt(str.length() - 1); } /** * 是否以指定字符串结尾
* 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false * * @param str 被监测字符串 * @param suffix 结尾字符串 * @param isIgnoreCase 是否忽略大小写 * @return 是否以指定字符串结尾 */ public static boolean endWith(CharSequence str, CharSequence suffix, boolean isIgnoreCase) { if (null == str || null == suffix) { if (null == str && null == suffix) { return true; } return false; } if (isIgnoreCase) { return str.toString().toLowerCase().endsWith(suffix.toString().toLowerCase()); } else { return str.toString().endsWith(suffix.toString()); } } /** * 是否以指定字符串结尾 * * @param str 被监测字符串 * @param suffix 结尾字符串 * @return 是否以指定字符串结尾 */ public static boolean endWith(CharSequence str, CharSequence suffix) { return endWith(str, suffix, false); } /** * 是否以指定字符串结尾,忽略大小写 * * @param str 被监测字符串 * @param suffix 结尾字符串 * @return 是否以指定字符串结尾 */ public static boolean endWithIgnoreCase(CharSequence str, CharSequence suffix) { return endWith(str, suffix, true); } /** * 指定字符是否在字符串中出现过 * * @param str 字符串 * @param searchChar 被查找的字符 * @return 是否包含 * @since 3.1.2 */ public static boolean contains(CharSequence str, char searchChar) { return indexOf(str, searchChar) > -1; } /** * 是否包含特定字符,忽略大小写,如果给定两个参数都为null,返回true * * @param str 被检测字符串 * @param testStr 被测试是否包含的字符串 * @return 是否包含 */ public static boolean containsIgnoreCase(CharSequence str, CharSequence testStr) { if (null == str) { // 如果被监测字符串和 return null == testStr; } return str.toString().toLowerCase().contains(testStr.toString().toLowerCase()); } /** * @param str * @param separator * @return * @author tanyaowu */ public static String[] split(String str, String separator) { if (str == null) { return null; } return str.split(separator); } /** * 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 * * @param obj 对象 * @return 字符串 */ public static String utf8Str(Object obj) { return str(obj, StandardCharsets.UTF_8); } /** * 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 * * @param obj 对象 * @param charsetName 字符集 * @return 字符串 */ public static String str(Object obj, String charsetName) { return str(obj, Charset.forName(charsetName)); } /** * 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 * * @param obj 对象 * @param charset 字符集 * @return 字符串 */ public static String str(Object obj, Charset charset) { if (null == obj) { return null; } if (obj instanceof String) { return (String) obj; } else if (obj instanceof byte[]) { return str((byte[]) obj, charset); } else if (obj instanceof Byte[]) { return str((Byte[]) obj, charset); } else if (obj instanceof ByteBuffer) { return str((ByteBuffer) obj, charset); } else if (ArrayUtil.isArray(obj)) { return ArrayUtil.toString(obj); } return obj.toString(); } /** * {@link CharSequence} 转为字符串,null安全 * * @param cs {@link CharSequence} * @return 字符串 */ public static String str(CharSequence cs) { return null == cs ? null : cs.toString(); } /** * 改进JDK subString
* index从0开始计算,最后一个字符为-1
* 如果from和to位置一样,返回 ""
* 如果from或to为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length
* 如果经过修正的index中from大于to,则互换from和to example:
* abcdefgh 2 3 =》 c
* abcdefgh 2 -3 =》 cde
* * @param str String * @param fromIndex 开始的index(包括) * @param toIndex 结束的index(不包括) * @return 字串 */ public static String sub(CharSequence str, int fromIndex, int toIndex) { if (isEmpty(str)) { return str(str); } int len = str.length(); if (fromIndex < 0) { fromIndex = len + fromIndex; if (fromIndex < 0) { fromIndex = 0; } } else if (fromIndex > len) { fromIndex = len; } if (toIndex < 0) { toIndex = len + toIndex; if (toIndex < 0) { toIndex = len; } } else if (toIndex > len) { toIndex = len; } if (toIndex < fromIndex) { int tmp = fromIndex; fromIndex = toIndex; toIndex = tmp; } if (fromIndex == toIndex) { return EMPTY; } return str.toString().substring(fromIndex, toIndex); } /** * 截取部分字符串,这里一个汉字的长度认为是2 * * @param str 字符串 * @param len 切割的位置 * @param suffix 切割后加上后缀 * @return 切割后的字符串 * @since 3.1.1 */ public static String subPreGbk(CharSequence str, int len, CharSequence suffix) { if (isEmpty(str)) { return str(str); } byte b[]; int counterOfDoubleByte = 0; b = str.toString().getBytes(Charset.forName("GBK")); if (b.length <= len) { return str.toString(); } for (int i = 0; i < len; i++) { if (b[i] < 0) { counterOfDoubleByte++; } } if (counterOfDoubleByte % 2 != 0) { len += 1; } return new String(b, 0, len, Charset.forName("GBK")) + suffix; } /** * 限制字符串长度,如果超过指定长度,截取指定长度并在末尾加"..." * * @param string 字符串 * @param length 最大长度 * @return 切割后的剩余的前半部分字符串+"..." * @since 4.0.10 */ public static String maxLength(CharSequence string, int length) { if (null == string) { return null; } if (string.length() <= length) { return string.toString(); } return sub(string, 0, length) + "..."; } /** * 切割指定位置之前部分的字符串 * * @param string 字符串 * @param toIndex 切割到的位置(不包括) * @return 切割后的剩余的前半部分字符串 */ public static String subPre(CharSequence string, int toIndex) { return sub(string, 0, toIndex); } /** * 切割指定位置之后部分的字符串 * * @param string 字符串 * @param fromIndex 切割开始的位置(包括) * @return 切割后后剩余的后半部分字符串 */ public static String subSuf(CharSequence string, int fromIndex) { if (isEmpty(string)) { return null; } return sub(string, fromIndex, string.length()); } /** * 切割指定长度的后部分的字符串 * *
   * StrUtil.subSufByLength("abcde", 3)      =    "cde"
   * StrUtil.subSufByLength("abcde", 0)      =    ""
   * StrUtil.subSufByLength("abcde", -5)     =    ""
   * StrUtil.subSufByLength("abcde", -1)     =    ""
   * StrUtil.subSufByLength("abcde", 5)       =    "abcde"
   * StrUtil.subSufByLength("abcde", 10)     =    "abcde"
   * StrUtil.subSufByLength(null, 3)               =    null
   * 
* * @param string 字符串 * @param length 切割长度 * @return 切割后后剩余的后半部分字符串 * @since 4.0.1 */ public static String subSufByLength(CharSequence string, int length) { if (isEmpty(string)) { return null; } if (length <= 0) { return EMPTY; } return sub(string, -length, string.length()); } /** * 截取字符串,从指定位置开始,截取指定长度的字符串
* author weibaohui * * @param input 原始字符串 * @param fromIndex 开始的index,包括 * @param length 要截取的长度 * @return 截取后的字符串 */ public static String subWithLength(String input, int fromIndex, int length) { return sub(input, fromIndex, fromIndex + length); } /** * 截取分隔字符串之前的字符串,不包括分隔字符串
* 如果给定的字符串为空串(null或"")或者分隔字符串为null,返回原字符串
* 如果分隔字符串为空串"",则返回空串,如果分隔字符串未找到,返回原字符串 * * 栗子: * *
   * StrUtil.subBefore(null, *)      = null
   * StrUtil.subBefore("", *)        = ""
   * StrUtil.subBefore("abc", "a")   = ""
   * StrUtil.subBefore("abcba", "b") = "a"
   * StrUtil.subBefore("abc", "c")   = "ab"
   * StrUtil.subBefore("abc", "d")   = "abc"
   * StrUtil.subBefore("abc", "")    = ""
   * StrUtil.subBefore("abc", null)  = "abc"
   * 
* * @param string 被查找的字符串 * @param separator 分隔字符串(不包括) * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个 * @return 切割后的字符串 * @since 3.1.1 */ public static String subBefore(CharSequence string, CharSequence separator, boolean isLastSeparator) { if (isEmpty(string) || separator == null) { return null == string ? null : string.toString(); } final String str = string.toString(); final String sep = separator.toString(); if (sep.isEmpty()) { return EMPTY; } final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep); if (pos == INDEX_NOT_FOUND) { return str; } return str.substring(0, pos); } /** * 截取分隔字符串之后的字符串,不包括分隔字符串
* 如果给定的字符串为空串(null或""),返回原字符串
* 如果分隔字符串为空串(null或""),则返回空串,如果分隔字符串未找到,返回空串 * * 栗子: * *
   * StrUtil.subAfter(null, *)      = null
   * StrUtil.subAfter("", *)        = ""
   * StrUtil.subAfter(*, null)      = ""
   * StrUtil.subAfter("abc", "a")   = "bc"
   * StrUtil.subAfter("abcba", "b") = "cba"
   * StrUtil.subAfter("abc", "c")   = ""
   * StrUtil.subAfter("abc", "d")   = ""
   * StrUtil.subAfter("abc", "")    = "abc"
   * 
* * @param string 被查找的字符串 * @param separator 分隔字符串(不包括) * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个 * @return 切割后的字符串 * @since 3.1.1 */ public static String subAfter(CharSequence string, CharSequence separator, boolean isLastSeparator) { if (isEmpty(string)) { return null == string ? null : string.toString(); } if (separator == null) { return EMPTY; } final String str = string.toString(); final String sep = separator.toString(); final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep); if (pos == INDEX_NOT_FOUND) { return EMPTY; } return str.substring(pos + separator.length()); } /** * 截取指定字符串中间部分,不包括标识字符串
* * 栗子: * *
   * StrUtil.subBetween("wx[b]yz", "[", "]") = "b"
   * StrUtil.subBetween(null, *, *)          = null
   * StrUtil.subBetween(*, null, *)          = null
   * StrUtil.subBetween(*, *, null)          = null
   * StrUtil.subBetween("", "", "")          = ""
   * StrUtil.subBetween("", "", "]")         = null
   * StrUtil.subBetween("", "[", "]")        = null
   * StrUtil.subBetween("yabcz", "", "")     = ""
   * StrUtil.subBetween("yabcz", "y", "z")   = "abc"
   * StrUtil.subBetween("yabczyabcz", "y", "z")   = "abc"
   * 
* * @param str 被切割的字符串 * @param before 截取开始的字符串标识 * @param after 截取到的字符串标识 * @return 截取后的字符串 * @since 3.1.1 */ public static String subBetween(CharSequence str, CharSequence before, CharSequence after) { if (str == null || before == null || after == null) { return null; } final String str2 = str.toString(); final String before2 = before.toString(); final String after2 = after.toString(); final int start = str2.indexOf(before2); if (start != INDEX_NOT_FOUND) { final int end = str2.indexOf(after2, start + before2.length()); if (end != INDEX_NOT_FOUND) { return str2.substring(start + before2.length(), end); } } return null; } /** * 截取指定字符串中间部分,不包括标识字符串
* * 栗子: * *
   * StrUtil.subBetween(null, *)            = null
   * StrUtil.subBetween("", "")             = ""
   * StrUtil.subBetween("", "tag")          = null
   * StrUtil.subBetween("tagabctag", null)  = null
   * StrUtil.subBetween("tagabctag", "")    = ""
   * StrUtil.subBetween("tagabctag", "tag") = "abc"
   * 
* * @param str 被切割的字符串 * @param beforeAndAfter 截取开始和结束的字符串标识 * @return 截取后的字符串 * @since 3.1.1 */ public static String subBetween(CharSequence str, CharSequence beforeAndAfter) { return subBetween(str, beforeAndAfter, beforeAndAfter); } /** * * @param type * @param value * @return * @throws Exception * @author tanyaowu */ public static Object convert(Class type, String value) throws Exception { if (type == String.class) { return value; } else { if (isBlank(value)) { return null; } if (type == Byte.class || type == byte.class) { return Byte.parseByte(value); } else if (type == Short.class || type == short.class) { return Short.parseShort(value); } else if (type == Integer.class || type == int.class) { return Integer.parseInt(value); } else if (type == Long.class || type == long.class) { return Long.parseLong(value); } else if (type == Float.class || type == float.class) { return Float.parseFloat(value); } else if (type == Double.class || type == double.class) { return Double.parseDouble(value); } else if (type == Character.class || type == char.class) { return Character.valueOf(value.charAt(0)); } else if (type == Boolean.class || type == boolean.class) { return "1".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value); } else if (type == BigDecimal.class) { return new BigDecimal(value); } else if (type == BigInteger.class) { return new BigInteger(value); } else if (type == Number.class) { return NumberFormat.getInstance().parse(value); } else if (type == Date.class) { return DateUtil.parseToDate(value); } else if (type == java.sql.Date.class) { return DateUtil.parseToSqlDate(value); } else if (type == java.sql.Timestamp.class) { return DateUtil.parseToTimestamp(value); } else if (type == java.sql.Time.class) { return DateUtil.parseToTime(value); } } throw new Exception("不知道要转换成啥" + type); } /** * * @param type * @param values * @return 返回的也是一个数组 * @throws Exception * @author tanyaowu */ // @SuppressWarnings("unchecked") public static Object convert(Class type, String[] values) throws Exception { if (values == null) { return null; } Class componentType = null; if (type.isArray()) { componentType = type.getComponentType(); } else { componentType = type; } if (componentType.isPrimitive()) { if (componentType == int.class) { int[] ret = new int[values.length]; for (int i = 0; i < ret.length; i++) { if (isBlank(values[i])) { ret[i] = 0; continue; } ret[i] = Integer.parseInt(values[i]); } return ret; } else if (componentType == long.class) { long[] ret = new long[values.length]; for (int i = 0; i < ret.length; i++) { if (isBlank(values[i])) { ret[i] = 0; continue; } ret[i] = Long.parseLong(values[i]); } return ret; } else if (componentType == short.class) { short[] ret = new short[values.length]; for (int i = 0; i < ret.length; i++) { if (isBlank(values[i])) { ret[i] = 0; continue; } ret[i] = Short.parseShort(values[i]); } return ret; } else if (componentType == double.class) { double[] ret = new double[values.length]; for (int i = 0; i < ret.length; i++) { if (isBlank(values[i])) { ret[i] = 0; continue; } ret[i] = Double.parseDouble(values[i]); } return ret; } else if (componentType == float.class) { float[] ret = new float[values.length]; for (int i = 0; i < ret.length; i++) { if (isBlank(values[i])) { ret[i] = 0; continue; } ret[i] = Float.parseFloat(values[i]); } return ret; } else if (componentType == byte.class) { byte[] ret = new byte[values.length]; for (int i = 0; i < ret.length; i++) { if (isBlank(values[i])) { ret[i] = 0; continue; } ret[i] = Byte.parseByte(values[i]); } return ret; } else if (componentType == boolean.class) { boolean[] ret = new boolean[values.length]; for (int i = 0; i < ret.length; i++) { if (isBlank(values[i])) { ret[i] = false; continue; } ret[i] = "1".equalsIgnoreCase(values[i]) || "true".equalsIgnoreCase(values[i]) || "yes".equalsIgnoreCase(values[i]); } return ret; } else if (componentType == char.class) { char[] ret = new char[values.length]; for (int i = 0; i < ret.length; i++) { if (isBlank(values[i])) { ret[i] = 0; continue; } ret[i] = Character.valueOf(values[i].charAt(0)); } return ret; } return null; } else { Object[] ret = ArrayUtil.newArray(componentType, values.length); for (int i = 0; i < ret.length; i++) { ret[i] = convert(componentType, values[i]); } return ret; } } /** * 查找指定字符串是否包含指定字符串列表中的任意一个字符串 * * @param str 指定字符串 * @param testStrs 需要检查的字符串数组 * @return 是否包含任意一个字符串 * @since 3.2.0 */ public static boolean containsAny(CharSequence str, CharSequence... testStrs) { return null != getContainsStr(str, testStrs); } /** * 查找指定字符串是否包含指定字符串列表中的任意一个字符串,如果包含返回找到的第一个字符串 * * @param str 指定字符串 * @param testStrs 需要检查的字符串数组 * @return 被包含的第一个字符串 * @since 3.2.0 */ public static String getContainsStr(CharSequence str, CharSequence... testStrs) { if (isEmpty(str) || testStrs == null) { return null; } for (CharSequence checkStr : testStrs) { if (str.toString().contains(checkStr)) { return checkStr.toString(); } } return null; } /** * 大写首字母
* 例如:str = name, return Name * * @param str 字符串 * @return 字符串 */ public static String upperFirst(CharSequence str) { if (null == str) { return null; } if (str.length() > 0) { char firstChar = str.charAt(0); if (Character.isLowerCase(firstChar)) { return Character.toUpperCase(firstChar) + subSuf(str, 1); } } return str.toString(); } /** * 小写首字母
* 例如:str = Name, return name * * @param str 字符串 * @return 字符串 */ public static String lowerFirst(CharSequence str) { if (null == str) { return null; } if (str.length() > 0) { char firstChar = str.charAt(0); if (Character.isUpperCase(firstChar)) { return Character.toLowerCase(firstChar) + subSuf(str, 1); } } return str.toString(); } /** * 字符串转换成驼峰格式 * *
   * toLowerCaseAnyway 参数的作用如下:
   * 
   * 1:当待转换字符串中包含下划线字符 '_' 时,无需关心 toLowerCaseAnyway 参数的值,转换结果始终一样
   * 
   * 2:当待转换字符串中不包含下划线字符 '_' 时,toLowerCaseAnyway 参数规则如下:
   *    true 值:  将待转换字符串全部转换成小与字母,适用于 oralce 数据库字段转换的场景
   *              因为 oracle 字段全是大写字母
   *                 
   *    false 值: 则原样返回待转换字符串,适用于待转换字符串可能原本就是驼峰格式的场景
   *              如果原本就是驼峰,全部转成小写字母显然不合理
   * 
*/ public static String toCamelCase(String str, boolean toLowerCaseAnyway) { int len = str.length(); if (len <= 1) { return str; } char ch; int index = 0; char[] buf = new char[len]; int i = 0; for (; i < len; i++) { ch = str.charAt(i); if (ch == '_') { // 当前字符为下划线时,将指针后移一位,将紧随下划线后面一个字符转成大写并存放 i++; if (i < len) { ch = str.charAt(i); buf[index] = (index == 0 ? // 首字母无条件变小写 Character.toLowerCase(ch) : Character.toUpperCase(ch)); index++; } } else { buf[index++] = Character.toLowerCase(ch); } } if (toLowerCaseAnyway) { return new String(buf, 0, index); } // i == index 时,表明字符串中不存在字符 '_' // 无下划线的字符串原本可能就是驼峰形式,所以原样返回 return i == index ? str : new String(buf, 0, index); } /** * 首字母变小写 * * @param str * @return */ public static String firstCharToLowerCase(String str) { char firstChar = str.charAt(0); if (firstChar >= 'A' && firstChar <= 'Z') { char[] arr = str.toCharArray(); arr[0] += ('a' - 'A'); return new String(arr); } return str; } public static boolean isNotEmpty(String str) { return str != null && !str.isEmpty(); } public static boolean notEmpty(String str) { return str != null && !str.isEmpty(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy