HomeSearch

Java String Switch Example: Switch Versus HashMap

This Java example page uses switch statements on Strings. It benchmarks expressions, HashMap and String switches.
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.
Simple example. Here we introduce a logical method that matches the names of moths. I am not a moth expert, but these names are interesting.

Return: The isMoth method returns true if a moth name is detected, and false otherwise.

Return

Default: When no string is matched in the isMoth method, we reach the default case, where false is returned.

Java program that uses string switch 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")); } } Output true false false
Performance test. Let us consider the performance of string switches. Here we have two methods, both of which return the same values.

IsMoth: This uses a switch statement to detect the names of moths. It is the same as the first example.

IsMothOr: This uses an expression with string equality and logical ors. It could be written as an if-statement.

If

Result: After 5 runs of each method, I found that the expression-based isMothOr performed better.

Java program that benchmarks string switch, expression 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 { String[] tests = { "Ribald Wave", "Java", "Beet Armyworm", "Python" }; // Call both methods. boolean x = isMoth(""); x = isMothOr(""); System.out.println(x); long t1 = System.currentTimeMillis(); // ... Change isMoth to isMothOr to test expression version. for (int i = 0; i < 100000000; i++) { int count = 0; for (String test : tests) { if (isMoth(test)) { count++; } } if (count != 2) { throw new Exception(); } } long t2 = System.currentTimeMillis(); // ... Time. System.out.println(t2 - t1); } } Output isMoth: 1058 ms isMoth: 1672 ms isMoth: 1672 ms isMoth: 1672 ms isMoth: 1781 ms isMothOr: 844 ms isMothOr: 859 ms isMothOr: 843 ms isMothOr: 688 ms isMothOr: 875 ms
This benchmark has flaws, but overall isMothOr seemed better. In Java, benchmarks are optimized by the JIT compiler, so they can be misleading.
HashMap performance. Does a string switch come close to the performance of a HashMap? In my investigation, I found that a HashMap was superior to a string switch.HashMap

ContainsKey: I use containsKey on the HashMap to search for a matching string value. This computes a hash code.

Result: On the test system, I found that the HashMap was faster than a string switch, but slower than the expression version.

Java program that benchmarks HashMap import java.util.HashMap; public class Program { public static void main(String[] args) throws Exception { String[] tests = { "Ribald Wave", "Java", "Beet Armyworm", "Python" }; // 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); long t1 = System.currentTimeMillis(); // ... This version uses containsKey on a HashMap. for (int i = 0; i < 100000000; i++) { int count = 0; for (String test : tests) { if (hash.containsKey(test)) { count++; } } if (count != 2) { throw new Exception(); } } long t2 = System.currentTimeMillis(); // ... Time. System.out.println(t2 - t1); } } Output containsKey: 1108 ms containsKey: 1119 ms containsKey: 1117 ms containsKey: 1126 ms containsKey: 1108 ms
Some comments. For small groups of strings, an expression (with logical ors) is fastest. But when more data are present, we should optimize with a HashMap.

Switch: The string switch is convenient, but in my test it was slower than either the expressions or the HashMap.

A review. 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.
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
Home
Dot Net Perls