Author: niallp Date: Sun Jan 9 00:40:03 2011 New Revision: 1056846 URL: http://svn.apache.org/viewvc?rev=1056846&view=rev Log: Port LANG-633 to LANG 2.x Branch - use same optimization in toBooleanObject(String) as in toBoolean(String)
Modified: commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/BooleanUtils.java commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/BooleanUtilsTest.java Modified: commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/BooleanUtils.java URL: http://svn.apache.org/viewvc/commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/BooleanUtils.java?rev=1056846&r1=1056845&r2=1056846&view=diff ============================================================================== --- commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/BooleanUtils.java (original) +++ commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/BooleanUtils.java Sun Jan 9 00:40:03 2011 @@ -560,20 +560,98 @@ 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 1: { + char ch0 = str.charAt(0); + if ((ch0 == 'y' || ch0 == 'Y') || + (ch0 == 't' || ch0 == 'T')) + { + return Boolean.TRUE; + } + if ((ch0 == 'n' || ch0 == 'N') || + (ch0 == 'f' || ch0 == 'F')) + { + return Boolean.FALSE; + } + break; + } + case 2: { + char ch0 = str.charAt(0); + char ch1 = str.charAt(1); + if ((ch0 == 'o' || ch0 == 'O') && + (ch1 == 'n' || ch1 == 'N') ) + { + return Boolean.TRUE; + } + if ((ch0 == 'n' || ch0 == 'N') && + (ch1 == 'o' || ch1 == 'O') ) + { + return Boolean.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 Boolean.TRUE; + } + if ((ch0 == 'o' || ch0 == 'O') && + (ch1 == 'f' || ch1 == 'F') && + (ch2 == 'f' || ch2 == 'F') ) + { + return Boolean.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 Boolean.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 Boolean.FALSE; + } + break; + } + } + return null; } @@ -644,60 +722,10 @@ public class BooleanUtils { * </pre> * * @param str the String to check - * @return the boolean value of the string, <code>false</code> if no match + * @return the boolean value of the string, <code>false</code> if no match or the String is null */ 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/branches/LANG_2_X/src/test/java/org/apache/commons/lang/BooleanUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/BooleanUtilsTest.java?rev=1056846&r1=1056845&r2=1056846&view=diff ============================================================================== --- commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/BooleanUtilsTest.java (original) +++ commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/BooleanUtilsTest.java Sun Jan 9 00:40:03 2011 @@ -246,6 +246,20 @@ public class BooleanUtilsTest extends Te assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("ON")); assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("YES")); assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TruE")); + assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TruE")); + + assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("y")); + assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("Y")); + assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("t")); + assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("T")); + assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("f")); + assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("F")); + assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("n")); + assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("N")); + assertEquals(null, BooleanUtils.toBooleanObject("z")); + + assertEquals(null, BooleanUtils.toBooleanObject("ab")); + assertEquals(null, BooleanUtils.toBooleanObject("yoo")); } public void test_toBooleanObject_String_String_String_String() { @@ -311,6 +325,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() {