3.5 Maps of Enums
Once you've gotten your fingers used to typing public enum, you'll start
to find all sorts of interesting uses for enums. Once you've gotten past
the very basic constant-replacement, you'll start to see that they also
serve as great keys, or indices, in
collection-type structures. Apparently
the Sun guys thought the same thing, and provided a nice facility for
working with enums as indices.
3.5.1 How do I do that?
In the old, archaic, pre-Tiger days (snicker, snicker), you might have used
a constants class like OldAntStatus (you'll remember a similar class from
Example 3-3):
You might then write a simple array of messages that are associated with
public class OldAntStatus {
public static final int INITIALIZING = 0;
public static final int COMPILING = 1;
public static final int COPYING = 2;
public static final int JARRING = 3;
public static final int ZIPPING = 4;
public static final int DONE = 5;
public static final int ERROR = 6;
}
each of these status codes:
You can then access the appropriate message using the constant:
String[] antMessages = new String[] {
"Initalizing Ant...", // INITIALIZING
"Compiling Java classes...", // COMPILING
"Copying files...", // COPYING
"JARring up files...", // JARRING
"ZIPping up files...", // ZIPPING
"Build complete.", // DONE
"Error occurred." // ERROR
}
It's a pretty valid desire to want to accomplish the same sorts of tasks
int antStatus = antProcess.getStatus( );
out.println("ant> " + antMessages[antStatus]);
with enumerated types, and get all the benefits of enums along the way.
You'll need to use the java.util.EnumMap class to accomplish this, which
is a new collection type just perfect for the job. First, you need to define
the enum you want to use for a keyset, as shown in Example 3-4.
Example 3-4. An enum to use for a keyset
You can now create a new EnumMap, in conjunction with generics
package com.oreilly.tiger.ch03;
public enum AntStatus {
INITIALIZING,
COMPILING,
COPYING,
JARRING,
ZIPPING,
DONE,
ERROR
}
declare the enumerated type you want to use for the key, and the class
type you want to use for the value:
Then, when creating a new instance, you pass the EnumMap the Class
EnumMap<AntStatus, String> antMessages;
object for the enum used for the keyset:
EnumMap<AntStatus, String> antMessages =
EnumMap<AntStatus, String>(AntStatus.class);
|
declare the types
being used, key
and value, in both
the variable
declaration and
the variable
instantiation.Once the initialization is taken care of, things get very simple. You just
seed the values, and use them:
NOTEThis code is in
public void testEnumMap(PrintStream out) throws IOException {
// Create a map with the key and a String message
EnumMap<AntStatus, String> antMessages =
new EnumMap<AntStatus, String>(AntStatus.class);
// Initialize the map
antMessages.put(AntStatus.INITIALIZING, "Initializing Ant...");
antMessages.put(AntStatus.COMPILING, "Compiling Java classes...");
antMessages.put(AntStatus.COPYING, "Copying files...");
antMessages.put(AntStatus.JARRING, "JARring up files...");
antMessages.put(AntStatus.ZIPPING, "ZIPping up files...");
antMessages.put(AntStatus.DONE, "Build complete.");
antMessages.put(AntStatus.ERROR, "Error occurred.");
// Iterate and print messages
for (AntStatus status : AntStatus.values( ) ) {
out.println("For status " + status + ", message is: " +
antMessages.get(status));
}
}
AntStatusTester.
java.Running this code nicely prints out all the status codes, and the associated
message with each:
Of course, as an added benefit, EnumMap protects you from mis-ordering
[echo] Running AntStatusTester...
[java] For status INITIALIZING, message is: Initializing Ant...
[java] For status COMPILING, message is: Compiling Java classes...
[java] For status COPYING, message is: Copying files...
[java] For status JARRING, message is: JARring up files...
[java] For status ZIPPING, message is: ZIPping up files...
[java] For status DONE, message is: Build complete.
[java] For status ERROR, message is: Error occurred.
when initializing values, reordering in the enumerated type, and just
about any other strange situation that can arise from more than one person
working on code at the same time.