Repository: commons-lang Updated Branches: refs/heads/master 2dd459003 -> a069c490e
LANG-1143: StringUtils should use toXxxxCase(int) rather than toXxxxCase(char) (closes #201) based on patch by Sebb Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/a069c490 Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/a069c490 Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/a069c490 Branch: refs/heads/master Commit: a069c490e8119189fa2b43d3b597b79b3d42a367 Parents: 2dd4590 Author: pascalschumacher <pascalschumac...@gmx.net> Authored: Sun Oct 23 19:07:04 2016 +0200 Committer: pascalschumacher <pascalschumac...@gmx.net> Committed: Mon Oct 31 13:29:36 2016 +0100 ---------------------------------------------------------------------- src/changes/changes.xml | 5 +- .../org/apache/commons/lang3/StringUtils.java | 74 ++++++++++++-------- 2 files changed, 48 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-lang/blob/a069c490/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 4b8f2b4..d5dc634 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -46,8 +46,8 @@ The <action> type attribute can be add,update,fix,remove. <body> <release version="3.6" date="2016-MM-DD" description="TBD"> - <action issue="LANG-1269" type="fix" dev="paschuma">Wrong name or result of StringUtils#getJaroWinklerDistance</action> - <action issue="LANG-1188" type="fix" dev="paschuma">StringUtils#join(T...): warning: [unchecked] Possible heap pollution from parameterized vararg type T</action> + <action issue="LANG-1269" type="fix" dev="pschumacher">Wrong name or result of StringUtils#getJaroWinklerDistance</action> + <action issue="LANG-1188" type="fix" dev="pschumacher">StringUtils#join(T...): warning: [unchecked] Possible heap pollution from parameterized vararg type T</action> <action issue="LANG-1144" type="fix" dev="ggregory" due-to="Waldemar Maier, Gary Gregory">Multiple calls of org.apache.commons.lang3.concurrent.LazyInitializer.initialize() are possible.</action> <action issue="LANG-1276" type="fix" dev="pschumacher" due-to="Andy Klimczak">StrBuilder#replaceAll ArrayIndexOutOfBoundsException</action> <action issue="LANG-1278" type="fix" dev="pschumacher" due-to="Duke Yin">BooleanUtils javadoc issues</action> @@ -57,6 +57,7 @@ The <action> type attribute can be add,update,fix,remove. <action issue="LANG-1270" type="add" dev="pschumacher" due-to="Pierre Templier">Add StringUtils#isAnyNotEmpty and #isAnyNotBlank</action> <action issue="LANG-1277" type="update" dev="pschumacher" due-to="yufcuy">StringUtils#getLevenshteinDistance reduce memory consumption</action> <action issue="LANG-1279" type="update" dev="ggregory">Update Java requirement from Java 6 to 7.</action> + <action issue="LANG-1143" type="update" dev="pschumacher" due-to="sebb">StringUtils should use toXxxxCase(int) rather than toXxxxCase(char)</action> </release> <release version="3.5" date="2016-10-13" description="New features including Java 9 detection"> http://git-wip-us.apache.org/repos/asf/commons-lang/blob/a069c490/src/main/java/org/apache/commons/lang3/StringUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java b/src/main/java/org/apache/commons/lang3/StringUtils.java index dbd7ff4..d52ee9f 100644 --- a/src/main/java/org/apache/commons/lang3/StringUtils.java +++ b/src/main/java/org/apache/commons/lang3/StringUtils.java @@ -6600,7 +6600,7 @@ public class StringUtils { /** * <p>Capitalizes a String changing the first character to title case as - * per {@link Character#toTitleCase(char)}. No other characters are changed.</p> + * per {@link Character#toTitleCase(int)}. No other characters are changed.</p> * * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#capitalize(String)}. * A {@code null} input String returns {@code null}.</p> @@ -6625,22 +6625,27 @@ public class StringUtils { return str; } - final char firstChar = str.charAt(0); - final char newChar = Character.toTitleCase(firstChar); - if (firstChar == newChar) { + final int firstCodepoint = str.codePointAt(0); + final int newCodePoint = Character.toTitleCase(firstCodepoint); + if (firstCodepoint == newCodePoint) { // already capitalized return str; } - final char[] newChars = new char[strLen]; - newChars[0] = newChar; - str.getChars(1,strLen, newChars, 1); - return String.valueOf(newChars); + int newCodePoints[] = new int[strLen]; // cannot be longer than the char array + int outOffset = 0; + newCodePoints[outOffset++] = newCodePoint; // copy the first codepoint + for (int inOffset = Character.charCount(firstCodepoint); inOffset < strLen; ) { + final int codepoint = str.codePointAt(inOffset); + newCodePoints[outOffset++] = codepoint; // copy the remaining ones + inOffset += Character.charCount(codepoint); + } + return new String(newCodePoints, 0, outOffset); } /** * <p>Uncapitalizes a String, changing the first character to lower case as - * per {@link Character#toLowerCase(char)}. No other characters are changed.</p> + * per {@link Character#toLowerCase(int)}. No other characters are changed.</p> * * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#uncapitalize(String)}. * A {@code null} input String returns {@code null}.</p> @@ -6665,17 +6670,22 @@ public class StringUtils { return str; } - final char firstChar = str.charAt(0); - final char newChar = Character.toLowerCase(firstChar); - if (firstChar == newChar) { - // already uncapitalized + final int firstCodepoint = str.codePointAt(0); + final int newCodePoint = Character.toLowerCase(firstCodepoint); + if (firstCodepoint == newCodePoint) { + // already capitalized return str; } - final char[] newChars = new char[strLen]; - newChars[0] = newChar; - str.getChars(1,strLen, newChars, 1); - return String.valueOf(newChars); + int newCodePoints[] = new int[strLen]; // cannot be longer than the char array + int outOffset = 0; + newCodePoints[outOffset++] = newCodePoint; // copy the first codepoint + for (int inOffset = Character.charCount(firstCodepoint); inOffset < strLen; ) { + final int codepoint = str.codePointAt(inOffset); + newCodePoints[outOffset++] = codepoint; // copy the remaining ones + inOffset += Character.charCount(codepoint); + } + return new String(newCodePoints, 0, outOffset); } /** @@ -6710,19 +6720,25 @@ public class StringUtils { return str; } - final char[] buffer = str.toCharArray(); - - for (int i = 0; i < buffer.length; i++) { - final char ch = buffer[i]; - if (Character.isUpperCase(ch)) { - buffer[i] = Character.toLowerCase(ch); - } else if (Character.isTitleCase(ch)) { - buffer[i] = Character.toLowerCase(ch); - } else if (Character.isLowerCase(ch)) { - buffer[i] = Character.toUpperCase(ch); + final int strLen = str.length(); + int newCodePoints[] = new int[strLen]; // cannot be longer than the char array + int outOffset = 0; + for (int i = 0; i < strLen; ) { + final int oldCodepoint = str.codePointAt(i); + final int newCodePoint; + if (Character.isUpperCase(oldCodepoint)) { + newCodePoint = Character.toLowerCase(oldCodepoint); + } else if (Character.isTitleCase(oldCodepoint)) { + newCodePoint = Character.toLowerCase(oldCodepoint); + } else if (Character.isLowerCase(oldCodepoint)) { + newCodePoint = Character.toUpperCase(oldCodepoint); + } else { + newCodePoint = oldCodepoint; } - } - return new String(buffer); + newCodePoints[outOffset++] = newCodePoint; + i += Character.charCount(newCodePoint); + } + return new String(newCodePoints, 0, outOffset); } // Count matches