如何在Java中定义重复的枚举常量? [英] How can I define duplicate enumeration constants in Java?

查看:135
本文介绍了如何在Java中定义重复的枚举常量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定义一个具有两个值相同的常量的枚举类型。我将这两个常量称为重复。请考虑以下示例:我想定义一个浏览器类型列表,并且我想同时具有文字IE和InternetExplorer,如下所示:



<$ p $浏览器{
CHROME(chrome),
FIREFOX(firefox),
IE(ie),
INTERNETEXPLORER IE);

字符串类型;
浏览器(字符串类型){
this.type = type;
}
}

但是,以下代码将失败,

 浏览器a = Browser.IE; 
浏览器b = Browser.INTERNETEXPLORER;
Assert.assertTrue(a == b);

我想到的唯一解决方法是添加一个 value() 的方法,返回浏览器实例的内部值的浏览器类型。而等式测试代码将是

  Assert.assertTrue(a.value()== b.value())

这不是很好。有没有人有更好的主意?



为什么Java不允许覆盖诸如 equals() Enum&T ; class?



编辑



感谢您的回答和意见。我同意我原来的想法是违反枚举的目的。我认为以下变化可以满足我的需要。

  public enum Browser {
CHROME,
FIREFOX,
IE;

public static浏览器valueOfType(String type){
if(b == null){
throw new IllegalArgumentException(No browser of type+ type);
switch(type.toLowerCase()){
casechrome:
return Browser.CHROME;
casefirefox:
return Browser.FIREFOX;
caseie:
caseinternetexplorer:
casemsie:
return Browser.IE;
default:
throw new IllegalArgumentException(No browser of type+ type);
}
}
}


解决方案

每个枚举相互扩展类枚举,将 equals()定义为 final 。这是因为枚举不是常规类。 JVM保证每个枚举元素是唯一的,即只存在一个JVM中每个元素的一个实例。



这是必需的,例如在 switch 语句等中使用枚举。



你想要做的是反对这个概念:你想要拥有相同枚举的2个相同的成员。



但是,我可以为您提供其他解决方案:仅定义一个 IE 成员。将 String [] 成员定义为可以通过任何别名找到适当成员的枚举和方法:

  public enum浏览器{


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浏览器valueOfByAlias(String alias){
浏览器b = browsers.get(别名);
if(b == null){
throw new IllegalArgumentException(
No enum alias+ Browser.class.getCanonicalName()+。+ alias);
}
return b;
}
}


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);
       }
   }
}

解决方案

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;
    }
}

这篇关于如何在Java中定义重复的枚举常量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆