这个类是spring的工具类,用于一些常用的字符串处理,但是这些方法不在jdk的String中。
know more about this class,write less code.
apache中的commmons lang中也有一个StringUtils,比spring中这个功能更全面。
下面是我把方法声明以及部分实现摘抄下来。
The result is convenient for path comparison. For other uses, This is the inverse operation of {@link Locale#toString Locale's toString}. The order of elements in the original arrays is preserved. The order of elements in the original arrays is preserved Will trim both the key and value before adding them to the Will trim both the key and value before adding them to the The given delimiters string is supposed to consist of any number of The given delimiters string is supposed to consist of any number of A single delimiter can consists of more than one character: It will still A single delimiter can consists of more than one character: It will still
* notice that Windows separators ("\") are replaced by simple slashes.
* @param path the original path
* @return the normalized path
*/
public static String cleanPath(String path) {
if (path == null) {
return null;
}
String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);
// Strip prefix from path to analyze, to not treat it as part of the
// first path element. This is necessary to correctly parse paths like
// "file:core/../core/io/Resource.class", where the ".." should just
// strip the first "core" directory while keeping the "file:" prefix.
int prefixIndex = pathToUse.indexOf(":");
String prefix = "";
if (prefixIndex != -1) {
prefix = pathToUse.substring(0, prefixIndex + 1);
pathToUse = pathToUse.substring(prefixIndex + 1);
}
if (pathToUse.startsWith(FOLDER_SEPARATOR)) {
prefix = prefix + FOLDER_SEPARATOR;
pathToUse = pathToUse.substring(1);
}
String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR);
List
int tops = 0;
for (int i = pathArray.length - 1; i >= 0; i--) {
String element = pathArray[i];
if (CURRENT_PATH.equals(element)) {
// Points to current directory - drop it.
}
else if (TOP_PATH.equals(element)) {
// Registering top path found.
tops++;
}
else {
if (tops > 0) {
// Merging path element with element corresponding to top path.
tops--;
}
else {
// Normal path element found.
pathElements.add(0, element);
}
}
}
// Remaining top paths need to be retained.
for (int i = 0; i < tops; i++) {
pathElements.add(0, TOP_PATH);
}
return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR);
}
/**
* Compare two paths after normalization of them.
* @param path1 first path for comparison
* @param path2 second path for comparison
* @return whether the two paths are equivalent after normalization
*/
public static boolean pathEquals(String path1, String path2) {
return cleanPath(path1).equals(cleanPath(path2));
}
/**
* Parse the given {@code localeString} value into a {@link Locale}.
*
* @param localeString the locale string, following {@code Locale's}
* {@code toString()} format ("en", "en_UK", etc);
* also accepts spaces as separators, as an alternative to underscores
* @return a corresponding {@code Locale} instance
*/
public static Locale parseLocaleString(String localeString) {
String[] parts = tokenizeToStringArray(localeString, "_ ", false, false);
String language = (parts.length > 0 ? parts[0] : "");
String country = (parts.length > 1 ? parts[1] : "");
validateLocalePart(language);
validateLocalePart(country);
String variant = "";
if (parts.length >= 2) {
// There is definitely a variant, and it is everything after the country
// code sans the separator between the country code and the variant.
int endIndexOfCountryCode = localeString.lastIndexOf(country) + country.length();
// Strip off any leading '_' and whitespace, what's left is the variant.
variant = trimLeadingWhitespace(localeString.substring(endIndexOfCountryCode));
if (variant.startsWith("_")) {
variant = trimLeadingCharacter(variant, '_');
}
}
return (language.length() > 0 ? new Locale(language, country, variant) : null);
}
private static void validateLocalePart(String localePart) {
for (int i = 0; i < localePart.length(); i++) {
char ch = localePart.charAt(i);
if (ch != '_' && ch != ' ' && !Character.isLetterOrDigit(ch)) {
throw new IllegalArgumentException(
"Locale part \"" + localePart + "\" contains invalid characters");
}
}
}
/**
* Determine the RFC 3066 compliant language tag,
* as used for the HTTP "Accept-Language" header.
* @param locale the Locale to transform to a language tag
* @return the RFC 3066 compliant language tag as String
*/
public static String toLanguageTag(Locale locale) {
return locale.getLanguage() + (hasText(locale.getCountry()) ? "-" + locale.getCountry() : "");
}
//---------------------------------------------------------------------
// Convenience methods for working with String arrays
//---------------------------------------------------------------------
/**
* Append the given String to the given String array, returning a new array
* consisting of the input array contents plus the given String.
* @param array the array to append to (can be {@code null})
* @param str the String to append
* @return the new array (never {@code null})
*/
public static String[] addStringToArray(String[] array, String str) {
if (ObjectUtils.isEmpty(array)) {
return new String[] {str};
}
String[] newArr = new String[array.length + 1];
System.arraycopy(array, 0, newArr, 0, array.length);
newArr[array.length] = str;
return newArr;
}
/**
* Concatenate the given String arrays into one,
* with overlapping array elements included twice.
*
* @param array1 the first array (can be {@code null})
* @param array2 the second array (can be {@code null})
* @return the new array ({@code null} if both given arrays were {@code null})
*/
public static String[] concatenateStringArrays(String[] array1, String[] array2) {
if (ObjectUtils.isEmpty(array1)) {
return array2;
}
if (ObjectUtils.isEmpty(array2)) {
return array1;
}
String[] newArr = new String[array1.length + array2.length];
System.arraycopy(array1, 0, newArr, 0, array1.length);
System.arraycopy(array2, 0, newArr, array1.length, array2.length);
return newArr;
}
/**
* Merge the given String arrays into one, with overlapping
* array elements only included once.
*
* (with the exception of overlapping elements, which are only
* included on their first occurrence).
* @param array1 the first array (can be {@code null})
* @param array2 the second array (can be {@code null})
* @return the new array ({@code null} if both given arrays were {@code null})
*/
public static String[] mergeStringArrays(String[] array1, String[] array2) {
if (ObjectUtils.isEmpty(array1)) {
return array2;
}
if (ObjectUtils.isEmpty(array2)) {
return array1;
}
List
result.addAll(Arrays.asList(array1));
for (String str : array2) {
if (!result.contains(str)) {
result.add(str);
}
}
return toStringArray(result);
}
/**
* Turn given source String array into sorted array.
* @param array the source array
* @return the sorted array (never {@code null})
*/
public static String[] sortStringArray(String[] array) {
if (ObjectUtils.isEmpty(array)) {
return new String[0];
}
Arrays.sort(array);
return array;
}
/**
* Copy the given Collection into a String array.
* The Collection must contain String elements only.
* @param collection the Collection to copy
* @return the String array ({@code null} if the passed-in
* Collection was {@code null})
*/
public static String[] toStringArray(Collection
if (collection == null) {
return null;
}
return collection.toArray(new String[collection.size()]);
}
/**
* Copy the given Enumeration into a String array.
* The Enumeration must contain String elements only.
* @param enumeration the Enumeration to copy
* @return the String array ({@code null} if the passed-in
* Enumeration was {@code null})
*/
public static String[] toStringArray(Enumeration
if (enumeration == null) {
return null;
}
List
return list.toArray(new String[list.size()]);
}
/**
* Trim the elements of the given String array,
* calling {@code String.trim()} on each of them.
* @param array the original String array
* @return the resulting array (of the same size) with trimmed elements
*/
public static String[] trimArrayElements(String[] array) {
if (ObjectUtils.isEmpty(array)) {
return new String[0];
}
String[] result = new String[array.length];
for (int i = 0; i < array.length; i++) {
String element = array[i];
result[i] = (element != null ? element.trim() : null);
}
return result;
}
/**
* Remove duplicate Strings from the given array.
* Also sorts the array, as it uses a TreeSet.
* @param array the String array
* @return an array without duplicates, in natural sort order
*/
public static String[] removeDuplicateStrings(String[] array) {
if (ObjectUtils.isEmpty(array)) {
return array;
}
Set
for (String element : array) {
set.add(element);
}
return toStringArray(set);
}
/**
* Split a String at the first occurrence of the delimiter.
* Does not include the delimiter in the result.
* @param toSplit the string to split
* @param delimiter to split the string up with
* @return a two element array with index 0 being before the delimiter, and
* index 1 being after the delimiter (neither element includes the delimiter);
* or {@code null} if the delimiter wasn't found in the given input String
*/
public static String[] split(String toSplit, String delimiter) {
if (!hasLength(toSplit) || !hasLength(delimiter)) {
return null;
}
int offset = toSplit.indexOf(delimiter);
if (offset < 0) {
return null;
}
String beforeDelimiter = toSplit.substring(0, offset);
String afterDelimiter = toSplit.substring(offset + delimiter.length());
return new String[] {beforeDelimiter, afterDelimiter};
}
/**
* Take an array Strings and split each element based on the given delimiter.
* A {@code Properties} instance is then generated, with the left of the
* delimiter providing the key, and the right of the delimiter providing the value.
*
* {@code Properties} instance.
* @param array the array to process
* @param delimiter to split each element using (typically the equals symbol)
* @return a {@code Properties} instance representing the array contents,
* or {@code null} if the array to process was null or empty
*/
public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter) {
return splitArrayElementsIntoProperties(array, delimiter, null);
}
/**
* Take an array Strings and split each element based on the given delimiter.
* A {@code Properties} instance is then generated, with the left of the
* delimiter providing the key, and the right of the delimiter providing the value.
*
* {@code Properties} instance.
* @param array the array to process
* @param delimiter to split each element using (typically the equals symbol)
* @param charsToDelete one or more characters to remove from each element
* prior to attempting the split operation (typically the quotation mark
* symbol), or {@code null} if no removal should occur
* @return a {@code Properties} instance representing the array contents,
* or {@code null} if the array to process was {@code null} or empty
*/
public static Properties splitArrayElementsIntoProperties(
String[] array, String delimiter, String charsToDelete) {
if (ObjectUtils.isEmpty(array)) {
return null;
}
Properties result = new Properties();
for (String element : array) {
if (charsToDelete != null) {
element = deleteAny(element, charsToDelete);
}
String[] splittedElement = split(element, delimiter);
if (splittedElement == null) {
continue;
}
result.setProperty(splittedElement[0].trim(), splittedElement[1].trim());
}
return result;
}
/**
* Tokenize the given String into a String array via a StringTokenizer.
* Trims tokens and omits empty tokens.
*
* 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
* (each of those characters is individually considered as delimiter).
* @return an array of the tokens
* @see java.util.StringTokenizer
* @see String#trim()
* @see #delimitedListToStringArray
*/
public static String[] tokenizeToStringArray(String str, String delimiters) {
return tokenizeToStringArray(str, delimiters, true, true);
}
/**
* Tokenize the given String into a String array via a StringTokenizer.
*
* 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
* (each of those characters is individually considered as delimiter)
* @param trimTokens trim the tokens via String's {@code trim}
* @param ignoreEmptyTokens 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 #delimitedListToStringArray
*/
public static String[] tokenizeToStringArray(
String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
if (str == null) {
return null;
}
StringTokenizer st = new StringTokenizer(str, delimiters);
List
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (trimTokens) {
token = token.trim();
}
if (!ignoreEmptyTokens || token.length() > 0) {
tokens.add(token);
}
}
return toStringArray(tokens);
}
/**
* Take a String which is a delimited list and convert it to a String array.
*
* be considered as single delimiter string, rather than as bunch of potential
* delimiter characters - in contrast to {@code tokenizeToStringArray}.
* @param str the input String
* @param delimiter the delimiter between elements (this is a single delimiter,
* rather than a bunch individual delimiter characters)
* @return an array of the tokens in the list
* @see #tokenizeToStringArray
*/
public static String[] delimitedListToStringArray(String str, String delimiter) {
return delimitedListToStringArray(str, delimiter, null);
}
/**
* Take a String which is a delimited list and convert it to a String array.
*
* be considered as single delimiter string, rather than as bunch of potential
* delimiter characters - in contrast to {@code tokenizeToStringArray}.
* @param str the input String
* @param delimiter the delimiter between elements (this is a single delimiter,
* rather than a bunch individual delimiter characters)
* @param charsToDelete a set of characters to delete. Useful for deleting unwanted
* line breaks: e.g. "\r\n\f" will delete all new lines and line feeds in a String.
* @return an array of the tokens in the list
* @see #tokenizeToStringArray
*/
public static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) {
if (str == null) {
return new String[0];
}
if (delimiter == null) {
return new String[] {str};
}
List
if ("".equals(delimiter)) {
for (int i = 0; i < str.length(); i++) {
result.add(deleteAny(str.substring(i, i + 1), charsToDelete));
}
}
else {
int pos = 0;
int delPos;
while ((delPos = str.indexOf(delimiter, pos)) != -1) {
result.add(deleteAny(str.substring(pos, delPos), charsToDelete));
pos = delPos + delimiter.length();
}
if (str.length() > 0 && pos <= str.length()) {
// Add rest of String, but not in case of empty input.
result.add(deleteAny(str.substring(pos), charsToDelete));
}
}
return toStringArray(result);
}
/**
* Convert a CSV list into an array of Strings.
* @param str the input String
* @return an array of Strings, or the empty array in case of empty input
*/
public static String[] commaDelimitedListToStringArray(String str) {
return delimitedListToStringArray(str, ",");
}
/**
* Convenience method to convert a CSV string list to a set.
* Note that this will suppress duplicates.
* @param str the input String
* @return a Set of String entries in the list
*/
public static Set
Set
String[] tokens = commaDelimitedListToStringArray(str);
for (String token : tokens) {
set.add(token);
}
return set;
}
/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for {@code toString()} implementations.
* @param coll the Collection to display
* @param delim the delimiter to use (probably a ",")
* @param prefix the String to start each element with
* @param suffix the String to end each element with
* @return the delimited String
*/
public static String collectionToDelimitedString(Collection> coll, String delim, String prefix, String suffix) {
if (CollectionUtils.isEmpty(coll)) {
return "";
}
StringBuilder sb = new StringBuilder();
Iterator> it = coll.iterator();
while (it.hasNext()) {
sb.append(prefix).append(it.next()).append(suffix);
if (it.hasNext()) {
sb.append(delim);
}
}
return sb.toString();
}
/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for {@code toString()} implementations.
* @param coll the Collection to display
* @param delim the delimiter to use (probably a ",")
* @return the delimited String
*/
public static String collectionToDelimitedString(Collection> coll, String delim) {
return collectionToDelimitedString(coll, delim, "", "");
}
/**
* Convenience method to return a Collection as a CSV String.
* E.g. useful for {@code toString()} implementations.
* @param coll the Collection to display
* @return the delimited String
*/
public static String collectionToCommaDelimitedString(Collection> coll) {
return collectionToDelimitedString(coll, ",");
}
将字符串转换成用指定分割符分割的格式
public static String arrayToDelimitedString(Object[] arr, String delim) {
if (ObjectUtils.isEmpty(arr)) {
return "";
}
if (arr.length == 1) {
return ObjectUtils.nullSafeToString(arr[0]);
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i > 0) {
sb.append(delim);
}
sb.append(arr[i]);
}
return sb.toString();
}
Convenience method to return a String array as a CSV String.
将数组转制成CSV格式,CSV即common separated value,就是以逗号分割的格式啦,跟js里面的join(",")是一样的效果的。
public static String arrayToCommaDelimitedString(Object[] arr) {
return arrayToDelimitedString(arr, ",");
}
}