Applying Stefan Zeller's performance improvement to StrBuilder (LANG-523) by doubling the size of the String in ensureCapacity. Tests indicate a hundredhold improvement in appending speed, which seems worth the doubling of data size.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@811944 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
da95cca2f3
commit
86c1cfa637
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.commons.lang;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
@ -31,10 +32,74 @@ import java.util.Map;
|
|||
* Validate.notNull( surname, "The surname must not be null");
|
||||
* </pre>
|
||||
*
|
||||
* All validate functions exist in 4 variants:
|
||||
*
|
||||
* <p>1st function with only the validation option</p>
|
||||
* <pre>
|
||||
* Validate.isNotNull(surName);
|
||||
* </pre>
|
||||
*
|
||||
* <p>2nd function with an additional String message parameter. This should
|
||||
* be used only if no additional parameters have to be provided. Instead of using
|
||||
* String operations to create the message String, the following 3rd variant
|
||||
* should be used.</p>
|
||||
* <pre>
|
||||
* Validate.isNotNull(surName, "surname must be set");
|
||||
* </pre>
|
||||
*
|
||||
* <p>Since commons-lang-3.0, for each validation function a similar 3rd validation function exists
|
||||
* with a list of additional message parameters as Objects in ellipsis notation.
|
||||
* This is used instead of simply passing a message String due to performance reasons!
|
||||
* When using a message string, all parameters would have to be string concatenated
|
||||
* before the call, even if no problem arises which would cost performance.</br>
|
||||
* Instead of this, we will concatenate (with spaces) all given msgObjects.toString()
|
||||
* only in case of a failed validation! If the first parameter of the msgObject is a
|
||||
* String, it will be taken as the format string for {@code MessageFormat}.</p>
|
||||
*
|
||||
* <h3>Examples:</h3>
|
||||
* <p>
|
||||
* Simply validating an Argument without further message:
|
||||
* <pre>
|
||||
* public void myFn(String argString, Integer argInt) {
|
||||
* Validate.notNull(argString);
|
||||
* Validate.notNull(argInt);
|
||||
* Validate.isTrue(argInt.intValue > 3);
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
*
|
||||
* <p>
|
||||
* Validating an Argument and adding a message to the IllegalArgumentException:
|
||||
* <pre>
|
||||
* public void myFn(String argString, Integer argInt) {
|
||||
* Validate.notNull(argInt, "Integer parameter must be set);
|
||||
* Validate.isTrue(argInt.intValue > 3, "Integer parameter must be <=3!");
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
*
|
||||
* <p>
|
||||
* If the first parameter of the msgObject is a String {@code MessageFormat} will be used:
|
||||
* <pre>
|
||||
* Validate.isTrue(argInt1.intValue > argInt2.intValue, "param2 actually is {1} but must larger than param1 {0} !", argInt1, argInt2);
|
||||
* </pre>
|
||||
* </p>
|
||||
*
|
||||
* <p>The same function sometimes exists multiple times in a 4th form with a single message String parameter
|
||||
* and an additional value parameter. This is essentially the same like the 3rd form, but with fixed
|
||||
* object values to preserve backward compatibility with Validate 2.0!<p>
|
||||
* <p>If the message String contains a <code>"{0}"</code>, it will be passed to
|
||||
* {@code MessageFormat} with the value parameter as single Object parameter. If not, the value parameter
|
||||
* will simply get concatenated to the message String separated with a space.
|
||||
* </p>
|
||||
|
||||
* @see MessageFormat
|
||||
*
|
||||
* @author <a href="mailto:ola.berg@arkitema.se">Ola Berg</a>
|
||||
* @author Stephen Colebourne
|
||||
* @author Gary Gregory
|
||||
* @author Norm Deane
|
||||
* @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
|
||||
* @since 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
@ -74,7 +139,7 @@ public class Validate {
|
|||
*/
|
||||
public static void isTrue(boolean expression, String message, Object value) {
|
||||
if (expression == false) {
|
||||
throw new IllegalArgumentException(message + value);
|
||||
throw new IllegalArgumentException(getMessage(message, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +165,8 @@ public class Validate {
|
|||
*/
|
||||
public static void isTrue(boolean expression, String message, long value) {
|
||||
if (expression == false) {
|
||||
throw new IllegalArgumentException(message + value);
|
||||
|
||||
throw new IllegalArgumentException(getMessage(message, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +193,7 @@ public class Validate {
|
|||
*/
|
||||
public static void isTrue(boolean expression, String message, double value) {
|
||||
if (expression == false) {
|
||||
throw new IllegalArgumentException(message + value);
|
||||
throw new IllegalArgumentException(getMessage(message, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,6 +248,32 @@ public class Validate {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the test result is <code>false</code>.</p>
|
||||
*
|
||||
* <p>This is used when validating according to an arbitrary boolean expression,
|
||||
* such as validating a primitive number or using your own custom validation
|
||||
* expression.</p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.isTrue(argInt1.intValue > argInt2.intValue,
|
||||
* "param2 actually is {1} but must larger than param1 {0} !", argInt1, argInt2);
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message</p>
|
||||
* <p>Otherwise the message in the exception is 'Validation failed: ' followed by all given
|
||||
* parameters delimited with spaces.</p>
|
||||
*
|
||||
* @param expression a boolean expression
|
||||
* @throws IllegalArgumentException if expression is <code>false</code>
|
||||
*/
|
||||
public static void isTrue(boolean expression, Object... msgObjects) {
|
||||
if (expression == false) {
|
||||
throw new IllegalArgumentException(getMessage(msgObjects));
|
||||
}
|
||||
}
|
||||
|
||||
// notNull
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
@ -221,6 +313,28 @@ public class Validate {
|
|||
notNull(object, "The validated object is null");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the argument is <code>null</code>.</p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.notNull(myObject, "This happens while processing user {0}, currentUser);
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message</p>
|
||||
* <p>Otherwise the message in the exception is 'Validation failed: ' followed by all given
|
||||
* parameters delimited with spaces.</p>
|
||||
*
|
||||
* @param object Object to validate
|
||||
* @param msgObjects additional Objects added as text message to the InvalidArgumentException
|
||||
*/
|
||||
public static void notNull(Object object, Object... msgObjects) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException(getMessage(msgObjects));
|
||||
}
|
||||
}
|
||||
|
||||
// notEmpty array
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
@ -259,6 +373,26 @@ public class Validate {
|
|||
notEmpty(array, "The validated array is empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the argument array is empty (<code>null</code> or no elements).</p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.notEmpty(myArray, "This happens while processing user {0}, currentUser);
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message</p>
|
||||
* <p>Otherwise the message in the exception is 'Validation failed: ' followed by all given
|
||||
* parameters delimited with spaces.</p>
|
||||
*
|
||||
* @param array the array to check is not empty
|
||||
* @param msgObjects additional Objects added as text message to the InvalidArgumentException
|
||||
* @throws IllegalArgumentException if the array is empty
|
||||
*/
|
||||
public static void notEmpty(Object[] array, Object... msgObjects) {
|
||||
notEmpty(array, getMessage(msgObjects));
|
||||
}
|
||||
|
||||
// notEmpty collection
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
@ -297,6 +431,26 @@ public class Validate {
|
|||
notEmpty(collection, "The validated collection is empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the argument Collection is empty (<code>null</code> or no elements).</p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.notEmpty(myCollection, "This happens while processing user {0}, currentUser);
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message</p>
|
||||
* <p>Otherwise the message in the exception is 'Validation failed: ' followed by all given
|
||||
* parameters delimited with spaces.</p>
|
||||
*
|
||||
* @param collection the collection to check is not empty
|
||||
* @param msgObjects additional Objects added as text message to the InvalidArgumentException
|
||||
* @throws IllegalArgumentException if the collection is empty
|
||||
*/
|
||||
public static void notEmpty(Collection<?> collection, Object... msgObjects) {
|
||||
notEmpty(collection, getMessage(msgObjects));
|
||||
}
|
||||
|
||||
// notEmpty map
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
@ -335,6 +489,26 @@ public class Validate {
|
|||
notEmpty(map, "The validated map is empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the argument Map is empty (<code>null</code> or no elements).</p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.notEmpty(myMap, "This happens while processing user {0}, currentUser);
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message</p>
|
||||
* <p>Otherwise the message in the exception is 'Validation failed: ' followed by all given
|
||||
* parameters delimited with spaces.</p>
|
||||
*
|
||||
* @param map the map to check is not empty
|
||||
* @param msgObjects additional Objects added as text message to the InvalidArgumentException
|
||||
* @throws IllegalArgumentException if the map is empty
|
||||
*/
|
||||
public static void notEmpty(Map<?,?> map, Object... msgObjects) {
|
||||
notEmpty(map, getMessage(msgObjects));
|
||||
}
|
||||
|
||||
// notEmpty string
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
@ -373,6 +547,26 @@ public class Validate {
|
|||
notEmpty(string, "The validated string is empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the argument String is empty (<code>null</code> or zero length).</p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.notEmpty(myString);
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message</p>
|
||||
* <p>Otherwise the message in the exception is 'Validation failed: ' followed by all given
|
||||
* parameters delimited with spaces.</p>
|
||||
*
|
||||
* @param string the string to check is not empty
|
||||
* @param msgObjects additional Objects added as text message to the InvalidArgumentException
|
||||
* @throws IllegalArgumentException if the string is empty
|
||||
*/
|
||||
public static void notEmpty(String string, Object... msgObjects) {
|
||||
notEmpty(string, getMessage(msgObjects));
|
||||
}
|
||||
|
||||
// notNullElements array
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
@ -429,6 +623,36 @@ public class Validate {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the argument array has <code>null</code> elements or is
|
||||
* <code>null</code>.</p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.noNullElements(myArray);
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message</p>
|
||||
* <p>Otherwise the message in the exception is 'Validation failed: ' followed by all given
|
||||
* parameters delimited with spaces.</p>
|
||||
*
|
||||
* <p>If the array is null then the message in the exception is 'The validated object is null'.</p>
|
||||
*
|
||||
* @param array the array to check
|
||||
* @param msgObjects additional Objects added as text message to the InvalidArgumentException
|
||||
* @throws IllegalArgumentException if the array has <code>null</code>
|
||||
* elements or is <code>null</code>
|
||||
*/
|
||||
public static void noNullElements(Object[] array, Object... msgObjects) {
|
||||
Validate.notNull(array);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (array[i] == null) {
|
||||
//X TODO maybe we can add 'i' as 0-th element?
|
||||
throw new IllegalArgumentException(getMessage(msgObjects));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// notNullElements collection
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
@ -485,6 +709,41 @@ public class Validate {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the argument Collection has <code>null</code> elements or is
|
||||
* <code>null</code>.</p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.noNullElements(myCollection);
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message</p>
|
||||
* <p>Otherwise the message in the exception is 'Validation failed: ' followed by all given
|
||||
* parameters delimited with spaces.</p>
|
||||
*
|
||||
* <p>If the collection is null then the message in the exception is 'The validated object is null'.</p>
|
||||
*
|
||||
* @param collection the collection to check
|
||||
* @param msgObjects additional Objects added as text message to the InvalidArgumentException
|
||||
* @throws IllegalArgumentException if the collection has
|
||||
* <code>null</code> elements or is <code>null</code>
|
||||
*/
|
||||
public static void noNullElements(Collection collection, Object... msgObjects) {
|
||||
Validate.notNull(collection);
|
||||
int i = 0;
|
||||
for (Iterator it = collection.iterator(); it.hasNext(); i++) {
|
||||
if (it.next() == null) {
|
||||
//X TODO how about adding 'i' as 0-th element?
|
||||
throw new IllegalArgumentException(getMessage(msgObjects));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// allElementsOfType collection
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Validate an argument, throwing <code>IllegalArgumentException</code>
|
||||
* if the argument collection is <code>null</code> or has elements that
|
||||
|
@ -541,4 +800,74 @@ public class Validate {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Validate an argument, throwing <code>IllegalArgumentException</code> if the argument collection is
|
||||
* <code>null</code> or has elements that are not of type <code>clazz</code> or a subclass.
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* Validate.allElementsOfType(collection, String.class);
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* The message in the exception is 'The validated collection contains an element not of type clazz at index: '.
|
||||
* </p>
|
||||
*
|
||||
* @param collection
|
||||
* the collection to check, not null
|
||||
* @param clazz
|
||||
* the <code>Class</code> which the collection's elements are expected to be, not null
|
||||
* @since 2.1
|
||||
*/
|
||||
public static void allElementsOfType(Collection collection, Class clazz, Object... msgObjects) {
|
||||
Validate.notNull(collection);
|
||||
Validate.notNull(clazz);
|
||||
int i = 0;
|
||||
for (Iterator it = collection.iterator(); it.hasNext(); i++) {
|
||||
if (clazz.isInstance(it.next()) == false) {
|
||||
//X TODO how to add clazz.getName() and i?
|
||||
throw new IllegalArgumentException(getMessage(msgObjects));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private helper functions
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* private helper function to create an error message from the given Objects
|
||||
* If the first object in msgObjects is of type {@code String} then
|
||||
* {@code MessageFormat} will be used to format the output message.
|
||||
*
|
||||
* @param msgObjects
|
||||
* @return concatenated String representation of all the objects
|
||||
*/
|
||||
private static String getMessage(Object... msgObjects) {
|
||||
if (msgObjects.length > 0 && msgObjects[0] instanceof String) {
|
||||
String message = (String) msgObjects[0];
|
||||
if (msgObjects.length == 2 && !message.matches("[^\\{]*\\{\\d*\\}.*")) {
|
||||
// if it doesn't contain {0}, {1} etc we simply use string concatenation
|
||||
return message + msgObjects[1]; // no space between to act like original function!
|
||||
}
|
||||
|
||||
MessageFormat form = new MessageFormat((String) msgObjects[0]);
|
||||
Object[] params = new Object[msgObjects.length - 1];
|
||||
System.arraycopy(msgObjects, 1, params, 0, msgObjects.length - 1);
|
||||
return form.format(params);
|
||||
}
|
||||
else {
|
||||
StringBuffer sb = new StringBuffer("Validation failed: [");
|
||||
for(int i = 0; i < msgObjects.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(msgObjects[i]);
|
||||
}
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ public class StrBuilder implements CharSequence, Appendable {
|
|||
public StrBuilder ensureCapacity(int capacity) {
|
||||
if (capacity > buffer.length) {
|
||||
char[] old = buffer;
|
||||
buffer = new char[capacity];
|
||||
buffer = new char[capacity * 2];
|
||||
System.arraycopy(old, 0, buffer, 0, size);
|
||||
}
|
||||
return this;
|
||||
|
|
Loading…
Reference in New Issue