diff --git a/gson/src/main/java/com/google/gson/FieldNamingPolicy.java b/gson/src/main/java/com/google/gson/FieldNamingPolicy.java index 1f1eb8f1..2e833cd0 100644 --- a/gson/src/main/java/com/google/gson/FieldNamingPolicy.java +++ b/gson/src/main/java/com/google/gson/FieldNamingPolicy.java @@ -159,31 +159,20 @@ public enum FieldNamingPolicy implements FieldNamingStrategy { * Ensures the JSON field names begins with an upper case letter. */ static String upperCaseFirstLetter(String name) { - StringBuilder fieldNameBuilder = new StringBuilder(); - int index = 0; - char firstCharacter = name.charAt(index); - int length = name.length(); + int firstLetterIndex = 0; + int limit = name.length() - 1; + for(; !Character.isLetter(name.charAt(firstLetterIndex)) && firstLetterIndex < limit; ++firstLetterIndex); - while (index < length - 1) { - if (Character.isLetter(firstCharacter)) { - break; - } - - fieldNameBuilder.append(firstCharacter); - firstCharacter = name.charAt(++index); - } - - if (!Character.isUpperCase(firstCharacter)) { - String modifiedTarget = modifyString(Character.toUpperCase(firstCharacter), name, ++index); - return fieldNameBuilder.append(modifiedTarget).toString(); - } else { + char firstLetter = name.charAt(firstLetterIndex); + if(Character.isUpperCase(firstLetter)) { //The letter is already uppercased, return the original return name; } - } - private static String modifyString(char firstCharacter, String srcString, int indexOfSubstring) { - return (indexOfSubstring < srcString.length()) - ? firstCharacter + srcString.substring(indexOfSubstring) - : String.valueOf(firstCharacter); + char uppercased = Character.toUpperCase(firstLetter); + if(firstLetterIndex == 0) { //First character in the string is the first letter, saves 1 substring + return uppercased + name.substring(1); + } + + return name.substring(0, firstLetterIndex) + uppercased + name.substring(firstLetterIndex + 1); } } diff --git a/gson/src/test/java/com/google/gson/functional/FieldNamingTest.java b/gson/src/test/java/com/google/gson/functional/FieldNamingTest.java index 5d326af8..4e383ec8 100644 --- a/gson/src/test/java/com/google/gson/functional/FieldNamingTest.java +++ b/gson/src/test/java/com/google/gson/functional/FieldNamingTest.java @@ -33,7 +33,7 @@ public final class FieldNamingTest extends TestCase { Gson gson = getGsonWithNamingPolicy(IDENTITY); assertEquals("{'lowerCamel':1,'UpperCamel':2,'_lowerCamelLeadingUnderscore':3," + "'_UpperCamelLeadingUnderscore':4,'lower_words':5,'UPPER_WORDS':6," + - "'annotatedName':7,'lowerId':8}", + "'annotatedName':7,'lowerId':8,'_9':9}", gson.toJson(new TestNames()).replace('\"', '\'')); } @@ -41,7 +41,7 @@ public final class FieldNamingTest extends TestCase { Gson gson = getGsonWithNamingPolicy(UPPER_CAMEL_CASE); assertEquals("{'LowerCamel':1,'UpperCamel':2,'_LowerCamelLeadingUnderscore':3," + "'_UpperCamelLeadingUnderscore':4,'Lower_words':5,'UPPER_WORDS':6," + - "'annotatedName':7,'LowerId':8}", + "'annotatedName':7,'LowerId':8,'_9':9}", gson.toJson(new TestNames()).replace('\"', '\'')); } @@ -49,7 +49,7 @@ public final class FieldNamingTest extends TestCase { Gson gson = getGsonWithNamingPolicy(UPPER_CAMEL_CASE_WITH_SPACES); assertEquals("{'Lower Camel':1,'Upper Camel':2,'_Lower Camel Leading Underscore':3," + "'_ Upper Camel Leading Underscore':4,'Lower_words':5,'U P P E R_ W O R D S':6," + - "'annotatedName':7,'Lower Id':8}", + "'annotatedName':7,'Lower Id':8,'_9':9}", gson.toJson(new TestNames()).replace('\"', '\'')); } @@ -57,7 +57,7 @@ public final class FieldNamingTest extends TestCase { Gson gson = getGsonWithNamingPolicy(LOWER_CASE_WITH_UNDERSCORES); assertEquals("{'lower_camel':1,'upper_camel':2,'_lower_camel_leading_underscore':3," + "'__upper_camel_leading_underscore':4,'lower_words':5,'u_p_p_e_r__w_o_r_d_s':6," + - "'annotatedName':7,'lower_id':8}", + "'annotatedName':7,'lower_id':8,'_9':9}", gson.toJson(new TestNames()).replace('\"', '\'')); } @@ -65,7 +65,7 @@ public final class FieldNamingTest extends TestCase { Gson gson = getGsonWithNamingPolicy(LOWER_CASE_WITH_DASHES); assertEquals("{'lower-camel':1,'upper-camel':2,'_lower-camel-leading-underscore':3," + "'_-upper-camel-leading-underscore':4,'lower_words':5,'u-p-p-e-r_-w-o-r-d-s':6," + - "'annotatedName':7,'lower-id':8}", + "'annotatedName':7,'lower-id':8,'_9':9}", gson.toJson(new TestNames()).replace('\"', '\'')); } @@ -85,5 +85,6 @@ public final class FieldNamingTest extends TestCase { int UPPER_WORDS = 6; @SerializedName("annotatedName") int annotated = 7; int lowerId = 8; + int _9 = 9; } }