Prev: Is there any ActiveRecord implementation for java?
Next: CFP: PPPJ 2010 -- Principles and Practice of Programming in Java (Vienna, Sep 10)
From: Lew on 18 Dec 2009 23:58 John B. Matthews wrote: > In article > <24ebe868-e3b3-49f9-a23c-0c47a107d6fe(a)a32g2000yqm.googlegroups.com>, > "david.karr" <davidmichaelkarr(a)gmail.com> wrote: > >> On Dec 18, 4:25 pm, EJP <esmond.not.p...(a)not.bigpond.com> wrote: >>> david.karr wrote: >>>> Can someone think of a better way to do this, that doesn't repeat >>>> the column values? >>> Have each enum value enter itself on construction into a >>> Map<Integer, YourEnum> with its own ColumnValue as the key. >>> >>> Like Peter I cannot see the point of setColumnValue(), and the Map >>> would of course require the columnValue to be constant. >> Yes, you're right, there's no need for "setColumnValue()". >> >> Concerning the Map, I had already thought of that. That's the >> obvious way to do it. Now, how would you do it? I would assume >> you'd define a static Map in the enum type and have the constructor >> put itself into the map. The problem is, it doesn't appear to be >> possible to do that. It doesn't compile. > > A static initializer works, as suggested in the "enum Color" discussion: > > <http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9> > > Here's a similar example that constructs a Map<Integer, Key>, where > Integer is a keyCode and Key is an enum: > > <http://robotchase.svn.sourceforge.net/viewvc/robotchase/trunk/ > src/org/gcs/robot/Key.java?revision=27&view=markup> > > The mapping is persisted using java.util.prefs.Preferences rather than a > database, but the result is similar. > >> What might work is implementing some sort of "super-map" that holds >> all the mappings for all enum types you implement, so the key would >> have to concatenate the class and the custom ordinal. enums generally have few enough values that a linear search is acceptable: public static MyNumeration fromRepresentation( String rep ) { for ( MyNumeration numer : values() ) { if ( numer.toString().equals( rep ) ) { return numer; } } return valueOf( numer ); } where 'toString()' is overridden to return the 'private final String' internal representation of the enum value. You can do something similar for integer or any 'Representation' type. -- Lew
From: Roedy Green on 19 Dec 2009 01:19 On Fri, 18 Dec 2009 15:42:05 -0800 (PST), "david.karr" <davidmichaelkarr(a)gmail.com> wrote, quoted or indirectly quoted someone who said : > public SomeType getEnum(int columnValue) { > switch (columnValue) { > case 101: return Foo; > case 100: return Bar; > case 4001: return Gork; > default: return null; > } > } If you use Java enums, you can use values()[i] to go from strict ordinal to enum value. What you have as your ints are basically short aliases for the enums. You can build a HashMap in the constructors. See http://mindprod.com/jgloss/enum.html for sample code. -- Roedy Green Canadian Mind Products http://mindprod.com The future has already happened, it just isn�t evenly distributed. ~ William Gibson (born: 1948-03-17 age: 61)
From: Daniel Pitts on 19 Dec 2009 01:29 david.karr wrote: > Quite often databases will have columns that are stored as integers, > but represent enumerated values. In object-relational mapping, it's a > good idea to translate that integer value to the enumerated value it > represents. > > The built-in "ordinal" value of an enum is almost useless. The integer > values for an enum always need to be controlled, and can't change if > you reorder things. > > So you at least have to implement one custom field in the enum, which > I'll call "columnValue". > > Somewhere you have to have code that translates those integer values > into the enumerated type value. The best place to do that is within > the enumerated type itself. Ideally, I'd like to do this in a way > that doesn't repeat the integer values, and is reasonably efficient. > > A simple-minded implementation might look like this: > > public static enum SomeType { > Foo(101), > Bar(100), > Gork(4001); > > private int columnValue; > > public final int getColumnValue() { return columnValue; } > public final void setColumnValue(int columnValue) > { this.columnValue = columnValue; } > > public SomeType getEnum(int columnValue) { > switch (columnValue) { > case 101: return Foo; > case 100: return Bar; > case 4001: return Gork; > default: return null; > } > } > > SomeType(int columnValue) { > this.columnValue = columnValue; > } > } > > Can someone think of a better way to do this, that doesn't repeat the > column values? See inline comments: public static enum SomeType { // enum names are usually all caps. FOO(101), BAR(100), GORK(4001); // Exposing this as a public final field. // One of the few times I would actually do that. public final int columnValue; SomeType(int columnValue) { this.columnValue = columnValue; } // using a Map private static final Map<Integer, SomeType> byId; // Static initializer block. static { // Start with a HashMap. final Map<Integer, SomeType> map = new HashMap<Integer, SomeType>(); // Add all the values. for (SomeType st: values) { map.put(st.columnValue, st); } byId = Collections.unmodifiableMap(map); } // Provide public method which hides the map. That way, you can // use any implementation you want, whether it be switch, map, or // sparse array. public static SomeType getByColumnValue(int columnValue) { return byId.get(columnValue); } } HTH, Daniel. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Daniel Pitts on 19 Dec 2009 01:32 Arved Sandstrom wrote: > david.karr wrote: >> Quite often databases will have columns that are stored as integers, >> but represent enumerated values. In object-relational mapping, it's a >> good idea to translate that integer value to the enumerated value it >> represents. > [ SNIP ] > > It's an even better idea to store the enumeration "name" as a varchar. > Do you have that control or is it already past that point? And a yet better idea is to store the enumeration "name" as a database "enum" type, if the DB supports it (MySQL does, not sure about others). The database converts to and from the internal representation (which is usually integer), but the column value looks like a string. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Daniel Pitts on 19 Dec 2009 01:34
david.karr wrote: > I cannot change the database at all, even adding tables or columns. That restriction is going to really suck when requirements dictate a design change. Glad I don't work at your company. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/> |