/* lang/tags/LANG_3_2_1/src/main/java/org/apache/commons/lang3/StringUtils.java
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.commons.lang3;
import java.util.Iterator;
/**
* <p>Operations on {@link java.lang.String} that are
* {@code null} safe.</p>
*
* <ul>
* <li><b>IsEmpty/IsBlank</b>
* - checks if a String contains text</li>
* <li><b>Trim/Strip</b>
* - removes leading and trailing whitespace</li>
* <li><b>Equals</b>
* - compares two strings null-safe</li>
* <li><b>startsWith</b>
* - check if a String starts with a prefix null-safe</li>
* <li><b>endsWith</b>
* - check if a String ends with a suffix null-safe</li>
* <li><b>IndexOf/LastIndexOf/Contains</b>
* - null-safe index-of checks
* <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b>
* - index-of any of a set of Strings</li>
* <li><b>ContainsOnly/ContainsNone/ContainsAny</b>
* - does String contains only/none/any of these characters</li>
* <li><b>Substring/Left/Right/Mid</b>
* - null-safe substring extractions</li>
* <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b>
* - substring extraction relative to other strings</li>
* <li><b>Split/Join</b>
* - splits a String into an array of substrings and vice versa</li>
* <li><b>Remove/Delete</b>
* - removes part of a String</li>
* <li><b>Replace/Overlay</b>
* - Searches a String and replaces one String with another</li>
* <li><b>Chomp/Chop</b>
* - removes the last part of a String</li>
* <li><b>AppendIfMissing</b>
* - appends a suffix to the end of the String if not present</li>
* <li><b>PrependIfMissing</b>
* - prepends a prefix to the start of the String if not present</li>
* <li><b>LeftPad/RightPad/Center/Repeat</b>
* - pads a String</li>
* <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b>
* - changes the case of a String</li>
* <li><b>CountMatches</b>
* - counts the number of occurrences of one String in another</li>
* <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b>
* - checks the characters in a String</li>
* <li><b>DefaultString</b>
* - protects against a null input String</li>
* <li><b>Reverse/ReverseDelimited</b>
* - reverses a String</li>
* <li><b>Abbreviate</b>
* - abbreviates a string using ellipsis</li>
* <li><b>Difference</b>
* - compares Strings and reports on their differences</li>
* <li><b>LevenshteinDistance</b>
* - the number of changes needed to change one String into another</li>
* </ul>
*
* <p>The {@code StringUtils} class defines certain words related to
* String handling.</p>
*
* <ul>
* <li>null - {@code null}</li>
* <li>empty - a zero-length string ({@code ""})</li>
* <li>space - the space character ({@code ' '}, char 32)</li>
* <li>whitespace - the characters defined by {@link Character#isWhitespace(char)}</li>
* <li>trim - the characters <= 32 as in {@link String#trim()}</li>
* </ul>
*
* <p>{@code StringUtils} handles {@code null} input Strings quietly.
* That is to say that a {@code null} input will return {@code null}.
* Where a {@code boolean} or {@code int} is being returned
* details vary by method.</p>
*
* <p>A side effect of the {@code null} handling is that a
* {@code NullPointerException} should be considered a bug in
* {@code StringUtils}.</p>
*
* <p>Methods in this class give sample code to explain their operation.
* The symbol {@code *} is used to indicate any input including {@code null}.</p>
*
* <p>#ThreadSafe#</p>
* @see java.lang.String
* @since 1.0
* @version $Id$
*/
//@Immutable
public class StringUtils {
/**
* The empty String {@code ""}.
* @since 2.0
*/
public static final String EMPTY = "";
// Joining
//-----------------------------------------------------------------------
/**
* <p>Joins the elements of the provided array into a single String
* containing the provided list of elements.</p>
*
* <p>No separator is added to the joined String.
* Null objects or empty strings within the array are represented by
* empty strings.</p>
*
* <pre>
* StringUtils.join(null) = null
* StringUtils.join([]) = ""
* StringUtils.join([null]) = ""
* StringUtils.join(["a", "b", "c"]) = "abc"
* StringUtils.join([null, "", "a"]) = "a"
* </pre>
*
* @param <T> the specific type of values to join together
* @param elements the values to join together, may be null
* @return the joined String, {@code null} if null array input
* @since 2.0
* @since 3.0 Changed signature to use varargs
*/
public static <T> String join(final T... elements) {
return join(elements, null);
}
/**
* <p>Joins the elements of the provided array into a single String
* containing the provided list of elements.</p>
*
* <p>No delimiter is added before or after the list.
* Null objects or empty strings within the array are represented by
* empty strings.</p>
*
* <pre>
* StringUtils.join(null, *) = null
* StringUtils.join([], *) = ""
* StringUtils.join([null], *) = ""
* StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
* StringUtils.join(["a", "b", "c"], null) = "abc"
* StringUtils.join([null, "", "a"], ';') = ";;a"
* </pre>
*
* @param array the array of values to join together, may be null
* @param separator the separator character to use
* @return the joined String, {@code null} if null array input
* @since 2.0
*/
public static String join(final Object[] array, final char separator) {
if (array == null) {
return null;
}
return join(array, separator, 0, array.length);
}
/**
* <p>Joins the elements of the provided array into a single String
* containing the provided list of elements.</p>
*
* <p>No delimiter is added before or after the list.
* Null objects or empty strings within the array are represented by
* empty strings.</p>
*
* <pre>
* StringUtils.join(null, *) = null
* StringUtils.join([], *) = ""
* StringUtils.join([null], *) = ""
* StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
* StringUtils.join(["a", "b", "c"], null) = "abc"
* StringUtils.join([null, "", "a"], ';') = ";;a"
* </pre>
*
* @param array the array of values to join together, may be null
* @param separator the separator character to use
* @param startIndex the first index to start joining from. It is
* an error to pass in an end index past the end of the array
* @param endIndex the index to stop joining from (exclusive). It is
* an error to pass in an end index past the end of the array
* @return the joined String, {@code null} if null array input
* @since 2.0
*/
public static String join(final Object[] array, final char separator, final int startIndex, final int endIndex) {
if (array == null) {
return null;
}
final int noOfItems = endIndex - startIndex;
if (noOfItems <= 0) {
return EMPTY;
}
final StringBuilder buf = new StringBuilder(noOfItems * 16);
for (int i = startIndex; i < endIndex; i++) {
if (i > startIndex) {
buf.append(separator);
}
if (array[i] != null) {
buf.append(array[i]);
}
}
return buf.toString();
}
/**
* <p>Joins the elements of the provided array into a single String
* containing the provided list of elements.</p>
*
* <p>No delimiter is added before or after the list.
* A {@code null} separator is the same as an empty String ("").
* Null objects or empty strings within the array are represented by
* empty strings.</p>
*
* <pre>
* StringUtils.join(null, *) = null
* StringUtils.join([], *) = ""
* StringUtils.join([null], *) = ""
* StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
* StringUtils.join(["a", "b", "c"], null) = "abc"
* StringUtils.join(["a", "b", "c"], "") = "abc"
* StringUtils.join([null, "", "a"], ',') = ",,a"
* </pre>
*
* @param array the array of values to join together, may be null
* @param separator the separator character to use, null treated as ""
* @return the joined String, {@code null} if null array input
*/
public static String join(final Object[] array, final String separator) {
if (array == null) {
return null;
}
return join(array, separator, 0, array.length);
}
/**
* <p>Joins the elements of the provided array into a single String
* containing the provided list of elements.</p>
*
* <p>No delimiter is added before or after the list.
* A {@code null} separator is the same as an empty String ("").
* Null objects or empty strings within the array are represented by
* empty strings.</p>
*
* <pre>
* StringUtils.join(null, *, *, *) = null
* StringUtils.join([], *, *, *) = ""
* StringUtils.join([null], *, *, *) = ""
* StringUtils.join(["a", "b", "c"], "--", 0, 3) = "a--b--c"
* StringUtils.join(["a", "b", "c"], "--", 1, 3) = "b--c"
* StringUtils.join(["a", "b", "c"], "--", 2, 3) = "c"
* StringUtils.join(["a", "b", "c"], "--", 2, 2) = ""
* StringUtils.join(["a", "b", "c"], null, 0, 3) = "abc"
* StringUtils.join(["a", "b", "c"], "", 0, 3) = "abc"
* StringUtils.join([null, "", "a"], ',', 0, 3) = ",,a"
* </pre>
*
* @param array the array of values to join together, may be null
* @param separator the separator character to use, null treated as ""
* @param startIndex the first index to start joining from.
* @param endIndex the index to stop joining from (exclusive).
* @return the joined String, {@code null} if null array input; or the empty string
* if {@code endIndex - startIndex <= 0}. The number of joined entries is given by
* {@code endIndex - startIndex}
* @throws ArrayIndexOutOfBoundsException ife<br/>
* {@code startIndex < 0} or <br/>
* {@code startIndex >= array.length()} or <br/>
* {@code endIndex < 0} or <br/>
* {@code endIndex > array.length()}
*/
public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) {
if (array == null) {
return null;
}
if (separator == null) {
separator = EMPTY;
}
// endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator))
// (Assuming that all Strings are roughly equally long)
final int noOfItems = endIndex - startIndex;
if (noOfItems <= 0) {
return EMPTY;
}
final StringBuilder buf = new StringBuilder(noOfItems * 16);
for (int i = startIndex; i < endIndex; i++) {
if (i > startIndex) {
buf.append(separator);
}
if (array[i] != null) {
buf.append(array[i]);
}
}
return buf.toString();
}
/**
* <p>Joins the elements of the provided {@code Iterator} into
* a single String containing the provided elements.</p>
*
* <p>No delimiter is added before or after the list. Null objects or empty
* strings within the iteration are represented by empty strings.</p>
*
* <p>See the examples here: {@link #join(Object[],char)}. </p>
*
* @param iterator the {@code Iterator} of values to join together, may be null
* @param separator the separator character to use
* @return the joined String, {@code null} if null iterator input
* @since 2.0
*/
public static String join(final Iterator<?> iterator, final char separator) {
// handle null, zero and one elements before building a buffer
if (iterator == null) {
return null;
}
if (!iterator.hasNext()) {
return EMPTY;
}
final Object first = iterator.next();
if (!iterator.hasNext()) {
return ObjectUtils.toString(first);
}
// two or more elements
final StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
if (first != null) {
buf.append(first);
}
while (iterator.hasNext()) {
buf.append(separator);
final Object obj = iterator.next();
if (obj != null) {
buf.append(obj);
}
}
return buf.toString();
}
/**
* <p>Joins the elements of the provided {@code Iterator} into
* a single String containing the provided elements.</p>
*
* <p>No delimiter is added before or after the list.
* A {@code null} separator is the same as an empty String ("").</p>
*
* <p>See the examples here: {@link #join(Object[],String)}. </p>
*
* @param iterator the {@code Iterator} of values to join together, may be null
* @param separator the separator character to use, null treated as ""
* @return the joined String, {@code null} if null iterator input
*/
public static String join(final Iterator<?> iterator, final String separator) {
// handle null, zero and one elements before building a buffer
if (iterator == null) {
return null;
}
if (!iterator.hasNext()) {
return EMPTY;
}
final Object first = iterator.next();
if (!iterator.hasNext()) {
return ObjectUtils.toString(first);
}
// two or more elements
final StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
if (first != null) {
buf.append(first);
}
while (iterator.hasNext()) {
if (separator != null) {
buf.append(separator);
}
final Object obj = iterator.next();
if (obj != null) {
buf.append(obj);
}
}
return buf.toString();
}
/**
* <p>Joins the elements of the provided {@code Iterable} into
* a single String containing the provided elements.</p>
*
* <p>No delimiter is added before or after the list. Null objects or empty
* strings within the iteration are represented by empty strings.</p>
*
* <p>See the examples here: {@link #join(Object[],char)}. </p>
*
* @param iterable the {@code Iterable} providing the values to join together, may be null
* @param separator the separator character to use
* @return the joined String, {@code null} if null iterator input
* @since 2.3
*/
public static String join(final Iterable<?> iterable, final char separator) {
if (iterable == null) {
return null;
}
return join(iterable.iterator(), separator);
}
/**
* <p>Joins the elements of the provided {@code Iterable} into
* a single String containing the provided elements.</p>
*
* <p>No delimiter is added before or after the list.
* A {@code null} separator is the same as an empty String ("").</p>
*
* <p>See the examples here: {@link #join(Object[],String)}. </p>
*
* @param iterable the {@code Iterable} providing the values to join together, may be null
* @param separator the separator character to use, null treated as ""
* @return the joined String, {@code null} if null iterator input
* @since 2.3
*/
public static String join(final Iterable<?> iterable, final String separator) {
if (iterable == null) {
return null;
}
return join(iterable.iterator(), separator);
}
}