Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > enum aliases

Reply
Thread Tools

enum aliases

 
 
Roedy Green
Guest
Posts: n/a
 
      06-26-2005
IT would be nice if there were an easy way to have both valueOf and
toString aliases for enums.

Why?

To allow you to use reserved words like true, false, default, null as
your enum string constants.

to allow additional variants on input e.g. for "yes" also allow "true"
"t" "f".

To change the way the enum displays e.g. to change the language. to
change default/usual to whatever the default value actually is.

Any ideas on how to implement that cleanly?

--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/...s_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
Reply With Quote
 
 
 
 
Lasse Reichstein Nielsen
Guest
Posts: n/a
 
      06-27-2005
Roedy Green <(E-Mail Removed)> writes:

> IT would be nice if there were an easy way to have both valueOf and
> toString aliases for enums.


> Why?
>
> To allow you to use reserved words like true, false, default, null as
> your enum string constants.


You can overwrite toString if you want to. There can obviosuly only be
one default string representation, so if you want both the enum name
and its alias, you need two functions, so just write your own myToString().

> to allow additional variants on input e.g. for "yes" also allow "true"
> "t" "f".


The valueOf method is implicitly defined on all enum classes, and you
are not allowed to overwrite it. But then, you can just create your
own.

> To change the way the enum displays e.g. to change the language. to
> change default/usual to whatever the default value actually is.


You should not depend on the name of the enum constant for its
display. If you need to display it in a way that might change, then
it is a display concern, and should be kept closer to the display
code than to the enum itself. I would just make a map from enum
name to presentation.

What is a default in this scenarios?

Anyway:
---
public enum EnumTest {
TEST("test","trial","query"),
SUCCESS("success","yes","true"),
FAILURE("failure","fail","no","false");

private static Map<String,EnumTest> aliasMap;

private final String defaultName;

EnumTest(String... aliases) {
if (aliasMap == null) {
aliasMap = new HashMap<String,EnumTest>();
}
for (String alias : aliases) {
aliasMap.put(alias, this);
}
if (aliases.length > 0) {
defaultName = aliases[0];
} else {
defaultName = name();
}
}

static EnumTest valueOfAlias(String alias) {
EnumTest value = aliasMap.get(alias);
if (value == null) {
throw new IllegalArgumentException(alias + " not an alias");
}
return value;
}

public String toString() {
return defaultName;
}
}
---

I think that qualifies as an "easy way"
/L
--
Lasse Reichstein Nielsen - http://www.velocityreviews.com/forums/(E-Mail Removed)
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
 
Reply With Quote
 
 
 
 
Roedy Green
Guest
Posts: n/a
 
      06-28-2005
On Mon, 27 Jun 2005 02:02:23 +0200, Lasse Reichstein Nielsen
<(E-Mail Removed)> wrote or quoted :

> aliasMap.put(alias, this);

then will generate an errormessage

illegal reference to static field from initializer

I don't understand why.


import java.util.HashMap;
import java.util.Map;

/**
* enum with aliases for string input to valueOf
* @author Roedy Green, added comments.
* based on posted code by Lasse Reichstein Nielsen (E-Mail Removed)
*/

public enum Outcome {
SUCCESS( "success", "yes", "true" ),
FAILURE( "failure", "fail", "no", "false" ),
UNDECIDED( "undecided", "maybe" );

/**
* maps from alias name to matching enum constant
*/
private static Map<String, Outcome> aliasMap = new
HashMap<String,Outcome>();

/**
*the preferred alias to use as the canonical name
*/
private final String defaultName;

/**
* constructor for an enum constant
* @param aliases takes String[] specified as a variable length
list of strings
* representing alternate input values for the
aliases.
*/
Outcome( String... aliases )
{

for ( String alias : aliases )
{
aliasMap.put( alias, this );
}
if ( aliases.length > 0 )
{
defaultName = aliases[0];
}
else
{
// allow some enum constants to have no aliases, work as
normal enum constants
defaultName = name();
}
}

/**
* convert string to enum constant
* @param alias string representing one of the aliases of one of
the enum constants.
* @returns enum constant matching String.
* @throws IllegalArgumentExeption if alias is not a legal one.
*/
static Outcome valueOfAlias( String alias )
{
Outcome value = aliasMap.get( alias );
if ( value == null )
{
throw new IllegalArgumentException( alias + " not a legal
Outcome alias" );
}
return value;
}

/**
* The canonical name of this enum constant/variable.
*/
public String toString()
{
return defaultName;
}

private static final boolean DEBUGGING = true;

/**
* test harness
*
* @param args not used
*/
public static void main ( String[] args )
{
if ( DEBUGGING )
{
Outcome o = Outcome.valueOfAlias( "no" );
System.out.println( o ); // prints "failure"
}
}



--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/...s_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
Reply With Quote
 
Lasse Reichstein Nielsen
Guest
Posts: n/a
 
      06-28-2005
Roedy Green <(E-Mail Removed)> writes:

> On Mon, 27 Jun 2005 02:02:23 +0200, Lasse Reichstein Nielsen
> <(E-Mail Removed)> wrote or quoted :
>
>> aliasMap.put(alias, this);

> then will generate an errormessage
>
> illegal reference to static field from initializer


The error message I get from your code is:
---
java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at Outcome.<init>(Outcome.java:41)
at Outcome.<clinit>(Outcome.java:17)
Exception in thread "main"
---

> I don't understand why.


You are initializing the static variable "aliasMap" *after* creating
the instances of Outcome. Remember that enum values are really static
final fields, and they are assigned earlier in the static
initialization than other static fields. That means that the
"aliasMap" field is null when the constructors try to put values into
the map.

If you compare it to my original code, I initialized the map the first
time I needed it, to make sure it was not null. That was deliberate

/L
--
Lasse Reichstein Nielsen - (E-Mail Removed)
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      06-30-2005
On Tue, 28 Jun 2005 21:17:53 +0200, Lasse Reichstein Nielsen
<(E-Mail Removed)> wrote or quoted :

>Roedy Green <(E-Mail Removed)> writes:
>
>> On Mon, 27 Jun 2005 02:02:23 +0200, Lasse Reichstein Nielsen
>> <(E-Mail Removed)> wrote or quoted :
>>
>>> aliasMap.put(alias, this);

>> then will generate an errormessage
>>
>> illegal reference to static field from initializer

>
>The error message I get from your code is:
>---
>java.lang.ExceptionInInitializerError
>Caused by: java.lang.NullPointerException
> at Outcome.<init>(Outcome.java:41)
> at Outcome.<clinit>(Outcome.java:17)
>Exception in thread "main"
>---
>
>> I don't understand why.

>
>You are initializing the static variable "aliasMap" *after* creating
>the instances of Outcome. Remember that enum values are really static
>final fields, and they are assigned earlier in the static
>initialization than other static fields. That means that the
>"aliasMap" field is null when the constructors try to put values into
>the map.
>
>If you compare it to my original code, I initialized the map the first
>time I needed it, to make sure it was not null. That was deliberate
>
>/L


when I do it your way, I get even more of those static initialiser
errors.

You are doing things in the logical order, but Java does not trust
you.

--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/...s_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      06-30-2005
On Thu, 30 Jun 2005 03:05:38 GMT, Roedy Green
<(E-Mail Removed)> wrote or quoted :

>when I do it your way, I get even more of those static initialiser
>errors.


here is my code that works, but is not very smart. It just does a
linear search.
package com.mindprod.pricelist;

/**
* constants for Application categories
*/
public enum AppCat {

/* short name, description, aliases */

APPLET( "Applet", "Java Applet", "applet" ),
APPLICATION( "application", "Java application", "application"),
DOCUMENTATION( "documentation", "documentation" , "documentation"
),
HYBRID( "hybrid", "Java Applet that can also be run as an
application", "hybrid" ),
JWS( "Java Web Start" ,"Java Web Start", "jws", "weblet",
"webstart", "jaws" ),
LIBRARY( "Class" , "Class library", "class", "classes", "library"
),
SERVLET( "servlet", "Java Servlet", "servlet" ),
UTILITY( "Utility", "non-Java Utility", "utility" );

/**
* constructor for an enum constant
* @param human output description.
* @param ShorName for display
* @param description long description
* @param aliases other names for string input
*/
AppCat( String shortName, String description, String... aliases )
{
this.shortName = shortName;
this.description = description;
this.aliases = aliases;
}

private String shortName;

private String description;

/**
* cannot use String... here, only in parm list
* alterate input names for the alias
*/
private String[] aliases;

public String getShortName()
{
return shortName;
}

public String getDescription()
{
return description;
}

public String[] getAliases()
{
return aliases;
}
// you may not redefine valueOf since has been covertly defined in
this class

public static AppCat valueOfAlias ( String s )
{
try
{
return valueOf( AppCat.class, s );
}
catch ( IllegalArgumentException e )
{
// usual method failed, try looking up alias
// This seems long winded, why no HashSet?
// Because Java won't let me access a static common
// lookup in the enum constructors.
for ( AppCat candidateEnum : AppCat.values() )
{

for ( String candidateString : candidateEnum.getAliases()
)
{
if ( candidateString.equalsIgnoreCase( s ) )
{
return candidateEnum;
}
}
}
// fell out the bottom of search over all enums and aliases
// give up

throw new IllegalArgumentException( "unknown Application
Category: " + s);

}

}
}

--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/...s_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ENUM server for private ENUM kael UK VOIP 2 02-25-2007 11:54 AM
enum: display elements of an enum specified at runtime Jerminia Java 3 10-07-2005 10:08 PM
enum within an enum - Java 6 06-13-2005 12:51 AM
Including an enum within another enum, possible? mrhicks C Programming 2 06-10-2004 03:00 AM
How to enum an enum? Ernst Murnleitner C++ 5 11-13-2003 11:06 AM



Advertisments