I want to define an enum type with two constants whose "value" is the same. I call these two constants as duplicates. Consider the following example: I want to define a list of browser types, and I want to have both a literal "IE" and "InternetExplorer", as below:
enum Browser {
CHROME("chrome"),
FIREFOX("firefox"),
IE("ie"),
INTERNETEXPLORER("ie");
String type;
Browser(String type) {
this.type = type;
}
}
However, with this, the following code will fail,
Browser a = Browser.IE;
Browser b = Browser.INTERNETEXPLORER;
Assert.assertTrue(a==b);
The only workaround I can think of is that to add a value()
method of the Browser
type that returns the internal value of the browser instance. And the equality test code would be
Assert.assertTrue(a.value()==b.value())
This is not nice. So does anyone have a better idea?
Why does Java not allow to override methods like equals()
of Enum<T>
class?
EDIT:
OK, thanks for the answers and comments. I agree that my original thought was against the purpose of enum. I think the following changes can meet my need.
public enum Browser {
CHROME,
FIREFOX,
IE;
public static Browser valueOfType(String type) {
if (b == null) {
throw new IllegalArgumentException("No browser of type " + type);
switch (type.toLowerCase()) {
case "chrome":
return Browser.CHROME;
case "firefox":
return Browser.FIREFOX;
case "ie":
case "internetexplorer":
case "msie":
return Browser.IE;
default:
throw new IllegalArgumentException("No browser of type " + type);
}
}
}
CA1069: Enums should not have duplicate values.
A Java enum is a data type that stores a list of constants. You can create an enum object using the enum keyword. Enum constants appear as a comma-separated list within a pair of curly brackets. An enum, which is short for enumeration, is a data type that has a fixed set of possible values.
Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.
The values assigned to the enum names must be integral constant, i.e., it should not be of other types such string, float, etc. All the enum names must be unique in their scope, i.e., if we define two enum having same scope, then these two enums should have different enum names otherwise compiler will throw an error.
Hierarchical enumeration trick is probably what you want in this case. Although it doesn't solve the comparison problem, it provides a very nice alternative to you problem.
http://java.dzone.com/articles/enum-tricks-hierarchical-data
I quote the codes from the site above directly with slight simplification:
public enum OsType {
OS(null),
Windows(OS),
WindowsNT(Windows),
WindowsNTWorkstation(WindowsNT),
WindowsNTServer(WindowsNT),
WindowsXp(Windows),
WindowsVista(Windows),
Windows7(Windows),
Unix(OS),
Linux(Unix),
;
private OsType parent = null;
private OsType(OsType parent) {
this.parent = parent;
}
}
Each enum mutually extends class Enum
that defines equals()
as final
. This is done because enum is not a regular class. JVM guarantees that each enum element is unique, i.e. exists only one instance of each element within one JVM.
This is required for example for using enums in switch
statement etc.
What you are trying to do is to go against this concept: you want to have 2 equal members of the same enum.
However I can offer you other solution: define only one IE
member. Define String[]
member into the enum and method that can find appropriate member by any alias:
public enum Browser {
CHROME("Chrome"),
FIREFOX("FireFox"),
IE("IE", "MSIE", "Microsoft Internet Exporer"),
;
private String[] aliases;
private static Map<String, Browser> browsers = new HashMap<>();
static {
for (Browser b : Browser.values()) {
for (String alias : b.aliases) {
browsers.put(alias, b);
}
}
}
private Browser(String ... aliases) {
this.aliases = aliases;
}
public static Browser valueOfByAlias(String alias) {
Browser b = browsers.get(alias);
if (b == null) {
throw new IllegalArgumentException(
"No enum alias " + Browser.class.getCanonicalName() + "." + alias);
}
return b;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With