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

com.feilong.core.lang.StringUtil Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
/*
 * Copyright (C) 2008 feilong
 *
 * 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
 *
 *         http://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 com.feilong.core.lang;

import static com.feilong.core.Validator.isNullOrEmpty;
import static com.feilong.core.bean.ConvertUtil.toArray;
import static com.feilong.core.lang.ArrayUtil.EMPTY_STRING_ARRAY;
import static com.feilong.core.util.CollectionsUtil.newArrayList;

import java.io.UncheckedIOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import com.feilong.core.CharsetType;
import com.feilong.core.Validate;
import com.feilong.lib.lang3.StringUtils;
import com.feilong.lib.lang3.text.StrSubstitutor;
import com.feilong.tools.slf4j.Slf4jUtil;

/**
 * {@link String}工具类,可以查询,截取,format.
 * 
 * 

分隔(split)

* *
*
    *
  • {@link #split(String, String)}
  • *
*
* *

分隔(tokenize)

* *
*
    *
  • {@link #tokenizeToStringArray(String, String)}
  • *
  • {@link #tokenizeToStringArray(String, String, boolean, boolean)}
  • *
* *

* 区别在于,split 使用的是 正则表达式 {@link Pattern#split(CharSequence)} 分隔(特别注意,一些特殊字符 $|()[{^?*+\\ 需要转义才能做分隔符),而 {@link StringTokenizer} 使用索引机制,在性能上 * StringTokenizer更高
* 因此,在注重性能的场景,还是建议使用{@link StringTokenizer} *

* *
* *

查询(search)

* *
*
    *
  • {@link StringUtils#countMatches(CharSequence, CharSequence)} 查询出现的次数
  • *
*
* *

其他

* *
*
    *
  • {@link StringUtils#capitalize(String)} 首字母大写
  • *
  • {@link StringUtils#uncapitalize(String)} 单词首字母小写
  • *
  • org.apache.commons.lang3.text.WordUtils#uncapitalize(String, char...) 如果要使用一段文字,每个单词首字母小写
  • *
*
* *

{@link String#String(byte[] )} 和 {@link String#String(byte[], Charset)} 区别

* *
*

* {@link String#String(byte[] )} 其实调用了{@link String#String(byte[], Charset)};
* 先使用 {@link Charset#defaultCharset()},如果有异常再用 ISO-8859-1, 具体参见 java.lang.StringCoding#decode(byte[], int, int) *

*
* *

{@link StringBuffer} 和 {@link StringBuilder} 和 {@link String} 对比

* *
*
    *
  • {@link StringBuffer} 字符串变量(线程安全)
  • *
  • {@link StringBuilder} 字符串变量(非线程安全)
  • *
  • {@link String} 字符串常量
  • *
  • 在大部分情况下 {@link StringBuffer} {@code >} {@link String}
  • *
  • 在大部分情况下 {@link StringBuilder} {@code >} {@link StringBuffer}
  • *
*
* *

String s1 = new String("xyz"); 到底创建几个对象?

* *
*

* 要看虚拟机的实现.而且要联系上下文 *

* *
    *
  • 假设:HotSpot1.6,之前没有创建过"xyz" 则创建2个,之前创建过"xyz"则只创建1个
  • *
  • 假设:HotSpot1.7,之前不管有没有创建过"xyz" 都创建1个
  • *
*
* *

String s3 = s1 + s2; 
* s3.intern() == s3 到底相不相等?

*

* 要看虚拟机的实现 *

* *
    *
  • 假设:HotSpot1.6,则false不相等
  • *
  • 假设:HotSpot1.7,则在之前没有创建过"abcabc"时,true相等
  • *
*
* *

{@link StringUtil#replace(String, String, String) replace} 和 {@link #replaceAll(CharSequence, String, String) replaceAll} 和 * {@link String#replaceFirst(String, String) replaceFirst}区别:

* *
* * * * * * * * * * * * * * * * * * *
字段说明
{@link StringUtil#replace(String, String, String)}将字符串中出现的target替换成replacement
{@link #replaceAll(CharSequence, String, String)}regex是一个正则表达式,将字符串中匹配的子字符串替换为replacement
{@link String#replaceFirst(String, String)}和{@link StringUtil#replace(String, String, String)}类似,只不过只替换第一个出现的地方。
* *

* 对比以下代码: *

* *
 * StringUtil.replaceAll("SH1265,SH5951", "([a-zA-Z]+[0-9]+)", "'$1'")  ='SH1265','SH5951'
 * StringUtil.replace("SH1265,SH5951", "([a-zA-Z]+[0-9]+)", "'$1'")     =SH1265,SH5951
 * "SH1265,SH5951".replaceFirst("([a-zA-Z]+[0-9]+)", "'$1'")            ='SH1265',SH5951
 * 
* *
* * @author feilong * @see java.util.StringTokenizer * @see "org.springframework.util.StringUtils#tokenizeToStringArray(String, String)" * @see "org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#MULTI_VALUE_ATTRIBUTE_DELIMITERS" * @see com.feilong.lib.lang3.StringUtils * @see "com.google.common.base.Strings" * @since 1.4.0 */ public final class StringUtil{ /** * A String for a space character. * * @since 3.0.0 */ public static final String SPACE = " "; /** * The empty String {@code ""}. * * @since 3.0.0 */ public static final String EMPTY = ""; /** * A String for linefeed LF ("\n"). * * @see JLF: Escape Sequences * for Character and String Literals * @since 3.0.0 */ public static final String LF = "\n"; /** * A String for carriage return CR ("\r"). * * @see JLF: Escape Sequences * for Character and String Literals * @since 3.0.0 */ public static final String CR = "\r"; //--------------------------------------------------------------- /** Don't let anyone instantiate this class. */ private StringUtil(){ //AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化. //see 《Effective Java》 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } //--------------------------------------------------------------- /** * Constructs a new String by decoding the specified array of bytes using the given charset. * * @param bytes * The bytes to be decoded into characters, may be null * @param charsetType * 字符编码,建议使用 {@link CharsetType} 定义好的常量 * @return A new String decoded from the specified array of bytes using the given charset, * or null if the input byte array was null. * @see String#String(byte[], String) * @see "org.apache.commons.lang3.StringUtils#toString(byte[], String)" * @see com.feilong.lib.lang3.StringUtils#toEncodedString(byte[], Charset) * @see "org.apache.commons.codec.binary.StringUtils#newString(byte[], String)" * @since 1.3.0 */ public static String newString(byte[] bytes,String charsetType){ return StringUtils.toEncodedString(bytes, Charset.forName(charsetType)); } // [start]toBytes //--------------------------------------------------------------- /** * 字符串转换成byte数组. * * @param value * 字符串 * @return 如果 value 是null,抛出 {@link NullPointerException}
* @see String#getBytes() * @since 1.3.0 */ public static byte[] getBytes(String value){ Validate.notNull(value, "value can't be null!"); return value.getBytes(); } /** * 字符串 value 转换成byte数组. * * @param value * 字符串 * @param charsetName * 受支持的 charset 名称,比如 utf-8, {@link CharsetType} * @return 如果 value 是null,抛出 {@link NullPointerException}
* 如果 charsetName 是null,抛出 {@link NullPointerException}
* 如果 charsetName 是blank,抛出 {@link IllegalArgumentException}
* @see String#getBytes(String) * @since 1.3.0 */ public static byte[] getBytes(String value,String charsetName){ Validate.notNull(value, "value can't be null!"); Validate.notBlank(charsetName, "charsetName can't be blank!"); //--------------------------------------------------------------- try{ return value.getBytes(charsetName); }catch (UnsupportedEncodingException e){ String pattern = "value:[{}],charsetName:[{}],suggest you use [{}] constants"; String message = Slf4jUtil.format(pattern, value, charsetName, CharsetType.class.getCanonicalName()); throw new UncheckedIOException(message, e); } } // [end] // [start]replace //--------------------------------------------------------------- /** * 将 text 中的 searchString 替换成 replacement. * *

示例:

* *
* *

* A {@code null} reference passed to this method is a no-op. *

* *
     * StringUtil.replace(null, *, *) = null
     * StringUtil.replace("", *, *) = ""
     * StringUtil.replace("any", null, *) = "any"
     * StringUtil.replace("any", *, null) = "any"
     * StringUtil.replace("any", "", *) = "any"
     * StringUtil.replace("aba", "a", null) = "aba"
     * StringUtil.replace("aba", "a", "") = "b"
     * StringUtil.replace("aba", "a", "z") = "zbz"
     * 
     * StringUtil.replace("黑色/黄色/蓝色", "/", "_")         =   "黑色_黄色_蓝色"
     * StringUtil.replace(null, "/", "_")               =   null
     * StringUtil.replace("黑色/黄色/蓝色", "/", null)        =   "黑色/黄色/蓝色"
     * 
* * 此外注意的是: * *
     * StringUtil.replace("SH1265,SH5951", "([a-zA-Z]+[0-9]+)", "'$1'") = SH1265,SH5951
     * 
* * (注意和 {@link #replaceAll(CharSequence, String, String)} 的区别) * *
* *

注意:

*
*
    *
  1. 该替换从字符串的开头朝末尾执行,例如,用 "b" 替换字符串 "aaa" 中的 "aa" 将生成 "ba" 而不是 "ab".
  2. *
  3. 虽然底层调用了{@link java.util.regex.Matcher#replaceAll(String) Matcher.replaceAll()},但是使用了 * {@link java.util.regex.Matcher#quoteReplacement(String) Matcher.quoteReplacement()} 处理了特殊字符
  4. *
*
* * @param text * text to search and replace in, may be null * @param searchString * the String to search for, may be null * @param replacement * the String to replace it with, may be null * @return 如果 text 是null,返回 null
* 如果 searchString 是null,原样返回 text
* 如果 replacement 是null,原样返回 text
* @see java.lang.String#replace(CharSequence, CharSequence) * @see com.feilong.lib.lang3.StringUtils#replace(String, String, String) * @since jdk 1.5 */ public static String replace(final String text,final String searchString,final String replacement){ return StringUtils.replace(text, searchString, replacement); } /** * 使用给定的replacement替换 content 此字符串所有匹配给定的正则表达式 regex的子字符串. * *

说明:

*
*
    *
  1. * 此方法底层调用的是 {@link java.util.regex.Matcher#replaceAll(String)},相同于 * Pattern.compile(regex).matcher(str).replaceAll(repl) *
  2. *
*
* *

示例:

* *
* *
     * StringUtil.replaceAll("SH1265,SH5951,SH6766,SH7235,SH1265,SH5951,SH6766,SH7235", "([a-zA-Z]+[0-9]+)", "'$1'")
     * 
* * 返回: * *
     * 'SH1265','SH5951','SH6766','SH7235','SH1265','SH5951','SH6766','SH7235'
     * 
* *
* *

请注意:

* *
* *

* 在替代字符串replacement中,使用 backslashes反斜杆(\)和 dollar signs美元符号 ($)与将其视为字面值替代字符串所得的结果可能不同. *
* 请参阅 {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll};如有需要,可使用 {@link java.util.regex.Matcher#quoteReplacement * Matcher.quoteReplacement}取消这些字符的特殊含义 *

* *

* $ may be treated as references to captured subsequences as described above,$这个特殊的字符,因为替换串使用这个引用正则表达式匹配的组, * $0代表匹配项,$1代表第1个匹配分组,$1代表第2个匹配分组 *
* 并且 \ are used to escape literal characters in the replacement string.  *

*
* *

对于以下代码:

* *
* *
     * 
     * //分隔字符串并添加引号.
     * public void splitAndAddYinHao(){
     *     String a = "12345,56789,1123456";
     *     String[] aStrings = a.split(",");
     *     StringBuilder sb = new StringBuilder();
     *     int size = aStrings.length;
     *     for (int i = 0; i {@code <} size; i++){
     *         sb.append("'" + aStrings[i] + "'");
     *         if (i != size - 1){
     *             sb.append(",");
     *         }
     *     }
     *     LOGGER.debug(sb.toString());
     * }
     * 
     * 
* * 可以重构成: * *
     * StringUtil.replaceAll("12345,56789,1123456", "([0-9]+)", "'$1'")
     * 
* * 结果都是: * *
     * '12345','56789','1123456'
     * 
* *
* * @param content * 需要被替换的字符串 * @param regex * 用来匹配此字符串的正则表达式,规则参见 RegexPattern 注释 * @param replacement * 用来替换每个匹配项的字符串 * @return 如果 content 是null,返回 {@link StringUtils#EMPTY}
* 如果 content 中,没有 regex匹配的字符串或者格式,返回content
* @see String字符串替换的一个诡异问题 * @see java.lang.String#replaceAll(String, String) * @since jdk 1.4 */ public static String replaceAll(CharSequence content,String regex,String replacement){ return null == content ? EMPTY : content.toString().replaceAll(regex, replacement); } /** * 使用给定的字符串 templateString 作为模板,解析匹配的变量 . * *

示例:

* *
* *
     * String template = "/home/webuser/expressdelivery/${yearMonth}/${expressDeliveryType}/vipQuery_${fileName}.log";
     * Date date = now();
     * 
     * Map{@code } valuesMap = newHashMap();
     * valuesMap.put("yearMonth", DateUtil.toString(date, DatePattern.YEAR_AND_MONTH));
     * valuesMap.put("expressDeliveryType", "sf");
     * valuesMap.put("fileName", DateUtil.toString(date, DatePattern.TIMESTAMP));
     * LOGGER.debug(StringUtil.replace(template, valuesMap));
     * 
* * 返回: * *
     * /home/webuser/expressdelivery/2016-06/sf/vipQuery_20160608214846.log
     * 
* *
* *

* 注意:此方法只能替换字符串,而不能像el表达式一样使用对象属性之类的来替换 *

* *

比如:

* *
* *
     * Map{@code } valuesMap = newHashMap();
     * valuesMap.put("today", DateUtil.toString(now(), COMMON_DATE));
     * valuesMap.put("user", new User(1L));
     * LOGGER.debug(StringUtil.replace("${today}${today1}${user.id}${user}", valuesMap) + "");
     * 
* * 返回: * *
     * 2016-07-16${today1}${user.id}com.feilong.test.User@16f9a31
     * 
* *
* * @param * the value type * @param templateString * the template string * @param valuesMap * the values map * @return 如果 templateStringStringUtils.isEmpty(templateString),返回 {@link StringUtils#EMPTY}
* 如果 valuesMap 是null或者empty,原样返回 templateString
* @see com.feilong.lib.lang3.text.StrSubstitutor#replace(String) * @see com.feilong.lib.lang3.text.StrSubstitutor#replace(Object, Map) * @since 1.1.1 */ public static String replace(CharSequence templateString,Map valuesMap){ return StringUtils.isEmpty(templateString) ? EMPTY : StrSubstitutor.replace(templateString, valuesMap); } // [end] // [start]substring //--------------------------------------------------------------- /** * [截取]从指定索引处(beginIndex)的字符开始,直到此字符串末尾. * *

* 如果 beginIndex是负数,那么表示倒过来截取,从结尾开始截取长度,此时等同于 {@link #substringLast(String, int)} *

* *
     * StringUtil.substring(null, *)   = null
     * StringUtil.substring("", *)     = ""
     * StringUtil.substring("abc", 0)  = "abc"
     * StringUtil.substring("abc", 2)  = "c"
     * StringUtil.substring("abc", 4)  = ""
     * StringUtil.substring("abc", -2) = "bc"
     * StringUtil.substring("abc", -4) = "abc"
     * StringUtil.substring("jinxin.feilong",6)    =.feilong
     * 
* * @param text * 内容 the String to get the substring from, may be null * @param beginIndex * 从指定索引处 the position to start from,negative means count back from the end of the String by this many characters * @return 如果 text 是null,返回 null
* An empty ("") String 返回 "".
* @see com.feilong.lib.lang3.StringUtils#substring(String, int) * @see #substringLast(String, int) */ public static String substring(final String text,final int beginIndex){ return StringUtils.substring(text, beginIndex); } /** * [截取]从开始位置(startIndex),截取固定长度(length)字符串. * *
     * StringUtil.substring(null, 6, 8)                 =   null
     * StringUtil.substring("jinxin.feilong", 6, 2)     =   .f
     * 
* * @param text * 被截取文字 * @param startIndex * 索引开始位置,0开始 * @param length * 长度 {@code >=1} * @return 如果 text 是null,返回 null
* 如果 startIndex + length {@code >} text.length,那么截取 从 startIndex 开始截取,截取到最后 * @see com.feilong.lib.lang3.StringUtils#substring(String, int, int) */ public static String substring(final String text,int startIndex,int length){ return StringUtils.substring(text, startIndex, startIndex + length); } /** * [截取]:获取文字最后位数 lastLenth 的字符串. * *

示例:

* *
* *
     * StringUtil.substringLast("jinxin.feilong", 5) = ilong
     * 
* *
* * @param text * 文字 * @param lastLenth * 最后的位数 * @return 如果 text 是null,返回 null
* 如果 {@code lastLenth<0},返回 {@link StringUtils#EMPTY}
* 如果 {@code text.length() <= lastLenth},返回text
* 否则返回 text.substring(text.length() - lastLenth) * @see com.feilong.lib.lang3.StringUtils#right(String, int) */ public static String substringLast(final String text,int lastLenth){ return StringUtils.right(text, lastLenth); } /** * [截取]:去除最后几位 lastLenth . * *

* 调用了 {@link java.lang.String#substring(int, int)} *

* *

示例:

* *
* *
     * StringUtil.substringWithoutLast("jinxin.feilong", 5) //jinxin.fe
     * 
* *
* * @param text * 文字 * @param lastLenth * 最后的位数 * @return 如果 text 是null,返回 {@link StringUtils#EMPTY}
* @see java.lang.String#substring(int, int) * @see com.feilong.lib.lang3.StringUtils#left(String, int) */ public static String substringWithoutLast(final String text,final int lastLenth){ return null == text ? EMPTY : text.substring(0, text.length() - lastLenth); } /** * [截取]:去除最后的字符串 lastString. * *

示例:

* *
* *
     * StringUtil.substringWithoutLast(null, "222")                     = ""
     * StringUtil.substringWithoutLast("jinxin.feilong", "ng")          = "jinxin.feilo"
     * StringUtil.substringWithoutLast("jinxin.feilong     ", "     ")  = "jinxin.feilong"
     * 
* *
* * @param text * the text * @param lastString * the last string * @return 如果 text 是null,返回 {@link StringUtils#EMPTY}
* 如果 lastString 是null,返回 text.toString()
* @since 1.4.0 */ public static String substringWithoutLast(final CharSequence text,final String lastString){ if (null == text){ return EMPTY; } String textString = text.toString(); if (null == lastString){ return textString; } return textString.endsWith(lastString) ? substringWithoutLast(textString, lastString.length()) : textString; } // [end] // [start]splitToT /** * 将字符串 value 使用分隔符 regexSpliter 分隔成 字符串数组. * *

* 建议使用 {@link #tokenizeToStringArray(String, String)} 或者 {@link StringUtils#split(String)} *

* * @param value * value * @param regexSpliter * 此处不是简单的分隔符,是正则表达式,.$|()[{^?*+\\ 有特殊的含义,因此我们使用.的时候必须进行转义,"\"转义时要写成"\\\\"
* 最终调用了 {@link java.util.regex.Pattern#split(CharSequence)} * @return 如果 value 是null或者empty,返回 {@link ArrayUtil#EMPTY_STRING_ARRAY}
* @see String#split(String) * @see String#split(String, int) * @see StringUtils#split(String) * @see java.util.regex.Pattern#split(CharSequence) */ public static String[] split(String value,String regexSpliter){ return isNullOrEmpty(value) ? EMPTY_STRING_ARRAY : value.split(regexSpliter); } // [end] // [start]tokenizeToStringArray /** * 使用StringTokenizer分隔给定的字符串到字符串数组,去除 tokens的空格并且忽略empty tokens. * *

* (此方法借鉴 "org.springframework.util.StringUtils#tokenizeToStringArray"). *

* *

* 调用了 {@link #tokenizeToStringArray(String, String, boolean, boolean)},本方法默认使用参数 trimTokens = true; * ignoreEmptyTokens = true; *

* *

示例:

*
* *
     * String str = "jin.xin  feilong ,jinxin;venusdrogon;jim ";
     * String delimiters = ";, .";
     * String[] tokenizeToStringArray = StringUtil.tokenizeToStringArray(str, delimiters);
     * LOGGER.info(JsonUtil.format(tokenizeToStringArray));
     * 
* * 返回: * *
     * [
     * "jin",
     * "xin",
     * "feilong",
     * "jinxin",
     * "venusdrogon",
     * "jim"
     * ]
     * 
* *
* *

说明:

* *
*

* 给定的delimiters字符串支持任意数量的分隔字符characters.
* 每一个characters可以用来分隔tokens.一个delimiter分隔符常常是一个single字符;
* 如果你要使用多字符 multi-character delimiters分隔, 你可以考虑使用delimitedListToStringArray *

*
* * @param str * 需要被分隔的字符串 * @param delimiters * delimiter characters, assembled as String
* 参数中的所有字符都是分隔标记的分隔符,比如这里可以设置成 ";, " ,spring就是使用这样的字符串来分隔数组/集合的 * @return 如果 str 是null,返回 {@link ArrayUtil#EMPTY_STRING_ARRAY}
* 如果 str 是blank,返回 {@link ArrayUtil#EMPTY_STRING_ARRAY}
* @see java.util.StringTokenizer * @see String#trim() * @see "org.springframework.util.StringUtils#delimitedListToStringArray" * @see "org.springframework.util.StringUtils#tokenizeToStringArray" * * @see #tokenizeToStringArray(String, String, boolean, boolean) * @since 1.0.7 */ public static String[] tokenizeToStringArray(String str,String delimiters){ boolean trimTokens = true; boolean ignoreEmptyTokens = true; return tokenizeToStringArray(str, delimiters, trimTokens, ignoreEmptyTokens); } /** * 使用StringTokenizer分隔给定的字符串到字符串数组. * *

* (此方法借鉴 "org.springframework.util.StringUtils#tokenizeToStringArray"). *

* *

说明:

* *
*

* 给定的delimiters字符串支持任意数量的分隔字符characters.
* 每一个characters可以用来分隔tokens.一个delimiter分隔符常常是一个single字符;
* 如果你要使用多字符 multi-character delimiters分隔, 你可以考虑使用delimitedListToStringArray *

*
* *

关于 {@link StringTokenizer}:

* *
* * {@link StringTokenizer} implements {@code Enumeration}
* 其在 Enumeration接口的基础上,定义了 hasMoreTokens nextToken两个方法
* 实现的Enumeration接口中的 hasMoreElements nextElement,调用了 hasMoreTokens nextToken
* * * * @param str * 需要被分隔的字符串 * @param delimiters * delimiter characters, assembled as String
* 参数中的所有字符都是分隔标记的分隔符,比如这里可以设置成 ";, " ,spring就是使用这样的字符串来分隔数组/集合的 * @param trimTokens * 是否使用 {@link String#trim()}操作token * @param ignoreEmptyTokens * 是否忽视空白的token,如果为true,那么token必须长度 {@code >} 0;如果为false会包含长度=0 空白的字符
* (仅仅用于那些 trim之后是empty的tokens,StringTokenizer不会考虑subsequent delimiters as token in the first place). * @return 如果 str 是null,返回 {@link ArrayUtil#EMPTY_STRING_ARRAY}
* @see java.util.StringTokenizer * @see String#trim() * @see "org.springframework.util.StringUtils#delimitedListToStringArray" * @see "org.springframework.util.StringUtils#tokenizeToStringArray" * @since 1.0.7 */ public static String[] tokenizeToStringArray(String str,String delimiters,boolean trimTokens,boolean ignoreEmptyTokens){ if (null == str){ return EMPTY_STRING_ARRAY; } List tokens = newArrayList(); StringTokenizer stringTokenizer = new StringTokenizer(str, delimiters); while (stringTokenizer.hasMoreTokens()){ String token = stringTokenizer.nextToken(); token = trimTokens ? token.trim() : token;//去空 if (!ignoreEmptyTokens || token.length() > 0){ tokens.add(token); } } return toArray(tokens, String.class); } // [end] // [start]format /** * 将各类数据,使用{@link String#format(String, Object...)}格式化为字符串. * *

规则:

*
* *
    * *
  1. * *

    * 对整数进行格式化: *

    * *

    * 由4部分组成:%[index$][标识][最小宽度]转换方式 *

    * *

    * 此外,StringUtil.format("%03d", 1) 不能写成 StringUtil.format("%03d", "1") *

    *
  2. * *
  3. *

    * 对浮点数进行格式化: *

    * *

    * %[index$][标识][最少宽度][.精度]转换方式 *

    * *
  4. * *
  5. %index$开头,index从1开始取值,表示将第index个参数拿进来进行格式化.
  6. * *
* *
* *

* 转换符和标志的说明: *

* *

转换符

* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
转换符说明示例
%s字符串类型"mingrisoft"
%c字符类型'm'
%b布尔类型true
%d整数类型(十进制)99
%x整数类型(十六进制)FF
%o整数类型(八进制)77
%f浮点类型99.99
%a十六进制浮点类型FF.35AE
%e指数类型9.38e+5
%g通用浮点类型(f和e类型中较短的)
%h散列码
%%百分比类型
%n换行符
%tx日期与时间类型(x代表不同的日期与时间转换符
*
* *

标志

* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
标志说明示例结果
+为正数或者负数添加符号("%+d",15)+15
-左对齐(不可以与"用0填充"同时使用)("%-5d",15)|15 |
0数字前面补0("%04d", 99)0099
空格在整数之前添加指定数量的空格("% 4d", 99)| 99|
,以","对数字分组("%,f", 9999.99)9,999.990000
(使用括号包含负数("%(f", -99.99)(99.990000)
#如果是浮点数则包含小数点,如果是16进制或8进制则添加0x或0("%#x", 99)
* ("%#o", 99)
0x63
* 0143
{@code <}格式化前一个转换符所描述的参数("%f和%{@code <}3.2f", 99.45)99.450000和99.45
$被格式化的参数索引("%1$d,%2$s", 99,"abc")99,abc
*
* * @param format * the format * @param args * the args * @return 如果 format 是null,返回 {@link StringUtils#EMPTY}
* 如果 format 包含不需要转化的字符串,这些字符串是你写什么,最终就输出什么
* 否则返回 {@link String#format(String, Object...)} * @see java.util.Formatter * @see String#format(String, Object...) * @see String#format(java.util.Locale, String, Object...) * @since JDK 1.5 */ public static String format(String format,Object...args){ return null == format ? EMPTY : String.format(format, args); } // [end] }