[Tony]: You might mean a reverse mapping, and it makes no sense; your example reverse mapping is specific to your enum type (not all enums have a reverse mapping from a char to the enum type). It's true that you can't do this particular type of mapping in general for all enums. However it certainly can be done for this particular mapping. "It makes no sense" makes no sense here, IMO.
In fact, enums already have a reverse lookup built in - the valueOf() method defined in
java.lang.Enum. It uses Strings - specifically, it uses the identifiers for the specific values of the enum. So Sonny could do something like this:
Instances can then be looked up easily:
The downside of this is that it forces us to use identifiers which duplicate the database values. This results in a loss of readability if we would have preferred a name like North rather than N. It may also require us to abandon conventional
Java naming conventions in order to match the DB values. Still, it may be acceptable to put up with these problems, as it's extremely quick and easy to create the enum in this case - no methods need to be coded at all.
Also, reverse mappings should be provided with O(1) lookup, not O(n) that is provided by switch/case (one of two fundamental reasons why switch/case should never be used). Actually switch statements are quite capable of providing O(1) lookup - that's what the tableswitch instruction in the JVM is for. Of course, the compiler doesn't bother using a tableswitch for low values of N like 4, as in Sonny's example. The overhead in setting up the table isn't warranted - it's faster to use a lookupswitch. Note that the docs for lookupswitch indicate that it may be faster than O(n), and indeed it's not difficult to imagine that a JVM could do the lookup in O(log(N)) for a lookupswitch, since it basically just requires a binary search. I don't know if the JVM actually
does a binary search - maybe there's never been any significant demand for optimization in this area; dunno. (Switch statements aren't very common in Java, as there are usually better alternatives involving
polymorphism and/or a Map of some sort.) Regardless, the compiler has several options for implementing switch statements efficiently, and overall it does a pretty good job in this department. There are some cases where it's prohibitive to use a tableswitch, if the ranch of values in the switch is so wide that it takes too much memory. I think such cases are usually pretty rare, in practice. And I suspect the performance devolves to O(log(N)) in such cases - which is not bad at all for most applications.
In summary: switch statements are generally very fast. If there are indeed real-world cases where
performance is a valid reason not to use a switch statement - I'd love to hear the details.
Now, as I alluded previously: this doesn't mean I recommend switch statements in general. My main objection to them is the error-prone syntax whcih requires us to explicitly provide a break. And if the possible values of the enum are changed in the future, I'd prefer to edit this in only one place (the list of values at the beginning of the enum declaration) without worrying about a separate switch statement elsewhere in the code. However - using a switch statement is not the end of the world, and Sonny's example seems fairly reasonable to me.
Typically, I define a private static class of the enum that contains a Map ,for your case, Map<Character, EnumType>, and lazily initialise it (in a static initialiser for class loader) to the appropriate values (or load them from an external resource if appropriate (the other reason why switch/case is flawed - you cannot do this)). No disagreements on this section - this would usually be my preferred strategy as well.
[ July 05, 2005: Message edited by: Jim Yingst ]