String
switch
A string
has a value (like "cat"). In a switch
statement we can select that value and match it. Java supports string
switches.
In a string
switch
, case is important. Lowercase and uppercase letters are not equal. As for performance, a string
switch
is usually less fast than a HashMap
or expression.
Here we introduce a logical method that matches the names of moths. I am not a moth expert, but these names are interesting.
isMoth
method returns true if a moth name is detected, and false otherwise.string
is matched in the isMoth
method, we reach the default case, where false is returned.public class Program { static boolean isMoth(String value) { // Switch on a string. // ... Match names of some moths. switch (value) { case "Atlas Moth": case "Beet Armyworm": case "Indian Meal Moth": case "Ash Pug": case "Latticed Heath": case "Ribald Wave": case "The Streak": return true; default: return false; } } public static void main(String[] args) { // Test the isMoth method. System.out.println(isMoth("Atlas Moth")); System.out.println(isMoth("atlas moth")); // Case matters. System.out.println(isMoth("Chiloe")); } }true false false
string
switch
Let us consider the performance of string
switches. Here we have two methods, both of which return the same values.
IsMoth
uses a switch
statement to detect the names of moths. It is the same as the first example.IsMothOr
uses an expression with string
equality and logical ors. It could be written as an if
-statement.HashMap
and its containsKey
method. The values are added at the start of main.isMothOr
performed better than the string
switch
and the HashMap
.import java.util.HashMap; public class Program { static boolean isMoth(String value) { switch (value) { case "Atlas Moth": case "Beet Armyworm": case "Indian Meal Moth": case "Ash Pug": case "Latticed Heath": case "Ribald Wave": case "The Streak": return true; default: return false; } } static boolean isMothOr(String value) { return value == "Atlas Moth" || value == "Beet Armyworm" || value == "Indian Meal Moth" || value == "Ash Pug" || value == "Latticed Heath" || value == "Ribald Wave" || value == "The Streak"; } public static void main(String[] args) throws Exception { // Initialize HashMap. HashMap<String, Boolean> hash = new HashMap<>(); hash.put("Atlas Moth", true); hash.put("Beet Armyworm", true); hash.put("Indian Meal Moth", true); hash.put("Ash Pug", true); hash.put("Latticed Heath", true); hash.put("Ribald Wave", true); hash.put("The Streak", true); String[] tests = { "Ribald Wave", "Java", "Beet Armyworm", "Python" }; int max = 100000000; long t1 = System.currentTimeMillis(); // Version 1: switch. for (int i = 0; i < max; i++) { int count = 0; for (String test : tests) { if (isMoth(test)) { count++; } } if (count != 2) { throw new Exception(); } } long t2 = System.currentTimeMillis(); // Version 2: or-expression. for (int i = 0; i < max; i++) { int count = 0; for (String test : tests) { if (isMothOr(test)) { count++; } } if (count != 2) { throw new Exception(); } } long t3 = System.currentTimeMillis(); // Version 3: use HashMap. for (int i = 0; i < max; i++) { int count = 0; for (String test : tests) { if (hash.containsKey(test)) { count++; } } if (count != 2) { throw new Exception(); } } long t4 = System.currentTimeMillis(); // Results. System.out.println(t2 - t1); System.out.println(t3 - t2); System.out.println(t4 - t3); } }1236 ms Switch 801 ms Or 2147 ms HashMap
For small groups of strings, an expression (with logical ors) is fastest. But when more data are present, we should optimize with a HashMap
.
string
switch
is convenient, but in my test it was slower than either the expressions or the HashMap
.isMothOr
seems better. Benchmarks are optimized by the JIT compiler, so they can be misleading.String
switches are easy to write in Java. Sadly they do not appear to have a performance edge—expressions and HashMap
lookups (with containsKey
) tend to be faster.