This reverts commit cf92d19d03
.
This commit is contained in:
parent
f808ffdb65
commit
8950304f03
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.alibaba.nacos.common.utils;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
* nacos array util.
|
||||
*
|
||||
* @author wujian
|
||||
*/
|
||||
public class ArrayUtil {
|
||||
|
||||
/**
|
||||
* The index value when an element is not found in a list or array: {@code -1}. This value is returned by methods in
|
||||
* this class and can also be used in comparisons with values returned by various method from {@link
|
||||
* java.util.List}.
|
||||
*/
|
||||
public static final int INDEX_NOT_FOUND = -1;
|
||||
|
||||
/**
|
||||
* An empty immutable {@code boolean} array.
|
||||
*/
|
||||
public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
|
||||
|
||||
/**
|
||||
* An empty immutable {@code String} array.
|
||||
*/
|
||||
public static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
/**
|
||||
* Checks if an array of Objects is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
*/
|
||||
public static boolean isEmpty(final Object[] array) {
|
||||
return getLength(array) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the specified array. This method can deal with {@code Object} arrays and with primitive
|
||||
* arrays.
|
||||
*
|
||||
* <p>If the input array is {@code null}, {@code 0} is returned.
|
||||
*
|
||||
* <pre>
|
||||
* ArrayUtils.getLength(null) = 0
|
||||
* ArrayUtils.getLength([]) = 0
|
||||
* ArrayUtils.getLength([null]) = 1
|
||||
* ArrayUtils.getLength([true, false]) = 2
|
||||
* ArrayUtils.getLength([1, 2, 3]) = 3
|
||||
* ArrayUtils.getLength(["a", "b", "c"]) = 3
|
||||
* </pre>
|
||||
*
|
||||
* @param array the array to retrieve the length from, may be null
|
||||
* @return The length of the array, or {@code 0} if the array is {@code null}
|
||||
* @throws IllegalArgumentException if the object argument is not an array.
|
||||
*/
|
||||
public static int getLength(final Object array) {
|
||||
if (array == null) {
|
||||
return 0;
|
||||
}
|
||||
return Array.getLength(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the object is in the given array.
|
||||
*
|
||||
* <p>The method returns {@code false} if a {@code null} array is passed in.
|
||||
*
|
||||
* @param array the array to search through
|
||||
* @param objectToFind the object to find
|
||||
* @return {@code true} if the array contains the object
|
||||
*/
|
||||
public static boolean contains(final Object[] array, final Object objectToFind) {
|
||||
return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Boolean array converters
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Converts an array of object Booleans to primitives.</p>
|
||||
*
|
||||
* <p>This method returns {@code null} for a {@code null} input array.</p>
|
||||
*
|
||||
* @param array a {@code Boolean} array, may be {@code null}
|
||||
* @return a {@code boolean} array, {@code null} if null array input
|
||||
* @throws NullPointerException if array content is {@code null}
|
||||
*/
|
||||
public static boolean[] toPrimitive(final Boolean[] array) {
|
||||
if (array == null) {
|
||||
return null;
|
||||
} else if (array.length == 0) {
|
||||
return EMPTY_BOOLEAN_ARRAY;
|
||||
}
|
||||
final boolean[] result = new boolean[array.length];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
result[i] = array[i].booleanValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// IndexOf search
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// Object IndexOf
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Finds the index of the given object in the array.
|
||||
*
|
||||
* <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
|
||||
*
|
||||
* @param array the array to search through for the object, may be {@code null}
|
||||
* @param objectToFind the object to find, may be {@code null}
|
||||
* @return the index of the object within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code
|
||||
* null} array input
|
||||
*/
|
||||
public static int indexOf(final Object[] array, final Object objectToFind) {
|
||||
return indexOf(array, objectToFind, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the index of the given object in the array starting at the given index.
|
||||
*
|
||||
* <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
|
||||
*
|
||||
* <p>A negative startIndex is treated as zero. A startIndex larger than the array
|
||||
* length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
|
||||
*
|
||||
* @param array the array to search through for the object, may be {@code null}
|
||||
* @param objectToFind the object to find, may be {@code null}
|
||||
* @param startIndex the index to start searching at
|
||||
* @return the index of the object within the array starting at the index, {@link #INDEX_NOT_FOUND} ({@code -1}) if
|
||||
* not found or {@code null} array input
|
||||
*/
|
||||
public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
|
||||
if (array == null) {
|
||||
return INDEX_NOT_FOUND;
|
||||
}
|
||||
if (startIndex < 0) {
|
||||
startIndex = 0;
|
||||
}
|
||||
if (objectToFind == null) {
|
||||
for (int i = startIndex; i < array.length; i++) {
|
||||
if (array[i] == null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = startIndex; i < array.length; i++) {
|
||||
if (objectToFind.equals(array[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return INDEX_NOT_FOUND;
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.alibaba.nacos.common.utils;
|
||||
|
||||
/**
|
||||
* nacos boolean util.
|
||||
*
|
||||
* @author wujian
|
||||
*/
|
||||
public class BooleanUtil {
|
||||
|
||||
/**
|
||||
* <p>Performs an and on a set of booleans.</p>
|
||||
*
|
||||
* <pre>
|
||||
* BooleanUtils.and(true, true) = true
|
||||
* BooleanUtils.and(false, false) = false
|
||||
* BooleanUtils.and(true, false) = false
|
||||
* BooleanUtils.and(true, true, false) = false
|
||||
* BooleanUtils.and(true, true, true) = true
|
||||
* </pre>
|
||||
*
|
||||
* @param array an array of {@code boolean}s
|
||||
* @return {@code true} if the and is successful.
|
||||
* @throws IllegalArgumentException if {@code array} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code array} is empty.
|
||||
*/
|
||||
public static boolean and(final boolean... array) {
|
||||
// Validates input
|
||||
if (array == null) {
|
||||
throw new IllegalArgumentException("The Array must not be null");
|
||||
}
|
||||
if (array.length == 0) {
|
||||
throw new IllegalArgumentException("Array is empty");
|
||||
}
|
||||
for (final boolean element : array) {
|
||||
if (!element) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Performs an and on an array of Booleans.</p>
|
||||
*
|
||||
* <pre>
|
||||
* BooleanUtils.and(Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
|
||||
* BooleanUtils.and(Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
|
||||
* BooleanUtils.and(Boolean.TRUE, Boolean.FALSE) = Boolean.FALSE
|
||||
* BooleanUtils.and(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
|
||||
* BooleanUtils.and(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
|
||||
* BooleanUtils.and(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
|
||||
* </pre>
|
||||
*
|
||||
* @param array an array of {@code Boolean}s
|
||||
* @return {@code true} if the and is successful.
|
||||
* @throws IllegalArgumentException if {@code array} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code array} is empty.
|
||||
* @throws IllegalArgumentException if {@code array} contains a {@code null}
|
||||
*/
|
||||
public static Boolean and(final Boolean... array) {
|
||||
if (array == null) {
|
||||
throw new IllegalArgumentException("The Array must not be null");
|
||||
}
|
||||
if (array.length == 0) {
|
||||
throw new IllegalArgumentException("Array is empty");
|
||||
}
|
||||
try {
|
||||
final boolean[] primitive = ArrayUtil.toPrimitive(array);
|
||||
return and(primitive) ? Boolean.TRUE : Boolean.FALSE;
|
||||
} catch (final NullPointerException ex) {
|
||||
throw new IllegalArgumentException("The array must not contain any null elements");
|
||||
}
|
||||
}
|
||||
}
|
@ -245,79 +245,6 @@ public final class ConvertUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Convert a <code>String</code> to a <code>double</code>, returning a
|
||||
* default value if the conversion fails.</p>
|
||||
*
|
||||
* <p>If the string <code>str</code> is <code>null</code>, the default
|
||||
* value is returned.</p>
|
||||
*
|
||||
* <pre>
|
||||
* NumberUtils.toDouble(null, 1.1d) = 1.1d
|
||||
* NumberUtils.toDouble("", 1.1d) = 1.1d
|
||||
* NumberUtils.toDouble("1.5", 0.0d) = 1.5d
|
||||
* </pre>
|
||||
*
|
||||
* @param str the string to convert, may be <code>null</code>
|
||||
* @param defaultValue the default value
|
||||
* @return the double represented by the string, or defaultValue if conversion fails
|
||||
*/
|
||||
public static double toDouble(final String str, final double defaultValue) {
|
||||
if (str == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(str);
|
||||
} catch (final NumberFormatException nfe) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
// end
|
||||
|
||||
/**
|
||||
* <p>Convert a <code>String</code> to a <code>float</code>, returning
|
||||
* <code>0.0f</code> if the conversion fails.</p>
|
||||
*
|
||||
* <p>If the string <code>str</code> is <code>null</code>,
|
||||
* <code>0.0f</code> is returned.</p>
|
||||
*
|
||||
* <pre>
|
||||
* NumberUtils.toFloat(null) = 0.0f
|
||||
* NumberUtils.toFloat("") = 0.0f
|
||||
* NumberUtils.toFloat("1.5") = 1.5f
|
||||
* </pre>
|
||||
*
|
||||
* @param str the string to convert, may be <code>null</code>
|
||||
* @return the float represented by the string, or <code>0.0f</code> if conversion fails
|
||||
*/
|
||||
public static float toFloat(final String str) {
|
||||
return toFloat(str, 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Convert a <code>String</code> to a <code>float</code>, returning a
|
||||
* default value if the conversion fails.</p>
|
||||
*
|
||||
* <p>If the string <code>str</code> is <code>null</code>, the default
|
||||
* value is returned.</p>
|
||||
*
|
||||
* <pre>
|
||||
* NumberUtils.toFloat(null, 1.1f) = 1.0f
|
||||
* NumberUtils.toFloat("", 1.1f) = 1.1f
|
||||
* NumberUtils.toFloat("1.5", 0.0f) = 1.5f
|
||||
* </pre>
|
||||
*
|
||||
* @param str the string to convert, may be <code>null</code>
|
||||
* @param defaultValue the default value
|
||||
* @return the float represented by the string, or defaultValue if conversion fails
|
||||
*/
|
||||
public static float toFloat(final String str, final float defaultValue) {
|
||||
if (str == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Float.parseFloat(str);
|
||||
} catch (final NumberFormatException nfe) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.alibaba.nacos.common.utils;
|
||||
|
||||
/**
|
||||
* nacos Number util.
|
||||
*
|
||||
* @author wujian
|
||||
*/
|
||||
public class NumberUtil {
|
||||
|
||||
/**
|
||||
* <p>Checks whether the String a valid Java number.</p>
|
||||
*
|
||||
* <p>Valid numbers include hexadecimal marked with the <code>0x</code> or
|
||||
* <code>0X</code> qualifier, octal numbers, scientific notation and
|
||||
* numbers marked with a type qualifier (e.g. 123L).</p>
|
||||
*
|
||||
* <p>Non-hexadecimal strings beginning with a leading zero are
|
||||
* treated as octal values. Thus the string <code>09</code> will return
|
||||
* <code>false</code>, since <code>9</code> is not a valid octal value.
|
||||
* However, numbers beginning with {@code 0.} are treated as decimal.</p>
|
||||
*
|
||||
* <p><code>null</code> and empty/blank {@code String} will return
|
||||
* <code>false</code>.</p>
|
||||
*
|
||||
* @param str the <code>String</code> to check
|
||||
* @return <code>true</code> if the string is a correctly formatted number
|
||||
*/
|
||||
public static boolean isNumber(final String str) {
|
||||
return isCreatable(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks whether the String a valid Java number.</p>
|
||||
*
|
||||
* <p>Valid numbers include hexadecimal marked with the <code>0x</code> or
|
||||
* <code>0X</code> qualifier, octal numbers, scientific notation and
|
||||
* numbers marked with a type qualifier (e.g. 123L).</p>
|
||||
*
|
||||
* <p>Non-hexadecimal strings beginning with a leading zero are
|
||||
* treated as octal values. Thus the string <code>09</code> will return
|
||||
* <code>false</code>, since <code>9</code> is not a valid octal value.
|
||||
* However, numbers beginning with {@code 0.} are treated as decimal.</p>
|
||||
*
|
||||
* <p><code>null</code> and empty/blank {@code String} will return
|
||||
* <code>false</code>.</p>
|
||||
*
|
||||
* @param str the <code>String</code> to check
|
||||
* @return <code>true</code> if the string is a correctly formatted number
|
||||
*/
|
||||
@SuppressWarnings({"PMD.UndefineMagicConstantRule", "PMD.AvoidComplexConditionRule"})
|
||||
public static boolean isCreatable(final String str) {
|
||||
if (StringUtils.isEmpty(str)) {
|
||||
return false;
|
||||
}
|
||||
final char[] chars = str.toCharArray();
|
||||
int sz = chars.length;
|
||||
boolean hasExp = false;
|
||||
boolean hasDecPoint = false;
|
||||
boolean allowSigns = false;
|
||||
boolean foundDigit = false;
|
||||
// deal with any possible sign up front
|
||||
final int start = chars[0] == '-' || chars[0] == '+' ? 1 : 0;
|
||||
// leading 0, skip if is a decimal number
|
||||
if (sz > start + 1 && chars[start] == '0' && !StringUtils.contains(str, '.')) {
|
||||
// leading 0x/0X
|
||||
if (chars[start + 1] == 'x' || chars[start + 1] == 'X') {
|
||||
int i = start + 2;
|
||||
if (i == sz) {
|
||||
// str == "0x"
|
||||
return false;
|
||||
}
|
||||
// checking hex (it can't be anything else)
|
||||
for (; i < chars.length; i++) {
|
||||
if ((chars[i] < '0' || chars[i] > '9') && (chars[i] < 'a' || chars[i] > 'f') && (chars[i] < 'A'
|
||||
|| chars[i] > 'F')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (Character.isDigit(chars[start + 1])) {
|
||||
// leading 0, but not hex, must be octal
|
||||
int i = start + 1;
|
||||
for (; i < chars.length; i++) {
|
||||
if (chars[i] < '0' || chars[i] > '7') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
sz--; // don't want to loop to the last char, check it afterwords
|
||||
// for type qualifiers
|
||||
int i = start;
|
||||
// loop to the next to last char or to the last char if we need another digit to
|
||||
// make a valid number (e.g. chars[0..5] = "1234E")
|
||||
while (i < sz || i < sz + 1 && allowSigns && !foundDigit) {
|
||||
if (chars[i] >= '0' && chars[i] <= '9') {
|
||||
foundDigit = true;
|
||||
allowSigns = false;
|
||||
|
||||
} else if (chars[i] == '.') {
|
||||
if (hasDecPoint || hasExp) {
|
||||
// two decimal points or dec in exponent
|
||||
return false;
|
||||
}
|
||||
hasDecPoint = true;
|
||||
} else if (chars[i] == 'e' || chars[i] == 'E') {
|
||||
// we've already taken care of hex.
|
||||
if (hasExp) {
|
||||
// two E's
|
||||
return false;
|
||||
}
|
||||
if (!foundDigit) {
|
||||
return false;
|
||||
}
|
||||
hasExp = true;
|
||||
allowSigns = true;
|
||||
} else if (chars[i] == '+' || chars[i] == '-') {
|
||||
if (!allowSigns) {
|
||||
return false;
|
||||
}
|
||||
allowSigns = false;
|
||||
// we need a digit after the E
|
||||
foundDigit = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i < chars.length) {
|
||||
if (chars[i] >= '0' && chars[i] <= '9') {
|
||||
// no type qualifier, OK
|
||||
return true;
|
||||
}
|
||||
if (chars[i] == 'e' || chars[i] == 'E') {
|
||||
// can't have an E at the last byte
|
||||
return false;
|
||||
}
|
||||
if (chars[i] == '.') {
|
||||
if (hasDecPoint || hasExp) {
|
||||
// two decimal points or dec in exponent
|
||||
return false;
|
||||
}
|
||||
// single trailing decimal point after non-exponent is ok
|
||||
return foundDigit;
|
||||
}
|
||||
if (!allowSigns && (chars[i] == 'd' || chars[i] == 'D' || chars[i] == 'f' || chars[i] == 'F')) {
|
||||
return foundDigit;
|
||||
}
|
||||
if (chars[i] == 'l' || chars[i] == 'L') {
|
||||
// not allowing L with an exponent or decimal point
|
||||
return foundDigit && !hasExp && !hasDecPoint;
|
||||
}
|
||||
// last character is illegal
|
||||
return false;
|
||||
}
|
||||
// allowSigns is true iff the val ends in 'E'
|
||||
// found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
|
||||
return !allowSigns && foundDigit;
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.alibaba.nacos.common.utils;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* nacos random util.
|
||||
*
|
||||
* @author wujian
|
||||
*/
|
||||
public class RandomUtil {
|
||||
|
||||
/**
|
||||
* Random object used by random method. This has to be not local to the random method so as to not return the same
|
||||
* value in the same millisecond.
|
||||
*/
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a random long within the specified range.
|
||||
* </p>
|
||||
*
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @return the random long
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
*/
|
||||
public static long nextLong(final long startInclusive, final long endExclusive) {
|
||||
Preconditions
|
||||
.checkArgument(endExclusive >= startInclusive, "Start value must be smaller or equal to end value.");
|
||||
Preconditions.checkArgument(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
|
||||
return (long) nextDouble(startInclusive, endExclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a random double within the specified range.
|
||||
* </p>
|
||||
*
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endInclusive the upper bound (included)
|
||||
* @return the random double
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endInclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
*/
|
||||
public static double nextDouble(final double startInclusive, final double endInclusive) {
|
||||
Preconditions
|
||||
.checkArgument(endInclusive >= startInclusive, "Start value must be smaller or equal to end value.");
|
||||
Preconditions.checkArgument(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
|
||||
if (startInclusive == endInclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
|
||||
return startInclusive + ((endInclusive - startInclusive) * RANDOM.nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a random integer within the specified range.
|
||||
* </p>
|
||||
*
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @return the random integer
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
*/
|
||||
public static int nextInt(final int startInclusive, final int endExclusive) {
|
||||
Preconditions
|
||||
.checkArgument(endExclusive >= startInclusive, "Start value must be smaller or equal to end value.");
|
||||
Preconditions.checkArgument(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
|
||||
return startInclusive + RANDOM.nextInt(endExclusive - startInclusive);
|
||||
}
|
||||
}
|
@ -22,9 +22,7 @@ import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
@ -42,8 +40,6 @@ public class StringUtils {
|
||||
|
||||
public static final String EMPTY = "";
|
||||
|
||||
public static final String LF = "\n";
|
||||
|
||||
public static String newStringForUtf8(byte[] bytes) {
|
||||
return new String(bytes, Charset.forName(Constants.ENCODE));
|
||||
}
|
||||
@ -67,35 +63,6 @@ public class StringUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks if a CharSequence is empty (""), null or whitespace only.</p>
|
||||
*
|
||||
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.isBlank(null) = true
|
||||
* StringUtils.isBlank("") = true
|
||||
* StringUtils.isBlank(" ") = true
|
||||
* StringUtils.isBlank("bob") = false
|
||||
* StringUtils.isBlank(" bob ") = false
|
||||
* </pre>
|
||||
*
|
||||
* @param cs the CharSequence to check, may be null
|
||||
* @return {@code true} if the CharSequence is null, empty or whitespace only
|
||||
*/
|
||||
public static boolean isBlank(final CharSequence cs) {
|
||||
int strLen;
|
||||
if (cs == null || (strLen = cs.length()) == 0) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < strLen; i++) {
|
||||
if (!Character.isWhitespace(cs.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge whether all strings are blank.
|
||||
*
|
||||
@ -123,10 +90,6 @@ public class StringUtils {
|
||||
return str == null || str.length() == 0;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(CharSequence cs) {
|
||||
return cs == null || cs.length() == 0;
|
||||
}
|
||||
|
||||
public static String defaultIfEmpty(String str, String defaultStr) {
|
||||
return StringUtils.isEmpty(str) ? defaultStr : str;
|
||||
}
|
||||
@ -313,6 +276,8 @@ public class StringUtils {
|
||||
* @param searchStr the CharSequence to find, may be null
|
||||
* @return true if the CharSequence contains the search CharSequence irrespective of case or false if not or {@code
|
||||
* null} string input
|
||||
* @since 3.0 Changed signature from containsIgnoreCase(String, String) to containsIgnoreCase(CharSequence,
|
||||
* CharSequence)
|
||||
*/
|
||||
public static boolean containsIgnoreCase(final CharSequence str, final CharSequence searchStr) {
|
||||
if (str == null || searchStr == null) {
|
||||
@ -388,6 +353,8 @@ public class StringUtils {
|
||||
* @param str1 the first CharSequence, may be null
|
||||
* @param str2 the second CharSequence, may be null
|
||||
* @return {@code true} if the CharSequence are equal, case insensitive, or both {@code null}
|
||||
* @since 3.0 Changed signature from equalsIgnoreCase(String, String) to equalsIgnoreCase(CharSequence,
|
||||
* CharSequence)
|
||||
*/
|
||||
public static boolean equalsIgnoreCase(final CharSequence str1, final CharSequence str2) {
|
||||
if (str1 == null || str2 == null) {
|
||||
@ -445,526 +412,7 @@ public class StringUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.UndefineMagicConstantRule")
|
||||
static int indexOf(CharSequence cs, int searchChar, int start) {
|
||||
if (cs instanceof String) {
|
||||
return ((String) cs).indexOf(searchChar, start);
|
||||
} else {
|
||||
int sz = cs.length();
|
||||
if (start < 0) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (searchChar < 65536) {
|
||||
for (int i = start; i < sz; ++i) {
|
||||
if (cs.charAt(i) == searchChar) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchChar <= 1114111) {
|
||||
char[] chars = Character.toChars(searchChar);
|
||||
|
||||
for (int i = start; i < sz - 1; ++i) {
|
||||
char high = cs.charAt(i);
|
||||
char low = cs.charAt(i + 1);
|
||||
if (high == chars[0] && low == chars[1]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int indexOf(CharSequence cs, CharSequence searchChar, int start) {
|
||||
return cs.toString().indexOf(searchChar.toString(), start);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks if CharSequence contains a search character, handling {@code null}.
|
||||
* This method uses {@link String#indexOf(int)} if possible.</p>
|
||||
*
|
||||
* <p>A {@code null} or empty ("") CharSequence will return {@code false}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.contains(null, *) = false
|
||||
* StringUtils.contains("", *) = false
|
||||
* StringUtils.contains("abc", 'a') = true
|
||||
* StringUtils.contains("abc", 'z') = false
|
||||
* </pre>
|
||||
*
|
||||
* @param seq the CharSequence to check, may be null
|
||||
* @param searchChar the character to find
|
||||
* @return true if the CharSequence contains the search character, false if not or {@code null} string input
|
||||
*/
|
||||
public static boolean contains(final CharSequence seq, final int searchChar) {
|
||||
if (isEmpty(seq)) {
|
||||
return false;
|
||||
}
|
||||
return CharSequenceUtils.indexOf(seq, searchChar, 0) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks if CharSequence contains a search CharSequence, handling {@code null}.
|
||||
* This method uses {@link String#indexOf(String)} if possible.</p>
|
||||
*
|
||||
* <p>A {@code null} CharSequence will return {@code false}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.contains(null, *) = false
|
||||
* StringUtils.contains(*, null) = false
|
||||
* StringUtils.contains("", "") = true
|
||||
* StringUtils.contains("abc", "") = true
|
||||
* StringUtils.contains("abc", "a") = true
|
||||
* StringUtils.contains("abc", "z") = false
|
||||
* </pre>
|
||||
*
|
||||
* @param seq the CharSequence to check, may be null
|
||||
* @param searchSeq the CharSequence to find, may be null
|
||||
* @return true if the CharSequence contains the search CharSequence, false if not or {@code null} string input
|
||||
*/
|
||||
public static boolean contains(final CharSequence seq, final CharSequence searchSeq) {
|
||||
if (seq == null || searchSeq == null) {
|
||||
return false;
|
||||
}
|
||||
return CharSequenceUtils.indexOf(seq, searchSeq, 0) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks if none of the CharSequences are empty (""), null or whitespace only.</p>
|
||||
*
|
||||
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.isNoneBlank((String) null) = false
|
||||
* StringUtils.isNoneBlank((String[]) null) = true
|
||||
* StringUtils.isNoneBlank(null, "foo") = false
|
||||
* StringUtils.isNoneBlank(null, null) = false
|
||||
* StringUtils.isNoneBlank("", "bar") = false
|
||||
* StringUtils.isNoneBlank("bob", "") = false
|
||||
* StringUtils.isNoneBlank(" bob ", null) = false
|
||||
* StringUtils.isNoneBlank(" ", "bar") = false
|
||||
* StringUtils.isNoneBlank(new String[] {}) = true
|
||||
* StringUtils.isNoneBlank(new String[]{""}) = false
|
||||
* StringUtils.isNoneBlank("foo", "bar") = true
|
||||
* </pre>
|
||||
*
|
||||
* @param css the CharSequences to check, may be null or empty
|
||||
* @return {@code true} if none of the CharSequences are empty or null or whitespace only
|
||||
*/
|
||||
public static boolean isNoneBlank(final CharSequence... css) {
|
||||
return !isAnyBlank(css);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks if any of the CharSequences are empty ("") or null or whitespace only.</p>
|
||||
*
|
||||
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.isAnyBlank((String) null) = true
|
||||
* StringUtils.isAnyBlank((String[]) null) = false
|
||||
* StringUtils.isAnyBlank(null, "foo") = true
|
||||
* StringUtils.isAnyBlank(null, null) = true
|
||||
* StringUtils.isAnyBlank("", "bar") = true
|
||||
* StringUtils.isAnyBlank("bob", "") = true
|
||||
* StringUtils.isAnyBlank(" bob ", null) = true
|
||||
* StringUtils.isAnyBlank(" ", "bar") = true
|
||||
* StringUtils.isAnyBlank(new String[] {}) = false
|
||||
* StringUtils.isAnyBlank(new String[]{""}) = true
|
||||
* StringUtils.isAnyBlank("foo", "bar") = false
|
||||
* </pre>
|
||||
*
|
||||
* @param css the CharSequences to check, may be null or empty
|
||||
* @return {@code true} if any of the CharSequences are empty or null or whitespace only
|
||||
*/
|
||||
public static boolean isAnyBlank(final CharSequence... css) {
|
||||
if (ArrayUtil.isEmpty(css)) {
|
||||
return false;
|
||||
}
|
||||
for (final CharSequence cs : css) {
|
||||
if (isBlank(cs)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Check if a CharSequence starts with a specified prefix.</p>
|
||||
*
|
||||
* <p>{@code null}s are handled without exceptions. Two {@code null}
|
||||
* references are considered to be equal. The comparison is case sensitive.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.startsWith(null, null) = true
|
||||
* StringUtils.startsWith(null, "abc") = false
|
||||
* StringUtils.startsWith("abcdef", null) = false
|
||||
* StringUtils.startsWith("abcdef", "abc") = true
|
||||
* StringUtils.startsWith("ABCDEF", "abc") = false
|
||||
* </pre>
|
||||
*
|
||||
* @param str the CharSequence to check, may be null
|
||||
* @param prefix the prefix to find, may be null
|
||||
* @return {@code true} if the CharSequence starts with the prefix, case sensitive, or both {@code null}
|
||||
*/
|
||||
public static boolean startsWith(final CharSequence str, final CharSequence prefix) {
|
||||
return startsWith(str, prefix, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Check if a CharSequence starts with a specified prefix (optionally case insensitive).</p>
|
||||
*
|
||||
* @param str the CharSequence to check, may be null
|
||||
* @param prefix the prefix to find, may be null
|
||||
* @param ignoreCase indicates whether the compare should ignore case (case insensitive) or not.
|
||||
* @return {@code true} if the CharSequence starts with the prefix or both {@code null}
|
||||
* @see String#startsWith(String)
|
||||
*/
|
||||
private static boolean startsWith(final CharSequence str, final CharSequence prefix, final boolean ignoreCase) {
|
||||
if (str == null || prefix == null) {
|
||||
return str == prefix;
|
||||
}
|
||||
if (prefix.length() > str.length()) {
|
||||
return false;
|
||||
}
|
||||
return CharSequenceUtils.regionMatches(str, ignoreCase, 0, prefix, 0, prefix.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Deletes all whitespaces from a String as defined by
|
||||
* {@link Character#isWhitespace(char)}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.deleteWhitespace(null) = null
|
||||
* StringUtils.deleteWhitespace("") = ""
|
||||
* StringUtils.deleteWhitespace("abc") = "abc"
|
||||
* StringUtils.deleteWhitespace(" ab c ") = "abc"
|
||||
* </pre>
|
||||
*
|
||||
* @param str the String to delete whitespace from, may be null
|
||||
* @return the String without whitespaces, {@code null} if null String input
|
||||
*/
|
||||
public static String deleteWhitespace(final String str) {
|
||||
if (isEmpty(str)) {
|
||||
return str;
|
||||
}
|
||||
final int sz = str.length();
|
||||
final char[] chs = new char[sz];
|
||||
int count = 0;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
if (!Character.isWhitespace(str.charAt(i))) {
|
||||
chs[count++] = str.charAt(i);
|
||||
}
|
||||
}
|
||||
if (count == sz) {
|
||||
return str;
|
||||
}
|
||||
return new String(chs, 0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Case insensitive check if a CharSequence starts with a specified prefix.</p>
|
||||
*
|
||||
* <p>{@code null}s are handled without exceptions. Two {@code null}
|
||||
* references are considered to be equal. The comparison is case insensitive.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.startsWithIgnoreCase(null, null) = true
|
||||
* StringUtils.startsWithIgnoreCase(null, "abc") = false
|
||||
* StringUtils.startsWithIgnoreCase("abcdef", null) = false
|
||||
* StringUtils.startsWithIgnoreCase("abcdef", "abc") = true
|
||||
* StringUtils.startsWithIgnoreCase("ABCDEF", "abc") = true
|
||||
* </pre>
|
||||
*
|
||||
* @param str the CharSequence to check, may be null
|
||||
* @param prefix the prefix to find, may be null
|
||||
* @return {@code true} if the CharSequence starts with the prefix, case insensitive, or both {@code null}
|
||||
* @see java.lang.String#startsWith(String)
|
||||
*/
|
||||
public static boolean startsWithIgnoreCase(final CharSequence str, final CharSequence prefix) {
|
||||
return startsWith(str, prefix, true);
|
||||
}
|
||||
|
||||
// Stripping
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Strips whitespace from the start and end of a String.</p>
|
||||
*
|
||||
* <p>This is similar to {@link #trim(String)} but removes whitespace.
|
||||
* Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
|
||||
*
|
||||
* <p>A {@code null} input String returns {@code null}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.strip(null) = null
|
||||
* StringUtils.strip("") = ""
|
||||
* StringUtils.strip(" ") = ""
|
||||
* StringUtils.strip("abc") = "abc"
|
||||
* StringUtils.strip(" abc") = "abc"
|
||||
* StringUtils.strip("abc ") = "abc"
|
||||
* StringUtils.strip(" abc ") = "abc"
|
||||
* StringUtils.strip(" ab c ") = "ab c"
|
||||
* </pre>
|
||||
*
|
||||
* @param str the String to remove whitespace from, may be null
|
||||
* @return the stripped String, {@code null} if null String input
|
||||
*/
|
||||
public static String strip(final String str) {
|
||||
return strip(str, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Strips any of a set of characters from the start and end of a String.
|
||||
* This is similar to {@link String#trim()} but allows the characters to be stripped to be controlled.</p>
|
||||
*
|
||||
* <p>A {@code null} input String returns {@code null}.
|
||||
* An empty string ("") input returns the empty string.</p>
|
||||
*
|
||||
* <p>If the stripChars String is {@code null}, whitespace is
|
||||
* stripped as defined by {@link Character#isWhitespace(char)}. Alternatively use {@link #strip(String)}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.strip(null, *) = null
|
||||
* StringUtils.strip("", *) = ""
|
||||
* StringUtils.strip("abc", null) = "abc"
|
||||
* StringUtils.strip(" abc", null) = "abc"
|
||||
* StringUtils.strip("abc ", null) = "abc"
|
||||
* StringUtils.strip(" abc ", null) = "abc"
|
||||
* StringUtils.strip(" abcyx", "xyz") = " abc"
|
||||
* </pre>
|
||||
*
|
||||
* @param str the String to remove characters from, may be null
|
||||
* @param stripChars the characters to remove, null treated as whitespace
|
||||
* @return the stripped String, {@code null} if null String input
|
||||
*/
|
||||
public static String strip(String str, final String stripChars) {
|
||||
if (isEmpty(str)) {
|
||||
return str;
|
||||
}
|
||||
str = stripStart(str, stripChars);
|
||||
return stripEnd(str, stripChars);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Strips any of a set of characters from the start of a String.</p>
|
||||
*
|
||||
* <p>A {@code null} input String returns {@code null}.
|
||||
* An empty string ("") input returns the empty string.</p>
|
||||
*
|
||||
* <p>If the stripChars String is {@code null}, whitespace is
|
||||
* stripped as defined by {@link Character#isWhitespace(char)}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.stripStart(null, *) = null
|
||||
* StringUtils.stripStart("", *) = ""
|
||||
* StringUtils.stripStart("abc", "") = "abc"
|
||||
* StringUtils.stripStart("abc", null) = "abc"
|
||||
* StringUtils.stripStart(" abc", null) = "abc"
|
||||
* StringUtils.stripStart("abc ", null) = "abc "
|
||||
* StringUtils.stripStart(" abc ", null) = "abc "
|
||||
* StringUtils.stripStart("yxabc ", "xyz") = "abc "
|
||||
* </pre>
|
||||
*
|
||||
* @param str the String to remove characters from, may be null
|
||||
* @param stripChars the characters to remove, null treated as whitespace
|
||||
* @return the stripped String, {@code null} if null String input
|
||||
*/
|
||||
public static String stripStart(final String str, final String stripChars) {
|
||||
int strLen;
|
||||
if (str == null || (strLen = str.length()) == 0) {
|
||||
return str;
|
||||
}
|
||||
int start = 0;
|
||||
if (stripChars == null) {
|
||||
while (start != strLen && Character.isWhitespace(str.charAt(start))) {
|
||||
start++;
|
||||
}
|
||||
} else if (stripChars.isEmpty()) {
|
||||
return str;
|
||||
} else {
|
||||
while (start != strLen && stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND) {
|
||||
start++;
|
||||
}
|
||||
}
|
||||
return str.substring(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Strips any of a set of characters from the end of a String.</p>
|
||||
*
|
||||
* <p>A {@code null} input String returns {@code null}.
|
||||
* An empty string ("") input returns the empty string.</p>
|
||||
*
|
||||
* <p>If the stripChars String is {@code null}, whitespace is
|
||||
* stripped as defined by {@link Character#isWhitespace(char)}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.stripEnd(null, *) = null
|
||||
* StringUtils.stripEnd("", *) = ""
|
||||
* StringUtils.stripEnd("abc", "") = "abc"
|
||||
* StringUtils.stripEnd("abc", null) = "abc"
|
||||
* StringUtils.stripEnd(" abc", null) = " abc"
|
||||
* StringUtils.stripEnd("abc ", null) = "abc"
|
||||
* StringUtils.stripEnd(" abc ", null) = " abc"
|
||||
* StringUtils.stripEnd(" abcyx", "xyz") = " abc"
|
||||
* StringUtils.stripEnd("120.00", ".0") = "12"
|
||||
* </pre>
|
||||
*
|
||||
* @param str the String to remove characters from, may be null
|
||||
* @param stripChars the set of characters to remove, null treated as whitespace
|
||||
* @return the stripped String, {@code null} if null String input
|
||||
*/
|
||||
public static String stripEnd(final String str, final String stripChars) {
|
||||
int end;
|
||||
if (str == null || (end = str.length()) == 0) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (stripChars == null) {
|
||||
while (end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
|
||||
end--;
|
||||
}
|
||||
} else if (stripChars.isEmpty()) {
|
||||
return str;
|
||||
} else {
|
||||
while (end != 0 && stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND) {
|
||||
end--;
|
||||
}
|
||||
}
|
||||
return str.substring(0, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Splits the provided text into an array, separators specified.
|
||||
* This is an alternative to using StringTokenizer.</p>
|
||||
*
|
||||
* <p>The separator is not included in the returned String array.
|
||||
* Adjacent separators are treated as one separator. For more control over the split use the StrTokenizer
|
||||
* class.</p>
|
||||
*
|
||||
* <p>A {@code null} input String returns {@code null}.
|
||||
* A {@code null} separatorChars splits on whitespace.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.split(null, *) = null
|
||||
* StringUtils.split("", *) = []
|
||||
* StringUtils.split("abc def", null) = ["abc", "def"]
|
||||
* StringUtils.split("abc def", " ") = ["abc", "def"]
|
||||
* StringUtils.split("abc def", " ") = ["abc", "def"]
|
||||
* StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
|
||||
* </pre>
|
||||
*
|
||||
* @param str the String to parse, may be null
|
||||
* @param separatorChars the characters used as the delimiters, {@code null} splits on whitespace
|
||||
* @return an array of parsed Strings, {@code null} if null String input
|
||||
*/
|
||||
public static String[] split(final String str, final String separatorChars) {
|
||||
return splitWorker(str, separatorChars, -1, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the logic for the {@code split} and {@code splitPreserveAllTokens} methods that return a maximum array
|
||||
* length.
|
||||
*
|
||||
* @param str the String to parse, may be {@code null}
|
||||
* @param separatorChars the separate character
|
||||
* @param max the maximum number of elements to include in the array. A zero or negative value implies
|
||||
* no limit.
|
||||
* @param preserveAllTokens if {@code true}, adjacent separators are treated as empty token separators; if {@code
|
||||
* false}, adjacent separators are treated as one separator.
|
||||
* @return an array of parsed Strings, {@code null} if null String input
|
||||
*/
|
||||
@SuppressWarnings("PMD.AvoidComplexConditionRule")
|
||||
private static String[] splitWorker(final String str, final String separatorChars, final int max,
|
||||
final boolean preserveAllTokens) {
|
||||
// Performance tuned for 2.0 (JDK1.4)
|
||||
// Direct code is quicker than StringTokenizer.
|
||||
// Also, StringTokenizer uses isSpace() not isWhitespace()
|
||||
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
final int len = str.length();
|
||||
if (len == 0) {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
final List<String> list = new ArrayList<String>();
|
||||
int sizePlus1 = 1;
|
||||
int i = 0;
|
||||
int start = 0;
|
||||
boolean match = false;
|
||||
boolean lastMatch = false;
|
||||
if (separatorChars == null) {
|
||||
// Null separator means use whitespace
|
||||
while (i < len) {
|
||||
if (Character.isWhitespace(str.charAt(i))) {
|
||||
if (match || preserveAllTokens) {
|
||||
lastMatch = true;
|
||||
if (sizePlus1++ == max) {
|
||||
i = len;
|
||||
lastMatch = false;
|
||||
}
|
||||
list.add(str.substring(start, i));
|
||||
match = false;
|
||||
}
|
||||
start = ++i;
|
||||
continue;
|
||||
}
|
||||
lastMatch = false;
|
||||
match = true;
|
||||
i++;
|
||||
}
|
||||
} else if (separatorChars.length() == 1) {
|
||||
// Optimise 1 character case
|
||||
final char sep = separatorChars.charAt(0);
|
||||
while (i < len) {
|
||||
if (str.charAt(i) == sep) {
|
||||
if (match || preserveAllTokens) {
|
||||
lastMatch = true;
|
||||
if (sizePlus1++ == max) {
|
||||
i = len;
|
||||
lastMatch = false;
|
||||
}
|
||||
list.add(str.substring(start, i));
|
||||
match = false;
|
||||
}
|
||||
start = ++i;
|
||||
continue;
|
||||
}
|
||||
lastMatch = false;
|
||||
match = true;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
// standard case
|
||||
while (i < len) {
|
||||
if (separatorChars.indexOf(str.charAt(i)) >= 0) {
|
||||
if (match || preserveAllTokens) {
|
||||
lastMatch = true;
|
||||
if (sizePlus1++ == max) {
|
||||
i = len;
|
||||
lastMatch = false;
|
||||
}
|
||||
list.add(str.substring(start, i));
|
||||
match = false;
|
||||
}
|
||||
start = ++i;
|
||||
continue;
|
||||
}
|
||||
lastMatch = false;
|
||||
match = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (match || preserveAllTokens && lastMatch) {
|
||||
list.add(str.substring(start, i));
|
||||
}
|
||||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
// end
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user