enum MyEnum { INIT, WORKING, FINAL, COMPLETE };
MyEnum value = (MyEnum)intValue;
gives a compile time error. I'd like to use an int of 0 as "INIT", 1 as
"WORKING" and so on. An exception if the int is not in the enumeration
would be logical. My enumeration will contain several hundred values and
this needs to be fast.
Java 5.0 enums can do some pretty clever stuff - surely it can do this?
I can't figure out how though... :o}
--
Aches and pains at your desk? Try a little exercise:
http://www.daily-exercise.com/
For the best solution, you'd ask yourself, why you come from
ints in the first place. Where do the int values come from,
and why can you not use enums throughout the whole application?
Now, while I don't see a good use for it, I also don't exclude the
possibility of a good use.
To get the conversion principially, you could use this idiom:
MyEnum.values()[ intValue ]
but this creates a clone of a privately (in MyEnum) kept array
each time you call this method, and I'd be really surprised if
the optimiser was able to optimize that.
If you need to do this conversion many times, then you may consider
saving a copy of MyEnum.values() once into a MyEnum[] typed variable
and use that for indexing.
If you do a performance comparison, I'd appreciate if you shared
the results.
Derek Fountain schreef:
> Newbie one: I have an integer that I want to convert into an enum of
> type MyEnum. A cast, like this:
>
> enum MyEnum { INIT, WORKING, FINAL, COMPLETE };
> MyEnum value = (MyEnum)intValue;
>
> gives a compile time error. I'd like to use an int of 0 as "INIT", 1 as
> "WORKING" and so on. An exception if the int is not in the enumeration
> would be logical. My enumeration will contain several hundred values and
> this needs to be fast.
>
> Java 5.0 enums can do some pretty clever stuff - surely it can do this?
> I can't figure out how though... :o}
Rethink your design. Casting an integer to an enum almost always means
you are using the concept of enum wrongly. It is not a coincidence that
Java enums do not allow this. If you really, really, really need it,
you can add a fromInt(int someInt) to your Enum.
H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org
iEYEARECAAYFAkkthPkACgkQBGFP0CTku6MjKACeOcJjkWwC3CNKi7oJvqvR+ysH
szMAoMQdRUZyyq6Mr5kOWAYSozSI0rHC
=rnkl
-----END PGP SIGNATURE-----
>Newbie one: I have an integer that I want to convert into an enum of
>type MyEnum. A cast, like this:
see http://mindprod.com/jgloss/enum.html
the trick is to index values()[i].
--
Roedy Green Canadian Mind Products
http://mindprod.com
"Humanity is conducting an unintended, uncontrolled, globally pervasive experiment
whose ultimate consequences could be second only to global nuclear war."
~ Environment Canada (The Canadian equivalent of the EPA on global warming)
>Newbie one: I have an integer that I want to convert into an enum of
>type MyEnum. A cast, like this:
>
> enum MyEnum { INIT, WORKING, FINAL, COMPLETE };
> MyEnum value = (MyEnum)intValue;
>
>gives a compile time error. I'd like to use an int of 0 as "INIT", 1 as
>"WORKING" and so on. An exception if the int is not in the enumeration
>would be logical. My enumeration will contain several hundred values and
>this needs to be fast.
>
>Java 5.0 enums can do some pretty clever stuff - surely it can do this?
>I can't figure out how though... :o}
As others have pointed out you should be using enums *instead of* ints
rather than alongside them. Go through your program and replace every
int that represents a member of your enumeration with the relevant
enum. Then got hold of a copy of Joshua Bloch's "Effective Java -
Second Edition" and read item 30 - "Use enums instead of int
constants".
If after all of that you decide that you really do want to do this,
then have a look at the code for the enum.valueOf() method and create
something similar with an integer parameter instead of a string
parameter.
If you don't want to do that then a crude solution would be to set up
a separate class to hold the mapping data, something like:
enum MyEnum { INIT, WORKING, FINAL, COMPLETE };
final static class EnumMap {
// Map for int <-> enum links
static Map<Integer, MyEnum> intMap =
new HashMap<Integer, MyEnum>(4);
// Static initialisation for the Map
static {
for (MyEnum e : MyEnum.values()) {
intMap.put(e.ordinal(), e);
}
}
// This is the function you want
// Returns null if key value not found.
public static MyEnum intValue(int key) {
return intMap.get(key);
}
} // end class EnumMap
To test it try:
public static void main(String[] args) {
for (int i = -1; i < 5; ++i) {
System.out.println(i + " -> " + EnumMap.intValue(i));
}
}
rossum
> System.out.println(i + " -> " + EnumMap.intValue(i));
EnumMap probably isn't the bestest name ever, though. I was scanning
this and thought "Wth? Why isn't he using get(i)?"
<http://java.sun.com/javase/6/docs/api/java/util/EnumMap.html>
;)
Here's my little attempt.
class EnumValues<E extends Enum<E>>
{
E[] values;
public EnumValues( Class<E> enumType )
{
values = enumType.getEnumConstants();
}
public E intToValue( int i ) {
return values[i];
}
}
>As others have pointed out you should be using enums *instead of* ints
>rather than alongside them. Go through your program and replace every
>int that represents a member of your enumeration with the relevant
>enum. Then got hold of a copy of Joshua Bloch's "Effective Java -
>Second Edition" and read item 30 - "Use enums instead of int
>constants".
You can't very well store enums in an SQL database. You need some sort
of external representation, a string or int. For strings, you can
build a HashMap lookup to convert them back to enum, and a an instance
method on the enum constants to cough up a value from the enum
constructor.
Not a hashmap. Just make a static method within the enum which looks up
the database value (by scanning through the values) and passes back the
corresponding enum:
-----------------------
enum Type
{
PROJECT(1), //
PERSON(2), //
EQUIPMENT(3); //
private char ivTypeID;
private Type( char typeID )
{
ivTypeID = typeID;
}
public char getTypeID()
{
return ivTypeID;
}
/**
* Returns the Type for a given id number<br><br>
* Used to find a Type from a Web page field or database column
*/
public static Type getType( int typeID ) throws EnumNotFoundException
{
for (Type type : Type.values())
if (type.getTypeID() == typeID)
return type;
throw new EnumNotFoundException( Logic.class.getName(), typeID );
}
}
-----------------------
And for text ids you would use the .equals method in the test.
--
Wojtek :-)
Um, that should be:
throw new EnumNotFoundException( Type.class.getName(), typeID );
(stupid copy/paste...)
--
Wojtek :-)
Why all that trouble. ENum already have toString and valueOf
with all the required functionality.
Arne
This is generally a much better strategy than storing ordinals in a database.
First, the enum will need a lookup for a string value to serve any
human-involved interaction with the data anyway. Second, ordinals might not
remain the same in the face of code refactoring, but string representations
are far less mutable, so serve better in the long run.
As for string-to-=enum conversion, careful choice of string representations
would allow use of the automatically generated enum method 'valueOf(String)'.
If that default implementation isn't suitable, then the Java enum probably
needs a custom 'fromString()' anyway, in which case one might well use an
internal HashMap.
--
Lew
Or just use the enum's 'valueOf(String)'.
--
Lew