<rdf:RDF
    xmlns:s='http://snipsnap.org/rdf/snip-schema#'
    xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
    xml:base='http://knowhow.amazers.net/rdf'>
    <s:Snip rdf:about='http://knowhow.amazers.net/rdf#dev/java+tips/enum+reverse+lookup'
         s:cUser='maz'
         s:oUser='maz'
         s:mUser='maz'>
        <s:name>dev/java tips/enum reverse lookup</s:name>
        <s:content>1 reverse lookup with enums&#xD;&#xA;&#xD;&#xA;The implementation of enumerations is great in java.&#xD;&#xA;In this Post I will introduce a very helpful hint for reverse lookup of enums.&#xD;&#xA;&#xD;&#xA;1.1 What is reverse lookup&#xD;&#xA;Just consider the case that there are some non easy understandable status columns within the database. In the java application it is wise to have enums with comprehensive items, so the code is understood very easy.&#xD;&#xA;&#xD;&#xA;For example just the gender column for user is in some databases realized as a varchar(1) or char column with &apos;M&apos; for male and &apos;F&apos; for female. (Don&apos;t blame me for this database definitions. I came across many of this kind definitions and in  a ideal world you would define lookup table in the database and link the value to them. But this is just an example for the use case :) )&#xD;&#xA;&#xD;&#xA;So in the first place the enum for gender could look like this:&#xD;&#xA;{code:type=java}&#xD;&#xA;public enum Gender&#xD;&#xA;{&#xD;&#xA;   MALE, FEMALE;&#xD;&#xA;}&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;One would then  use switch-case-instructions (actually I have seen this on the time of writing many times) to assign the database value and to get the enum from the database.&#xD;&#xA;&#xD;&#xA;But the most elegant way is to use the abilities of enums itself. Enums are in java classes by itself and may have constructors, members and functions. So let&apos;s use them.&#xD;&#xA;&#xD;&#xA;{code:type=java}&#xD;&#xA;public enum Gender&#xD;&#xA;{&#xD;&#xA;  MALE(&quot;M&quot;),&#xD;&#xA;  FEMALE(&quot;F&quot;);&#xD;&#xA;&#xD;&#xA;  protected String dbValue;&#xD;&#xA;&#xD;&#xA;  public Gender(String s)&#xD;&#xA;  {&#xD;&#xA;    dbValue=s;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  public String getDbValue() { return dbValue;}&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;  // prepare for reverse lookup&#xD;&#xA;  public static Map&lt;String, Gender&gt; lookupMap = new HashMap&lt;String, Gender&gt;();&#xD;&#xA;  // fill the reverse lookup map, alternatively this could be done within the constructor.&#xD;&#xA;  static&#xD;&#xA;  {&#xD;&#xA;    for(Gender item : EnumSet.allOf(Gender.class))&#xD;&#xA;       lookupMap.put(item.getDbValue(), item);&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;  public Gender findbyDbValue(String val)&#xD;&#xA;  {&#xD;&#xA;    return lookupMap.get(val);&#xD;&#xA;  } &#xD;&#xA;}&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;1.1 A generic enum inversion&#xD;&#xA;For easy usage it is rather useful to have an enum reverse finder as a helper utility and use it whereever useful:&#xD;&#xA;&#xD;&#xA;{code: type=java}&#xD;&#xA;public abstract class EnumReverseFinder&lt;K,V extends Enum&lt;V&gt;&gt; &#xD;&#xA;{&#xD;&#xA;  private Map&lt;K, V&gt; map = new HashMap&lt;K, V&gt;();&#xD;&#xA;  public EnumReverseFinder(Class&lt;V&gt; enumclass)&#xD;&#xA;  {&#xD;&#xA;    for(V v:enumclass.getEnumConstants())&#xD;&#xA;      map.put(getKey(v), v);&#xD;&#xA;  }&#xD;&#xA;  public V get(K k) {return map.get(k);}&#xD;&#xA;  protected abstract K getKey(V value);&#xD;&#xA;}&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;On the usage one must define the key by implementing the abstract getKey-Method.&#xD;&#xA;The Gender-Enum as an example would look like this:&#xD;&#xA;&#xD;&#xA;{code:type=java}&#xD;&#xA;public enum Gender&#xD;&#xA;{&#xD;&#xA;  MALE(&quot;M&quot;),&#xD;&#xA;  FEMALE(&quot;F&quot;);&#xD;&#xA;&#xD;&#xA;  protected String dbValue;&#xD;&#xA;&#xD;&#xA;  public Gender(String s)&#xD;&#xA;  {&#xD;&#xA;    dbValue=s;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  public String getDbValue() { return dbValue;}&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;  // reverse lookup for dbValue&#xD;&#xA;  private static final EnumReverseFinder&lt;String, Gender&gt; dbValueFinder = &#xD;&#xA;      new EnumReverseFinder&lt;String, Gender&gt;(Gender.class) {&#xD;&#xA;             protected String getKey(Gender v){return v.dbValue;}&#xD;&#xA;          };&#xD;&#xA;  &#xD;&#xA;  public static Gender findbyDbValue(String val){return dbValueFinder.get(val);} &#xD;&#xA;}&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;1.1 More fancy things about enums&#xD;&#xA;- checkout this newsletter issue from the great Heinz Kabutz (Javaspecialist): http://www.javaspecialists.eu/archive/Issue113.html&#xD;&#xA;- Also this article is useful: http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks</s:content>
        <s:mTime>2010-05-09 14:49:46.223</s:mTime>
        <s:cTime>2010-05-02 18:37:53.109</s:cTime>
        <s:comments
             rdf:type='http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag'/>
        <s:snipLinks>
            <rdf:Bag>
                <rdf:li rdf:resource='#snipsnap-index'/>
                <rdf:li rdf:resource='http://knowhow.amazers.net/rdf#dev/java tips'/>
                <rdf:li>
                    <s:Snip rdf:about='http://knowhow.amazers.net/rdf#dev/java+tips/enum+reverse+lookup'>
                        <s:attachments
                             rdf:type='http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag'/>
                    </s:Snip>
                </rdf:li>
                <rdf:li rdf:resource='http://knowhow.amazers.net/rdf#dev/info/UPNP-AV and DLNA/DLNA Device LCD-TV Phillips PFL 9603 D'/>
                <rdf:li rdf:resource='http://knowhow.amazers.net/rdf#dev/java tips/Hacks around XMLGregorianCalendar'/>
            </rdf:Bag>
        </s:snipLinks>
    </s:Snip>
</rdf:RDF>

