Browse Source

Optimize StringUtils.replace/deleteAny for common no-op case

Issue: SPR-15430
pull/1362/merge
Juergen Hoeller 9 years ago
parent
commit
3a1d431c7d
  1. 50
      spring-core/src/main/java/org/springframework/util/StringUtils.java
  2. 8
      spring-core/src/test/java/org/springframework/util/StringUtilsTests.java

50
spring-core/src/main/java/org/springframework/util/StringUtils.java

@ -140,6 +140,7 @@ public abstract class StringUtils { @@ -140,6 +140,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return false;
}
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
@ -174,6 +175,7 @@ public abstract class StringUtils { @@ -174,6 +175,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return false;
}
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (Character.isWhitespace(str.charAt(i))) {
@ -204,6 +206,7 @@ public abstract class StringUtils { @@ -204,6 +206,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
@ -225,6 +228,7 @@ public abstract class StringUtils { @@ -225,6 +228,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return str;
}
int len = str.length();
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0; i < len; i++) {
@ -246,6 +250,7 @@ public abstract class StringUtils { @@ -246,6 +250,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
@ -263,6 +268,7 @@ public abstract class StringUtils { @@ -263,6 +268,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
sb.deleteCharAt(sb.length() - 1);
@ -280,6 +286,7 @@ public abstract class StringUtils { @@ -280,6 +286,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && sb.charAt(0) == leadingCharacter) {
sb.deleteCharAt(0);
@ -297,6 +304,7 @@ public abstract class StringUtils { @@ -297,6 +304,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && sb.charAt(sb.length() - 1) == trailingCharacter) {
sb.deleteCharAt(sb.length() - 1);
@ -322,6 +330,7 @@ public abstract class StringUtils { @@ -322,6 +330,7 @@ public abstract class StringUtils {
if (str.length() < prefix.length()) {
return false;
}
String lcStr = str.substring(0, prefix.length()).toLowerCase();
String lcPrefix = prefix.toLowerCase();
return lcStr.equals(lcPrefix);
@ -376,6 +385,7 @@ public abstract class StringUtils { @@ -376,6 +385,7 @@ public abstract class StringUtils {
if (!hasLength(str) || !hasLength(sub)) {
return 0;
}
int count = 0;
int pos = 0;
int idx;
@ -398,10 +408,14 @@ public abstract class StringUtils { @@ -398,10 +408,14 @@ public abstract class StringUtils {
if (!hasLength(inString) || !hasLength(oldPattern) || newPattern == null) {
return inString;
}
StringBuilder sb = new StringBuilder();
int pos = 0; // our position in the old string
int index = inString.indexOf(oldPattern);
// the index of an occurrence we've found, or -1
if (index == -1) {
// no occurrence -> can return input as-is
return inString;
}
StringBuilder sb = new StringBuilder(inString.length());
int pos = 0; // our position in the old string
int patLen = oldPattern.length();
while (index >= 0) {
sb.append(inString.substring(pos, index));
@ -409,8 +423,8 @@ public abstract class StringUtils { @@ -409,8 +423,8 @@ public abstract class StringUtils {
pos = index + patLen;
index = inString.indexOf(oldPattern, pos);
}
// append any characters to the right of a match
sb.append(inString.substring(pos));
// remember to append any characters to the right of a match
return sb.toString();
}
@ -435,7 +449,8 @@ public abstract class StringUtils { @@ -435,7 +449,8 @@ public abstract class StringUtils {
if (!hasLength(inString) || !hasLength(charsToDelete)) {
return inString;
}
StringBuilder sb = new StringBuilder();
StringBuilder sb = new StringBuilder(inString.length());
for (int i = 0; i < inString.length(); i++) {
char c = inString.charAt(i);
if (charsToDelete.indexOf(c) == -1) {
@ -518,6 +533,7 @@ public abstract class StringUtils { @@ -518,6 +533,7 @@ public abstract class StringUtils {
if (!hasLength(str)) {
return str;
}
char baseChar = str.charAt(0);
char updatedChar;
if (capitalize) {
@ -529,6 +545,7 @@ public abstract class StringUtils { @@ -529,6 +545,7 @@ public abstract class StringUtils {
if (baseChar == updatedChar) {
return str;
}
char[] chars = str.toCharArray();
chars[0] = updatedChar;
return new String(chars, 0, chars.length);
@ -544,6 +561,7 @@ public abstract class StringUtils { @@ -544,6 +561,7 @@ public abstract class StringUtils {
if (path == null) {
return null;
}
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path);
}
@ -558,14 +576,17 @@ public abstract class StringUtils { @@ -558,14 +576,17 @@ public abstract class StringUtils {
if (path == null) {
return null;
}
int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
if (extIndex == -1) {
return null;
}
int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
if (folderIndex > extIndex) {
return null;
}
return path.substring(extIndex + 1);
}
@ -580,14 +601,17 @@ public abstract class StringUtils { @@ -580,14 +601,17 @@ public abstract class StringUtils {
if (path == null) {
return null;
}
int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
if (extIndex == -1) {
return path;
}
int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
if (folderIndex > extIndex) {
return path;
}
return path.substring(0, extIndex);
}
@ -756,8 +780,10 @@ public abstract class StringUtils { @@ -756,8 +780,10 @@ public abstract class StringUtils {
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
@ -825,6 +851,7 @@ public abstract class StringUtils { @@ -825,6 +851,7 @@ public abstract class StringUtils {
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;
@ -846,6 +873,7 @@ public abstract class StringUtils { @@ -846,6 +873,7 @@ public abstract class StringUtils {
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);
@ -869,6 +897,7 @@ public abstract class StringUtils { @@ -869,6 +897,7 @@ public abstract class StringUtils {
if (ObjectUtils.isEmpty(array2)) {
return array1;
}
List<String> result = new ArrayList<>();
result.addAll(Arrays.asList(array1));
for (String str : array2) {
@ -888,6 +917,7 @@ public abstract class StringUtils { @@ -888,6 +917,7 @@ public abstract class StringUtils {
if (ObjectUtils.isEmpty(array)) {
return new String[0];
}
Arrays.sort(array);
return array;
}
@ -903,6 +933,7 @@ public abstract class StringUtils { @@ -903,6 +933,7 @@ public abstract class StringUtils {
if (collection == null) {
return null;
}
return collection.toArray(new String[collection.size()]);
}
@ -917,6 +948,7 @@ public abstract class StringUtils { @@ -917,6 +948,7 @@ public abstract class StringUtils {
if (enumeration == null) {
return null;
}
List<String> list = Collections.list(enumeration);
return list.toArray(new String[list.size()]);
}
@ -931,6 +963,7 @@ public abstract class StringUtils { @@ -931,6 +963,7 @@ public abstract class StringUtils {
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];
@ -949,6 +982,7 @@ public abstract class StringUtils { @@ -949,6 +982,7 @@ public abstract class StringUtils {
if (ObjectUtils.isEmpty(array)) {
return array;
}
Set<String> set = new LinkedHashSet<>();
for (String element : array) {
set.add(element);
@ -973,6 +1007,7 @@ public abstract class StringUtils { @@ -973,6 +1007,7 @@ public abstract class StringUtils {
if (offset < 0) {
return null;
}
String beforeDelimiter = toSplit.substring(0, offset);
String afterDelimiter = toSplit.substring(offset + delimiter.length());
return new String[] {beforeDelimiter, afterDelimiter};
@ -1013,6 +1048,7 @@ public abstract class StringUtils { @@ -1013,6 +1048,7 @@ public abstract class StringUtils {
if (ObjectUtils.isEmpty(array)) {
return null;
}
Properties result = new Properties();
for (String element : array) {
if (charsToDelete != null) {
@ -1073,6 +1109,7 @@ public abstract class StringUtils { @@ -1073,6 +1109,7 @@ public abstract class StringUtils {
if (str == null) {
return null;
}
StringTokenizer st = new StringTokenizer(str, delimiters);
List<String> tokens = new ArrayList<>();
while (st.hasMoreTokens()) {
@ -1126,6 +1163,7 @@ public abstract class StringUtils { @@ -1126,6 +1163,7 @@ public abstract class StringUtils {
if (delimiter == null) {
return new String[] {str};
}
List<String> result = new ArrayList<>();
if ("".equals(delimiter)) {
for (int i = 0; i < str.length(); i++) {
@ -1187,6 +1225,7 @@ public abstract class StringUtils { @@ -1187,6 +1225,7 @@ public abstract class StringUtils {
if (CollectionUtils.isEmpty(coll)) {
return "";
}
StringBuilder sb = new StringBuilder();
Iterator<?> it = coll.iterator();
while (it.hasNext()) {
@ -1233,6 +1272,7 @@ public abstract class StringUtils { @@ -1233,6 +1272,7 @@ public abstract class StringUtils {
if (arr.length == 1) {
return ObjectUtils.nullSafeToString(arr[0]);
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i > 0) {

8
spring-core/src/test/java/org/springframework/util/StringUtilsTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -177,15 +177,15 @@ public class StringUtilsTests { @@ -177,15 +177,15 @@ public class StringUtilsTests {
// Non match: no change
s = StringUtils.replace(inString, "qwoeiruqopwieurpoqwieur", newPattern);
assertTrue("Replace non matched is equal", s.equals(inString));
assertSame("Replace non-matched is returned as-is", inString, s);
// Null new pattern: should ignore
s = StringUtils.replace(inString, oldPattern, null);
assertTrue("Replace non matched is equal", s.equals(inString));
assertSame("Replace non-matched is returned as-is", inString, s);
// Null old pattern: should ignore
s = StringUtils.replace(inString, null, newPattern);
assertTrue("Replace non matched is equal", s.equals(inString));
assertSame("Replace non-matched is returned as-is", inString, s);
}
@Test

Loading…
Cancel
Save