在字符串上使用switch
在JDK 7中,switch语句进行了小幅升级,现在可以在字符串上使用switch了,你可以给switch语句提供一个字符串表达式,也可以给每个case提供一个常量字符串表达式,清单1是一个使用这个特性的WC(字数统计)程序的代码。
清单1 WC.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.
}
}
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.
}
}
上面的例子充分说明了处理命令行参数时在字符串上使用switch是很有用的,可以替代这个功能的是if-else if … else表达式,但这样一来会使代码更冗长。
编译好WC.java后,指定(-i或I,区分大小写)和(-v或-V,输出详细信息)命令行参数运行这个程序,如:
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.
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.