全网最全:Java字符串处理

createh54个月前 (01-13)技术教程41

Java字符串处理,包含了多个静态方法,用于执行不同类型的字符串操作。

开箱即用

空白和空字符串检查

  • isBlankIfStr(Object obj):检查对象是否为空白字符串,包括null、空字符串、只包含空白字符(如空格、制表符等)的字符串。
  • isEmptyIfStr(Object obj):检查对象是否为空字符串,与isBlankIfStr不同,此方法不检查空白字符。

字符串处理

  • trim(String[] strs):对字符串数组中的每个元素进行首尾空白字符去除。
  • utf8Str(Object obj)str(Object obj, Charset charset):将对象转换为UTF-8编码的字符串。
  • toString(Object obj)toStringOrNull(Object obj):调用对象的toString方法,toStringOrNull在对象为null时返回null

字符串创建

  • builder()strBuilder():分别创建StringBuilderStrBuilder对象。
  • builder(int capacity)strBuilder(int capacity):创建具有指定初始容量的StringBuilderStrBuilder对象。

字符串填充

  • fillBefore(String str, char filledChar, int len)fillAfter(String str, char filledChar, int len):在字符串前或后填充字符至指定长度。

字符串转换

  • getReader(CharSequence str)getWriter():分别获取StringReaderStringWriter对象。
  • reverse(String str):反转字符串。

字符串相似度

  • similar(String str1, String str2)similar(String str1, String str2, int scale):计算两个字符串的相似度。

UUID生成

  • uuid():生成随机UUID字符串。

文本格式化

  • format(CharSequence template, Map<?, ?> map)format(CharSequence template, Map<?, ?> map, boolean ignoreNull):使用占位符格式化文本。

字符串截断

  • truncateUtf8(String str, int maxBytes)truncateByByteLength(String str, Charset charset, int maxBytes, int factor, boolean appendDots):根据指定的最大字节长度截断字符串,并可选地添加省略号。

具体代码:(代码参考Hutool字符串处理类)

// ------------------------------------------------------------------------ Blank

/**
 * <p>如果对象是字符串是否为空白,空白的定义如下:</p>
 * <ol>
 *     <li>{@code null}</li>
 *     <li>空字符串:{@code ""}</li>
 *     <li>空格、全角空格、制表符、换行符,等不可见字符</li>
 * </ol>
 *
 * <p>例:</p>
 * <ul>
 *     <li>{@code StrUtil.isBlankIfStr(null)     // true}</li>
 *     <li>{@code StrUtil.isBlankIfStr("")       // true}</li>
 *     <li>{@code StrUtil.isBlankIfStr(" \t\n")  // true}</li>
 *     <li>{@code StrUtil.isBlankIfStr("abc")    // false}</li>
 * </ul>
 *
 * <p>注意:该方法与 {@link #isEmptyIfStr(Object)} 的区别是:
 * 该方法会校验空白字符,且性能相对于 {@link #isEmptyIfStr(Object)} 略慢。</p>
 *
 * @param obj 对象
 * @return 如果为字符串是否为空串
 * @see StrUtil#isBlank(CharSequence)
 * @since 3.3.0
 */
public static boolean isBlankIfStr(Object obj) {
    if (null == obj) {
       return true;
    } else if (obj instanceof CharSequence) {
       return isBlank((CharSequence) obj);
    }
    return false;
}
// ------------------------------------------------------------------------ Empty

/**
 * <p>如果对象是字符串是否为空串,空的定义如下:</p><br>
 * <ol>
 *     <li>{@code null}</li>
 *     <li>空字符串:{@code ""}</li>
 * </ol>
 *
 * <p>例:</p>
 * <ul>
 *     <li>{@code StrUtil.isEmptyIfStr(null)     // true}</li>
 *     <li>{@code StrUtil.isEmptyIfStr("")       // true}</li>
 *     <li>{@code StrUtil.isEmptyIfStr(" \t\n")  // false}</li>
 *     <li>{@code StrUtil.isEmptyIfStr("abc")    // false}</li>
 * </ul>
 *
 * <p>注意:该方法与 {@link #isBlankIfStr(Object)} 的区别是:该方法不校验空白字符。</p>
 *
 * @param obj 对象
 * @return 如果为字符串是否为空串
 * @since 3.3.0
 */
public static boolean isEmptyIfStr(Object obj) {
    if (null == obj) {
       return true;
    } else if (obj instanceof CharSequence) {
       return 0 == ((CharSequence) obj).length();
    }
    return false;
}

// ------------------------------------------------------------------------ Trim

/**
 * 给定字符串数组全部做去首尾空格
 *
 * @param strs 字符串数组
 */
public static void trim(String[] strs) {
    if (null == strs) {
       return;
    }
    String str;
    for (int i = 0; i < strs.length; i++) {
       str = strs[i];
       if (null != str) {
          strs[i] = trim(str);
       }
    }
}

/**
 * 将对象转为字符串<br>
 *
 * <pre>
 * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组
 * 2、对象数组会调用Arrays.toString方法
 * </pre>
 *
 * @param obj 对象
 * @return 字符串
 */
public static String utf8Str(Object obj) {
    return str(obj, CharsetUtil.CHARSET_UTF_8);
}

/**
 * 将对象转为字符串
 *
 * <pre>
 * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组
 * 2、对象数组会调用Arrays.toString方法
 * </pre>
 *
 * @param obj         对象
 * @param charsetName 字符集
 * @return 字符串
 * @deprecated 请使用 {@link #str(Object, Charset)}
 */
@Deprecated
public static String str(Object obj, String charsetName) {
    return str(obj, Charset.forName(charsetName));
}

/**
 * 将对象转为字符串
 * <pre>
 *   1、Byte数组和ByteBuffer会被转换为对应字符串的数组
 *   2、对象数组会调用Arrays.toString方法
 * </pre>
 *
 * @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();
}

/**
 * 将byte数组转为字符串
 *
 * @param bytes   byte数组
 * @param charset 字符集
 * @return 字符串
 */
public static String str(byte[] bytes, String charset) {
    return str(bytes, CharsetUtil.charset(charset));
}

/**
 * 解码字节码
 *
 * @param data    字符串
 * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
 * @return 解码后的字符串
 */
public static String str(byte[] data, Charset charset) {
    if (data == null) {
       return null;
    }

    if (null == charset) {
       return new String(data);
    }
    return new String(data, charset);
}

/**
 * 将Byte数组转为字符串
 *
 * @param bytes   byte数组
 * @param charset 字符集
 * @return 字符串
 */
public static String str(Byte[] bytes, String charset) {
    return str(bytes, CharsetUtil.charset(charset));
}

/**
 * 解码字节码
 *
 * @param data    字符串
 * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
 * @return 解码后的字符串
 */
public static String str(Byte[] data, Charset charset) {
    if (data == null) {
       return null;
    }

    byte[] bytes = new byte[data.length];
    Byte dataByte;
    for (int i = 0; i < data.length; i++) {
       dataByte = data[i];
       bytes[i] = (null == dataByte) ? -1 : dataByte;
    }

    return str(bytes, charset);
}

/**
 * 将编码的byteBuffer数据转换为字符串
 *
 * @param data    数据
 * @param charset 字符集,如果为空使用当前系统字符集
 * @return 字符串
 */
public static String str(ByteBuffer data, String charset) {
    if (data == null) {
       return null;
    }

    return str(data, CharsetUtil.charset(charset));
}

/**
 * 将编码的byteBuffer数据转换为字符串
 *
 * @param data    数据
 * @param charset 字符集,如果为空使用当前系统字符集
 * @return 字符串
 */
public static String str(ByteBuffer data, Charset charset) {
    if (null == charset) {
       charset = Charset.defaultCharset();
    }
    return charset.decode(data).toString();
}

/**
 * 调用对象的toString方法,null会返回“null”
 *
 * @param obj 对象
 * @return 字符串
 * @see String#valueOf(Object)
 * @since 4.1.3
 */
public static String toString(Object obj) {
    return String.valueOf(obj);
}

/**
 * 调用对象的toString方法,null会返回{@code null}
 *
 * @param obj 对象
 * @return 字符串 or {@code null}
 * @since 5.7.17
 */
public static String toStringOrNull(Object obj) {
    return null == obj ? null : obj.toString();
}

/**
 * 创建StringBuilder对象
 *
 * @return StringBuilder对象
 */
public static StringBuilder builder() {
    return new StringBuilder();
}

/**
 * 创建StrBuilder对象
 *
 * @return StrBuilder对象
 * @since 4.0.1
 */
public static StrBuilder strBuilder() {
    return StrBuilder.create();
}

/**
 * 创建StringBuilder对象
 *
 * @param capacity 初始大小
 * @return StringBuilder对象
 */
public static StringBuilder builder(int capacity) {
    return new StringBuilder(capacity);
}

/**
 * 创建StrBuilder对象
 *
 * @param capacity 初始大小
 * @return StrBuilder对象
 * @since 4.0.1
 */
public static StrBuilder strBuilder(int capacity) {
    return StrBuilder.create(capacity);
}

/**
 * 获得StringReader
 *
 * @param str 字符串
 * @return StringReader
 */
public static StringReader getReader(CharSequence str) {
    if (null == str) {
       return null;
    }
    return new StringReader(str.toString());
}

/**
 * 获得StringWriter
 *
 * @return StringWriter
 */
public static StringWriter getWriter() {
    return new StringWriter();
}

/**
 * 反转字符串<br>
 * 例如:abcd =》dcba
 *
 * @param str 被反转的字符串
 * @return 反转后的字符串
 * @since 3.0.9
 */
public static String reverse(String str) {
    return new String(ArrayUtil.reverse(str.toCharArray()));
}

// ------------------------------------------------------------------------ fill

/**
 * 将已有字符串填充为规定长度,如果已有字符串超过这个长度则返回这个字符串<br>
 * 字符填充于字符串前
 *
 * @param str        被填充的字符串
 * @param filledChar 填充的字符
 * @param len        填充长度
 * @return 填充后的字符串
 * @since 3.1.2
 */
public static String fillBefore(String str, char filledChar, int len) {
    return fill(str, filledChar, len, true);
}

/**
 * 将已有字符串填充为规定长度,如果已有字符串超过这个长度则返回这个字符串<br>
 * 字符填充于字符串后
 *
 * @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 = StrUtil.repeat(filledChar, len - strLen);
    return isPre ? filledStr.concat(str) : str.concat(filledStr);
}

/**
 * 计算两个字符串的相似度
 *
 * @param str1 字符串1
 * @param str2 字符串2
 * @return 相似度
 * @since 3.2.3
 */
public static double similar(String str1, String str2) {
    return TextSimilarity.similar(str1, str2);
}

/**
 * 计算两个字符串的相似度百分比
 *
 * @param str1  字符串1
 * @param str2  字符串2
 * @param scale 相似度
 * @return 相似度百分比
 * @since 3.2.3
 */
public static String similar(String str1, String str2, int scale) {
    return TextSimilarity.similar(str1, str2, scale);
}

/**
 * 生成随机UUID
 *
 * @return UUID字符串
 * @see IdUtil#randomUUID()
 * @since 4.0.10
 */
public static String uuid() {
    return IdUtil.randomUUID();
}

/**
 * 格式化文本,使用 {varName} 占位<br>
 * map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=》 aValue and bValue
 *
 * @param template 文本模板,被替换的部分用 {key} 表示
 * @param map      参数值对
 * @return 格式化后的文本
 */
public static String format(CharSequence template, Map<?, ?> map) {
    return format(template, map, true);
}

/**
 * 格式化文本,使用 {varName} 占位<br>
 * map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=》 aValue and bValue
 *
 * @param template   文本模板,被替换的部分用 {key} 表示
 * @param map        参数值对
 * @param ignoreNull 是否忽略 {@code null} 值,忽略则 {@code null} 值对应的变量不被替换,否则替换为""
 * @return 格式化后的文本
 * @since 5.4.3
 */
public static String format(CharSequence template, Map<?, ?> map, boolean ignoreNull) {
    return StrFormatter.format(template, map, ignoreNull);
}

/**
 * 截断字符串,使用其按照UTF-8编码为字节后不超过maxBytes长度。截断后自动追加省略号(...)
 * 用于存储数据库varchar且编码为UTF-8的字段
 *
 * @param str      java字符串
 * @param maxBytes 最大字节长度
 * @return 截断后的字符
 */
public static String truncateUtf8(String str, int maxBytes) {
    Charset charset = StandardCharsets.UTF_8;
    //UTF-8编码单个字符最大长度4
    return truncateByByteLength(str, charset, maxBytes, 4, true);
}

/**
 * 截断字符串,使用其按照指定编码为字节后不超过maxBytes长度<br>
 * 此方法用于截取总bytes数不超过指定长度,如果字符出没有超出原样输出,如果超出了,则截取掉超出部分,并可选添加...,
 * 但是添加“...”后总长度也不超过限制长度。
 *
 * @param str        原始字符串
 * @param charset    指定编码
 * @param maxBytes   最大字节数
 * @param factor     速算因子,取该编码下单个字符的最大可能字节数
 * @param appendDots 截断后是否追加省略号(...)
 * @return 截断后的字符串
 */
public static String truncateByByteLength(String str, Charset charset, int maxBytes, int factor,
       boolean appendDots) {
    //字符数*速算因子<=最大字节数
    if (str == null || str.length() * factor <= maxBytes) {
       return str;
    }
    final byte[] sba = str.getBytes(charset);
    if (sba.length <= maxBytes) {
       return str;
    }
    //限制字节数
    final int limitBytes;
    if (appendDots) {
       limitBytes = maxBytes - "...".getBytes(charset).length;
    } else {
       limitBytes = maxBytes;
    }
    final ByteBuffer bb = ByteBuffer.wrap(sba, 0, limitBytes);
    final CharBuffer cb = CharBuffer.allocate(limitBytes);
    final CharsetDecoder decoder = charset.newDecoder();
    //忽略被截断的字符
    decoder.onMalformedInput(CodingErrorAction.IGNORE);
    decoder.decode(bb, cb, true);
    decoder.flush(cb);
    final String result = new String(cb.array(), 0, cb.position());
    if (appendDots) {
       return result + "...";
    }
    return result;
}

相关文章

Java基础之String与int两者之间如何相互转换?

项目开发中String字符串和int整型之间的转换操作是很常见的,当然可能你也会遇到String字符串和其它基本数据类型的转换操作,比如float、long、double等常见的类型。那么如果我们学会...

Java Array 和 String 的转换

英文标题【Array to String Conversions】概述本页面中的内容对 Array 和 String 之间互相进行转换的方法进行一些说明。我们可以使用 原生 Java(vanilla...

idea插件开发,写Java代码时中文字符替换为英文字符的多种方法

大部分编程语言写代码的时候,不能出现中文标点符号,必须使用英文的标点符号,但是写代码的过程中,很多时候是需要写中文注释的,这样来回切换输入法呢,有点繁琐,有时候不小心忘记切换,就写错了,有的编辑器比较...

Java将字符串解析为Json格式

解析json字符串格式如下"[[{"Result":{"ResponseStatus":{"ErrorCode":500,"IsSucc...

Java设置字符串的首字母为大写

概述Java 标准库提供了 String.toUpperCase() 方法,它允许我们将字符串中的所有字母转换为大写。在本文中,我们将学习如何将给定字符串的第一个字符仅转换为大写。 问题介绍一个例子可...

Java时间格式字符串与Date的相互转化

一、将Date转化为格式化字符串将Date转化为格式化字符串是利用SimpleDateFormat类继承自 java.text.DateFormat类的format方法实现的:public final...