Java tutorial
/* * Copyright (C) 2008 feilong (venusdrogon@163.com) * * 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.commons.core.util; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.StrSubstitutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.feilong.commons.core.bean.BeanUtil; import com.feilong.commons.core.bean.BeanUtilException; import com.feilong.commons.core.io.CharsetType; import com.feilong.commons.core.lang.ObjectUtil; /** * StringUtil {@link String},? ,?,format,?16?. * * <h3>(split)</h3> * * <blockquote> * <ul> * <li>{@link #splitToTArray(String, String, Class)}</li> * <li>{@link #splitToStringArray(String, String)}</li> * <li>{@link #splitToIntegerArray(String, String)}</li> * </ul> * </blockquote> * * <h3>(tokenize)</h3> <blockquote> * <ul> * <li>{@link #tokenizeToStringArray(String, String)}</li> * <li>{@link #tokenizeToStringArray(String, String, boolean, boolean)}</li> * </ul> * </blockquote> * * ,split ? {@link Pattern#split(CharSequence)} (?, $|()[{^?*+\\ ???), {@link StringTokenizer} , * StringTokenizer<br> * ,?,{@link StringTokenizer} * * @author 2010-2-9 ?09:53:37 * @see "org.springframework.util.StringUtils#tokenizeToStringArray(String, String)" * @see "org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#MULTI_VALUE_ATTRIBUTE_DELIMITERS" * @see java.util.StringTokenizer * @see org.apache.commons.lang3.StringUtils * @since 1.0.0 */ public final class StringUtil { /** The Constant log. */ private static final Logger log = LoggerFactory.getLogger(StringUtil.class); /** Don't let anyone instantiate this class. */ private StringUtil() { //AssertionError?. ?????. ???. //see Effective Java 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } // [start] search /** * ? * * <pre> * StringUtil.searchTimes("xin", "xin") * return 1 * * StringUtil.searchTimes("xiiiin", "ii") * return 2 * * </pre> * * @param source * ? * @param target * ? * @return count of target string in source * @see org.apache.commons.lang3.StringUtils#countMatches(CharSequence, CharSequence) * @since 1.0.2 * @deprecated {@link org.apache.commons.lang3.StringUtils#countMatches(CharSequence, CharSequence)} */ @Deprecated public static int searchTimes(String source, String target) { if (null == source) { throw new IllegalArgumentException("source can't be null!"); } if (null == target) { throw new IllegalArgumentException("target can't be null!"); } // times int count = 0; // while int j = 0; // ?? int fromIndex = 0; int sourceLength = source.length(); int targetLength = target.length(); // 0 while (j != sourceLength) { // ? int i = source.indexOf(target, fromIndex); if (i != -1) { // ? , // j = i + targetLength; fromIndex = i + targetLength; // ++ count++; } else { // ?? break; } } return count; } // [end] /** * ???<br> * * <pre> * String text = "jinxin.feilong"; * log.info(StringUtil.addDoubleQuotes(text)); * * : "jinxin.feilong" * </pre> * * @param text * ? * @return "\"" + text + "\"" */ public static String addDoubleQuotes(String text) { return "\"" + text + "\""; } /** * ?<br> * * <pre> * StringUtil.join(true, "_", "a", "2") * * return a_2 * </pre> * * @param isJoinBlankOrNull * ?null,true * @param separator * * @param elements * ? * @return the string */ public static final String join(boolean isJoinBlankOrNull, String separator, String... elements) { if (Validator.isNullOrEmpty(elements)) { return null; } StringBuilder stringBuilder = new StringBuilder(); int length = elements.length; for (int i = 0; i < length; ++i) { String string = elements[i]; boolean isCanJoin = true; // null ? ? if (Validator.isNullOrEmpty(string) && !isJoinBlankOrNull) { isCanJoin = false; } if (isCanJoin) { // ???? if (stringBuilder.length() > 0) { stringBuilder.append(separator); } stringBuilder.append(string); } } return stringBuilder.toString(); } /** * ??? jinxin * * return Jinxin * * <pre> * StringUtils.capitalize(null) = null * StringUtils.capitalize("") = "" * StringUtils.capitalize("cat") = "Cat" * StringUtils.capitalize("cAt") = "CAt" * </pre> * * @param word * ?? * @return ??? * @see org.apache.commons.lang3.StringUtils#swapCase(String) * @see org.apache.commons.lang3.StringUtils#capitalize(String) */ public static final String firstCharToUpperCase(String word) { return StringUtils.capitalize(word); } /** * ???? Jinxin * * return jinxin * * <pre> * StringUtils.capitalize(null) = null * StringUtils.capitalize("") = "" * StringUtils.capitalize("Jinxin") = "jinxin" * StringUtils.capitalize("CAt") = "cAt" * </pre> * * @param word * ?? * @return ???? * @see org.apache.commons.lang3.StringUtils#uncapitalize(String) */ public static final String firstCharToLowerCase(String word) { return StringUtils.uncapitalize(word); } // [start]Contain /** * ???. * * @param text * jinxin,?string * @param beIncludedString * ? in * @return ?true,text null false * @see String#indexOf(String) */ public static final boolean isContain(Object text, String beIncludedString) { if (null == text) { log.warn("the param \"text\" is null,default return false"); return false; } int indexOf = text.toString().indexOf(beIncludedString); return indexOf != -1; } /** * ? ??<br> * * <pre> * StringUtil.isContainIgnoreCase(null, "") return false * StringUtil.isContainIgnoreCase(text, null) return false * StringUtil.isContainIgnoreCase(text, "") return true * StringUtil.isContainIgnoreCase(text, "feilong") return true * StringUtil.isContainIgnoreCase(text, "feilong1") return false * StringUtil.isContainIgnoreCase(text, "feiLong") return true * * </pre> * * @param text * the text * @param beIncludedString * the be included string * @return <ul> * <li> null==text, return false</li> * <li> null==beIncludedString, return false</li> * <li> ? ? ,??</li> * </ul> */ public static final boolean isContainIgnoreCase(Object text, String beIncludedString) { if (null == text) { log.warn("the param \"text\" is null,default return false"); return false; } if (null == beIncludedString) { log.warn("the param \"beIncludedString\" is null,default return false"); return false; } return isContain(text.toString().toLowerCase(), beIncludedString.toLowerCase()); } // [end] // [start]replace // ********************************replace************************************************ /** * replacement ????.. * * @param content * ?? * @param regex * ??? * @param replacement * ???? * @return String,?,"" */ public static final String replaceAll(Object content, String regex, String replacement) { if (null == content) { return ""; } return content.toString().replaceAll(regex, replacement); } /** * ????????.<br> * ?? "b" ? "aaa" "aa" ? "ba" ? "ab". * * <pre> * ?replacement * </pre> * * . * * @param content * * @param target * ?? char ? * @param replacement * char ?? * @return ???? */ public static final String replace(Object content, String target, Object replacement) { if (null == content) { return ""; } // ??null if (Validator.isNullOrEmpty(replacement)) { replacement = ""; } return content.toString().replace(target, replacement.toString()); } /** * <code>content</code> ?? <code>target</code> ?? <code>bean</code>? <code>filedName</code> . * * @param content * * @param target * ?? * @param bean * bean * @param filedName * ?? * @return ?,content ??target ??bean?filedName * @throws BeanUtilException * the bean util exception */ public static final String replace(Object content, String target, Object bean, String filedName) throws BeanUtilException { String replacement = ""; // ??null if (Validator.isNotNullOrEmpty(bean)) { Object filedValue = BeanUtil.getProperty(bean, filedName); if (null != filedValue) { replacement = filedValue.toString(); } } return replace(content, target, replacement); } /** * * The following example demonstrates this: * * <pre> * Map valuesMap = HashMap(); * valuesMap.put("animal", "quick brown fox"); * valuesMap.put("target", "lazy dog"); * String templateString = "The ${animal} jumped over the ${target}."; * StrSubstitutor sub = new StrSubstitutor(valuesMap); * String resolvedString = sub.replace(templateString); * </pre> * * yielding: * * <pre> * The quick brown fox jumped over the lazy dog. * </pre> * * @param <V> * the value type * @param templateString * the template string * @param valuesMap * the values map * @return the string * @see org.apache.commons.lang3.text.StrSubstitutor * @since 1.1.1 */ public static final <V> String replace(String templateString, Map<String, V> valuesMap) { StrSubstitutor strSubstitutor = new StrSubstitutor(valuesMap); String resolvedString = strSubstitutor.replace(templateString); return resolvedString; } // [end] // [start]startsWith /** * ??.. * * @param value * value * @param prefix * ? * @return ???? true? false.??? String equals(Object) true. */ public static final boolean startsWith(Object value, String prefix) { return ObjectUtil.toString(value).startsWith(prefix); } // [end] /** * (???). * * @param str * * @param i * * @return (???) */ //TODO +javadoc public static final String stringAddInt(String str, int i) { int length = str.length(); String pattern = ""; for (int j = 0; j < length; ++j) { pattern += "0"; } return NumberUtil.toString(Integer.parseInt(str) + i, pattern); } // [start]substring // ********************************substring************************************************ /** * [?](beginIndex). <br> * text.substring(beginIndex) * * <pre> * substring("jinxin.feilong",6) * * return .feilong * </pre> * * @param text * * @param beginIndex * * @return <ul> * <li> Validator.isNull(t),return null</li> * <li>else,return text.substring(beginIndex)</li> * </ul> */ public static final String substring(Object text, int beginIndex) { String t = ObjectUtil.toString(text); if (Validator.isNullOrEmpty(t)) { return null; } return t.substring(beginIndex); } /** * [?]?(startIndex),?(length)<br> * * <pre> * StringUtil.substring("jinxin.feilong", 6, 2) * * renturn .f * </pre> * * @param textObject * ? * @param startIndex * ?,0 * @param length * {@code >=1} 1 ? <br> * ,?? * @return * <pre> * {@code * Validator.isNullOrEmpty(textValue), return null * startIndex>textLength - 1, return null * startIndex==textLength - 1, return substringLast(textString, 1) * length<1, return null * 1 == length, return textString.substring(startIndex, startIndex + 1) * remainLength > length, return textString.substring(startIndex, startIndex + length) * remainLength <= length, return textString.substring(startIndex) * } * </pre> */ public static final String substring(Object textObject, int startIndex, int length) { String returnValue = null; if (Validator.isNullOrEmpty(textObject)) { return null; } String textString = ObjectUtil.toString(textObject); int textLength = textString.length(); // ?? if (startIndex > textLength - 1) { return null; } else if (startIndex == textLength - 1) {// ?? return substringLast(textString, 1); } else if (length < 1) {// ?>=1 return null; } else if (1 == length) {// ?1 ? // ?? return textString.substring(startIndex, startIndex + 1); } else { // ?? int remainLength = textLength - startIndex; // ? if (remainLength > length) { // ? int endIndex = startIndex + length; // ??? returnValue = textString.substring(startIndex, endIndex); } else { // ?? returnValue = textString.substring(startIndex); } } return returnValue; } /** * [?]:{@link #substring(String, String, int)}, shift=0 * * <pre> * substring("jinxin.feilong",".")======>".feilong" * </pre> * * @param text * text * @param beginString * beginString? * @return {@link #substring(String, String, int)}, shift=0 */ public static final String substring(String text, String beginString) { return substring(text, beginString, 0); } /** * [?]:?(?)??,shift?????,<br> * beginIndex= text.indexOf(beginString) + shift;<br> * return text.substring(beginIndex); * * <pre> * substring("jinxin.feilong",".",0)======>".feilong" * substring("jinxin.feilong",".",1)======>"feilong" * </pre> * * @param text * text * @param beginString * beginString * @param shift * ??,??,0?? * @return <ul> * <li>if isNullOrEmpty(text),return null</li> * <li>if isNullOrEmpty(beginString),return null</li> * <li>if text.indexOf(beginString)==-1,return null</li> * <li>{@code beginIndex + shift > text.length()},return null</li> * <li>else,return text.substring(beginIndex + shift)</li> * </ul> * @throws IllegalArgumentException * {@code if beginIndex + shift<0} * */ public static final String substring(String text, String beginString, int shift) throws IllegalArgumentException { if (Validator.isNullOrEmpty(text)) { return null; } else if (Validator.isNullOrEmpty(beginString)) { return null; } //**************************************************** int beginIndex = text.indexOf(beginString); // ? if (beginIndex == -1) { return null; } //**************************************************** int startIndex = beginIndex + shift; if (startIndex < 0) { String logInfo = StringBuilderUtil.append("beginIndex + shift <0,", "beginIndex:", beginIndex, ",shift:" + shift, ",text:" + text, ",text.length:", text.length()); throw new IllegalArgumentException(logInfo); } else if (startIndex > text.length()) { if (log.isInfoEnabled()) { String logInfo = StringBuilderUtil.append("beginIndex + shift > text.length(),", "beginIndex:", beginIndex, ",shift:" + shift, ",text:" + text, ",text.length:", text.length()); log.info(logInfo); } return null; } // 0 return text.substring(startIndex); } /** * [?]:?(startString),???endString. * * @param text * * @param startString * ,null? * @param endString * ? * @return <pre> * Validator.isNull(text),return null; * Validator.isNull(startString),return text.substring(0, text.indexOf(endString)) * * </pre> */ public static final String substring(String text, String startString, String endString) { if (Validator.isNullOrEmpty(text)) { return null; } else if (Validator.isNullOrEmpty(startString)) { return text.substring(0, text.indexOf(endString)); } int beginIndex = text.indexOf(startString); int endIndex = text.indexOf(endString); return text.substring(beginIndex, endIndex); } /** * [?]:??. * * @param text * * @param lastLenth * ?? * @return ?? */ public static final String substringLast(String text, int lastLenth) { return text.substring(text.length() - lastLenth); } /** * [?]:??. * * @param text * * @param lastLenth * ?? * @return ??,text,"" */ public static final String substringWithoutLast(String text, int lastLenth) { if (Validator.isNullOrEmpty(text)) { return null; } return text.substring(0, text.length() - lastLenth); } // [end] // [start]toBytes // ******************************************************************************** /** * ??byte. * * @param value * * @return byte */ public static final byte[] toBytes(String value) { return value.getBytes(); } /** * ??byte. * * @param value * * @param charsetName * ?? charset ??, utf-8, {@link CharsetType} * @return byte * @see String#getBytes(String) * @see CharsetType */ public static final byte[] toBytes(String value, String charsetName) { try { return value.getBytes(charsetName); } catch (UnsupportedEncodingException e) { log.error(e.getClass().getName(), e); } return null; } // [end] /** * string ?,???. * * @param <T> * the generic type * @param value * * @param class1 * the class1 * @return <pre> * if (class1 == String.class){ * return (T) value; * }else if (class1 == Boolean.class){ * return (T) ObjectUtil.objectToBoolean(value); * }else if (class1 == Integer.class){ * return (T) ObjectUtil.objectToInteger(value); * } * </pre> */ @SuppressWarnings("unchecked") public static final <T> T toT(String value, Class<?> class1) { return (T) ObjectUtil.toT(value, class1); } // [start]splitToT /** * ? . * * @param value * value * @param regexSpliter * ,????, .$|()[{^?*+\\ ??.,<br> * ??"\"??"\\\\"<br> * {@link java.util.regex.Pattern#split(CharSequence)} * @return value null,null * @see String#split(String) * @see String#split(String, int) * @see java.util.regex.Pattern#split(CharSequence) */ public static final String[] splitToStringArray(String value, String regexSpliter) { if (null != value) { String[] strings = value.split(regexSpliter); return strings; } return null; } /** * ? . * * @param value * value * @param regexSpliter * ,????, .$|()[{^?*+\\ ??.,<br> * ??"\"??"\\\\"<br> * {@link java.util.regex.Pattern#split(CharSequence)} * @return value null,null * @see String#split(String) * @see String#split(String, int) * @see ArrayUtil#toIntegers(Object[]) * @see java.util.regex.Pattern#split(CharSequence) */ public static final Integer[] splitToIntegerArray(String value, String regexSpliter) { if (null != value) { String[] strings = value.split(regexSpliter); return ArrayUtil.toIntegers(strings); } return null; } /** * ?T. * * @param <T> * the generic type * @param value * * @param regexSpliter * ,????, .$|()[{^?*+\\ ??.,<br> * ??"\"??"\\\\"<br> * {@link java.util.regex.Pattern#split(CharSequence)} * @param typeClass * , T <br> * Temp support only:String.class and Integer.class * @return * @throws IllegalArgumentException * ??String Integer?, * @see java.util.regex.Pattern#split(CharSequence) * @see #splitToIntegerArray(String, String) * @see #splitToStringArray(String, String) */ @SuppressWarnings("unchecked") public static final <T> T[] splitToTArray(String value, String regexSpliter, Class<?> typeClass) throws IllegalArgumentException { if (typeClass == String.class) { return (T[]) splitToStringArray(value, regexSpliter); } else if (typeClass == Integer.class) { return (T[]) splitToIntegerArray(value, regexSpliter); } throw new IllegalArgumentException( "Param typeClass don't support,Temp support only:String.class and Integer.class"); } // [end] // [start]tokenizeToStringArray /** * ( {@link "org.springframework.util.StringUtils#tokenizeToStringArray"})<br> * Tokenize the given String into a String array via a StringTokenizer. * Trims tokens and omits empty tokens. * <p> * The given delimiters string is supposed to consist of any number of delimiter characters. Each of those characters can be used to * separate tokens. A delimiter is always a single character; for multi-character delimiters, consider using * {@code delimitedListToStringArray} * * @param str * the String to tokenize * @param delimiters * the delimiter characters, assembled as String<br> * ?,?? ";, " ,spring?/? * @return an array of the tokens * @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 = true; boolean ignoreEmptyTokens = true; return tokenizeToStringArray(str, delimiters, trimTokens, ignoreEmptyTokens); } /** * ( {@link "org.springframework.util.StringUtils#tokenizeToStringArray"})<br> * Tokenize the given String into a String array via a StringTokenizer. * <p> * The given delimiters string is supposed to consist of any number of delimiter characters. <br> * Each of those characters can be used to separate tokens. <br> * A delimiter is always a single character; <br> * for multi-character delimiters, consider using {@code delimitedListToStringArray} * * @param str * the String to tokenize * @param delimiters * the delimiter characters, assembled as String<br> * ?,?? ";, " ,spring?/? * @param trimTokens * ? {@link String#trim()}?token * @param ignoreEmptyTokens * ?token,true,token>0;false?=0 <br> * omit empty tokens from the result array * (only applies to tokens that are empty after trimming; StringTokenizer * will not consider subsequent delimiters as token in the first place). * @return an array of the tokens ({@code null} if the input String * was {@code null}) * @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 (str == null) { return null; } //StringTokenizer implements Enumeration<Object> // Enumeration?, hasMoreTokens nextToken //Enumeration? hasMoreElements nextElement hasMoreTokens nextToken StringTokenizer st = new StringTokenizer(str, delimiters); List<String> tokens = new ArrayList<String>(); while (st.hasMoreTokens()) { String token = st.nextToken(); if (trimTokens) { token = token.trim(); } if (!ignoreEmptyTokens || token.length() > 0) { tokens.add(token); } } return CollectionsUtil.toArray(tokens); } // [end] // [start]format /** * ? * <ul> * <li>StringUtil.format("%03d", 1)?? StringUtil.format("%03d", "1")</li> * </ul> * %index$index1?index???.<br> * ?:?4?:%[index$][][?]??<br> * ?:%[index$][][][.]??<br> * ?? ?<br> * * <h3>?</h3> * * <pre> * %s "mingrisoft" * %c 'm' * %b true * %d ?? 99 * %x ?? FF * %o 77 * %f 99.99 * %a ?? FF.35AE * %e 9.38e+5 * %g fe * %h ? * %% * %n ? * %tx x??? * </pre> * * <h3></h3> * * <pre> * {@code * + ? ("%+d",15) +15 * - ? ("%-5d",15) |15 | ??0?? * 0 ??0 ("%04d", 99) 0099 * ?? ("% 4d", 99) | 99| * , ,? ("%,f", 9999.99) 9,999.990000 * ( ?? ("%(f", -99.99) (99.990000) * # ??1680x0 * < ?????? ("%f%<3.2f", 99.45) 99.45000099.45 * $ ?? ("%1$d,%2$s", 99,"abc") 99,abc * } * </pre> * * @param format * the format * @param args * the args * @return A formatted string * @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 String.format(format, args); } // [end] // [start]toHexStringUpperCase/toOriginal /** * ? HexString ?gdpglc?. * * @param original * * @return the string */ public static final String toHexStringUpperCase(String original) { // Charset.defaultCharset() ISO-8859-1 String hexStringUpperCase = ByteUtil.bytesToHexStringUpperCase(original.getBytes()); log.debug("original:{},hexStringUpperCase:{}", original, hexStringUpperCase); return hexStringUpperCase; } /** * ? HexString ?gdpglc?. * * @param original * * @param charsetName * {@link CharsetType} * @return the string */ public static final String toHexStringUpperCase(String original, String charsetName) { try { String hexStringUpperCase = ByteUtil.bytesToHexStringUpperCase(original.getBytes(charsetName)); log.debug("original:{},hexStringUpperCase:{}", original, hexStringUpperCase); return hexStringUpperCase; } catch (UnsupportedEncodingException e) { log.error(e.getClass().getName(), e); } return null; } /** * ? HexString. * * @param hexStringUpperCase * HexString * @return the string */ public static final String toOriginal(String hexStringUpperCase) { byte[] hexBytesToBytes = ByteUtil.hexBytesToBytes(hexStringUpperCase.getBytes()); String original = new String(hexBytesToBytes); log.debug("hexStringUpperCase:{},original:{}", hexStringUpperCase, original); return original; } /** * ? HexString. * * @param hexStringUpperCase * the hex string upper case * @param charsetName * * @return the string */ public static final String toOriginal(String hexStringUpperCase, String charsetName) { byte[] hexBytesToBytes = ByteUtil.hexBytesToBytes(hexStringUpperCase.getBytes()); String original = null; try { original = new String(hexBytesToBytes, charsetName); } catch (UnsupportedEncodingException e) { log.error(e.getClass().getName(), e); } log.debug("hexStringUpperCase:{},original:{}", hexStringUpperCase, original); return original; } // [end] }