- What to Expect for JDK 7
- Binary Literals
- Switch on String
- Underscores in Integer Literals
- Conclusion
Switch on String
The switch statement is getting a minor upgrade in JDK 7. You'll now be able to switch on string values, thanks to Joe Darcy's Strings in Switch Project Coin proposal.
With switch on string, you supply a string expression to the switch statement, and also supply constant string expressions to each of the cases. Listing 1's source code to a WC (Word Count) application demonstrates this feature.
Listing 1WC.java
// WC.java import java.io.IOException; public class WC { public static void main (String [] args) throws IOException { boolean caseInsensitive = false; boolean verbose = false; for (String arg: args) switch (arg) { case "-i": case "-I": caseInsensitive = true; break; case "-V": case "-v": verbose = true; break; default : System.err.println ("usage : "+ "java WC [-i|-I -v|-V] stdin"); System.err.println ("example: java WC -v <WC.java"); return; } if (verbose) countWordsVerbose (caseInsensitive); else countWords (); } static void countWords () throws IOException { int ch, nWords = 0; while ((ch = System.in.read ()) != -1) { if (Character.isLetter (ch)) // Start of word is indicated by letter. { do { ch = System.in.read (); } while (Character.isLetterOrDigit (ch)); nWords++; } } System.out.println ("\nTotal words = " + nWords); } static void countWordsVerbose (boolean caseInsensitive) throws IOException { int ch; WordNode root = null; while ((ch = System.in.read ()) != -1) { if (Character.isLetter (ch)) // Start of word is indicated by letter. { StringBuffer sb = new StringBuffer (); do { sb.append ((char) ch); ch = System.in.read (); } while (Character.isLetterOrDigit (ch)); if (root == null) root = new WordNode (sb.toString ()); else root.insert (sb.toString (), caseInsensitive); } } display (root); } static void display (WordNode root) { // root == null when leaf node has been reached (or perhaps there are no // words in tree) if (root == null) return; // Display all words lexicographically less than the word in the current // node. display (root.left); // Display current node's word and number of occurrences. System.out.println ("Word = " + root.word + ", Count = " + root.count); // Display all words lexicographically greater than the word in the // current node. display (root.right); } } class WordNode { String word; // Stored word int count = 1; // Number of occurrences of word in text WordNode left; // Left subtree WordNode right; // Right subtree public WordNode (String word) { this.word = word; left = right = null; } public void insert (String word, boolean caseInsensitive) { int order = (caseInsensitive) ? this.word.compareToIgnoreCase (word) : this.word.compareTo (word); if (order > 0) // word argument lexicographically less than current // word { // If left-most leaf node reached then insert new node as its // left-most leaf node; otherwise, keep searching left. if (left == null) left = new WordNode (word); else left.insert (word, caseInsensitive); } else if (order < 0) // word argument lexicographically greater than current // word { // If right-most leaf node reached then insert new node as its // right-most leaf node; otherwise, keep searching right. if (right == null) right = new WordNode (word); else right.insert (word, caseInsensitive); } else this.count++; // Update number of found occurrences. } }
Listing 1 demonstrates the usefulness of switch on string in processing command-line arguments to clarify source code. The alternative to this feature would be an if-else if-...-else expression, which some developers might view as making the source code a bit more verbose.
After compiling WC.java, run this application by optionally specifying the case-insensitive (-i or -I) and verbose (-v or -V) command-line options, the < character (redirecting standard input) and the name of a file. Here are some examples:
java WC <WC.java // Count the number of words in WC.java and report the total. java WC -v <WC.java // Count the number of occurrences of each word in WC.java and report // each total. java WC -i -v <WC.java // Count the number of occurrences of each word in WC.java and report // each total. Use a case-insensitive comparison so that, for example, // this and This are treated as two occurrences of the same word instead // of one occurrence each of two different words.
Re[ae]mi Forax's Strings in switch and closures blog post also demonstrates switch on string in the context of processing command-line arguments.