Author: bayard Date: Tue Jul 20 19:10:34 2010 New Revision: 965963 URL: http://svn.apache.org/viewvc?rev=965963&view=rev Log: Refactoring toBoolean(String) and toBooleanObject(String) so that the latter has the same optimizations. I did this by pointing the former to the latter. I had to rewrite the optimizations a bit so they didn't auto-return as the latter considers null and false to be different. I also had to add specific support for false, no and off for the same reason. LANG-633
Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/BooleanUtils.java commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/BooleanUtils.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/BooleanUtils.java?rev=965963&r1=965962&r2=965963&view=diff ============================================================================== --- commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/BooleanUtils.java (original) +++ commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/BooleanUtils.java Tue Jul 20 19:10:34 2010 @@ -544,20 +544,84 @@ public class BooleanUtils { * <code>null</code> if no match or <code>null</code> input */ public static Boolean toBooleanObject(String str) { - if ("true".equalsIgnoreCase(str)) { - return Boolean.TRUE; - } else if ("false".equalsIgnoreCase(str)) { - return Boolean.FALSE; - } else if ("on".equalsIgnoreCase(str)) { - return Boolean.TRUE; - } else if ("off".equalsIgnoreCase(str)) { - return Boolean.FALSE; - } else if ("yes".equalsIgnoreCase(str)) { + // Previously used equalsIgnoreCase, which was fast for interned 'true'. + // Non interned 'true' matched 15 times slower. + // + // Optimisation provides same performance as before for interned 'true'. + // Similar performance for null, 'false', and other strings not length 2/3/4. + // 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower. + if (str == "true") { return Boolean.TRUE; - } else if ("no".equalsIgnoreCase(str)) { - return Boolean.FALSE; } - // no match + if (str == null) { + return null; + } + switch (str.length()) { + case 2: { + char ch0 = str.charAt(0); + char ch1 = str.charAt(1); + if ((ch0 == 'o' || ch0 == 'O') && + (ch1 == 'n' || ch1 == 'N') ) + { + return true; + } + if ((ch0 == 'n' || ch0 == 'N') && + (ch1 == 'o' || ch1 == 'O') ) + { + return false; + } + break; + } + case 3: { + char ch0 = str.charAt(0); + char ch1 = str.charAt(1); + char ch2 = str.charAt(2); + if ((ch0 == 'y' || ch0 == 'Y') && + (ch1 == 'e' || ch1 == 'E') && + (ch2 == 's' || ch2 == 'S') ) + { + return true; + } + if ((ch0 == 'o' || ch0 == 'O') && + (ch1 == 'f' || ch1 == 'F') && + (ch2 == 'f' || ch2 == 'F') ) + { + return false; + } + break; + } + case 4: { + char ch0 = str.charAt(0); + char ch1 = str.charAt(1); + char ch2 = str.charAt(2); + char ch3 = str.charAt(3); + if ((ch0 == 't' || ch0 == 'T') && + (ch1 == 'r' || ch1 == 'R') && + (ch2 == 'u' || ch2 == 'U') && + (ch3 == 'e' || ch3 == 'E') ) + { + return true; + } + break; + } + case 5: { + char ch0 = str.charAt(0); + char ch1 = str.charAt(1); + char ch2 = str.charAt(2); + char ch3 = str.charAt(3); + char ch4 = str.charAt(4); + if ((ch0 == 'f' || ch0 == 'F') && + (ch1 == 'a' || ch1 == 'A') && + (ch2 == 'l' || ch2 == 'L') && + (ch3 == 's' || ch3 == 'S') && + (ch4 == 'e' || ch4 == 'E') ) + { + return false; + } + break; + } + } + return null; } @@ -631,57 +695,7 @@ public class BooleanUtils { * @return the boolean value of the string, <code>false</code> if no match */ public static boolean toBoolean(String str) { - // Previously used equalsIgnoreCase, which was fast for interned 'true'. - // Non interned 'true' matched 15 times slower. - // - // Optimisation provides same performance as before for interned 'true'. - // Similar performance for null, 'false', and other strings not length 2/3/4. - // 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower. - if (str == "true") { - return true; - } - if (str == null) { - return false; - } - switch (str.length()) { - case 2: { - char ch0 = str.charAt(0); - char ch1 = str.charAt(1); - return - (ch0 == 'o' || ch0 == 'O') && - (ch1 == 'n' || ch1 == 'N'); - } - case 3: { - char ch = str.charAt(0); - if (ch == 'y') { - return - (str.charAt(1) == 'e' || str.charAt(1) == 'E') && - (str.charAt(2) == 's' || str.charAt(2) == 'S'); - } - if (ch == 'Y') { - return - (str.charAt(1) == 'E' || str.charAt(1) == 'e') && - (str.charAt(2) == 'S' || str.charAt(2) == 's'); - } - return false; - } - case 4: { - char ch = str.charAt(0); - if (ch == 't') { - return - (str.charAt(1) == 'r' || str.charAt(1) == 'R') && - (str.charAt(2) == 'u' || str.charAt(2) == 'U') && - (str.charAt(3) == 'e' || str.charAt(3) == 'E'); - } - if (ch == 'T') { - return - (str.charAt(1) == 'R' || str.charAt(1) == 'r') && - (str.charAt(2) == 'U' || str.charAt(2) == 'u') && - (str.charAt(3) == 'E' || str.charAt(3) == 'e'); - } - } - } - return false; + return toBooleanObject(str) == Boolean.TRUE; } /** Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java?rev=965963&r1=965962&r2=965963&view=diff ============================================================================== --- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java (original) +++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java Tue Jul 20 19:10:34 2010 @@ -241,6 +241,9 @@ public class BooleanUtilsTest extends Te assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("ON")); assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("YES")); assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TruE")); + + assertEquals(null, BooleanUtils.toBooleanObject("ab")); + assertEquals(null, BooleanUtils.toBooleanObject("yoo")); } public void test_toBooleanObject_String_String_String_String() { @@ -306,6 +309,10 @@ public class BooleanUtilsTest extends Te assertEquals(true, BooleanUtils.toBoolean("YES")); assertEquals(false, BooleanUtils.toBoolean("yes?")); assertEquals(false, BooleanUtils.toBoolean("tru")); + + assertEquals(false, BooleanUtils.toBoolean("no")); + assertEquals(false, BooleanUtils.toBoolean("off")); + assertEquals(false, BooleanUtils.toBoolean("yoo")); } public void test_toBoolean_String_String_String() {