关于java:将Enum值用作String文字

Using Enum values as String literals

使用枚举中存储的值作为字符串文本的最佳方法是什么?例如:

1
2
3
4
5
6
public enum Modes {
    some-really-long-string,
    mode1,
    mode2,
    mode3
}

然后,我可以使用Mode.mode1返回其字符串表示形式为mode1。不用一直打电话给Mode.mode1.toString()


你不能。我想你有四个选择。这四个都提供了解决方案,但方法略有不同…

选项一:在枚举上使用内置的name()。如果您不需要任何特殊的命名格式,这是非常好的。

1
    String name = Modes.mode1.name(); // Returns the name of this enum constant, exactly as declared in its enum declaration.

选项二:如果需要更多的控件,请将重写属性添加到枚举中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public enum Modes {
    mode1 ("Fancy Mode 1"),
    mode2 ("Fancy Mode 2"),
    mode3 ("Fancy Mode 3");

    private final String name;      

    private Modes(String s) {
        name = s;
    }

    public boolean equalsName(String otherName) {
        // (otherName == null) check is not needed because name.equals(null) returns false
        return name.equals(otherName);
    }

    public String toString() {
       return this.name;
    }
}

选项三:使用静态决赛而不是枚举:

1
2
3
4
5
6
7
8
public final class Modes {

    public static final String MODE_1 ="Fancy Mode 1";
    public static final String MODE_2 ="Fancy Mode 2";
    public static final String MODE_3 ="Fancy Mode 3";

    private Modes() { }
}

选项四:接口具有每个字段公共、静态和最终:

1
2
3
4
5
6
public interface Modes {

    String MODE_1 ="Fancy Mode 1";
    String MODE_2 ="Fancy Mode 2";
    String MODE_3 ="Fancy Mode 3";  
}


每个枚举都有一个name()和一个valueof(string)方法。前者返回枚举的字符串名称,后者提供名称为字符串的枚举值。这就是你要找的吗?

1
2
String name = Modes.mode1.name();
Modes mode = Modes.valueOf(name);

枚举本身也有一个静态值(class,string),因此您也可以使用

1
Modes mode = Enum.valueOf(Modes.class, name);


可以为每个枚举值重写toString()方法。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public enum Country {

  DE {
    @Override
    public String toString() {
      return"Germany";
    }
  },
  IT {
    @Override
    public String toString() {
      return"Italy";
    }
  },
  US {
    @Override
    public String toString() {
      return"United States";
    }
  }

}

用途:

1
2
3
4
5
public static void main(String[] args) {
  System.out.println(Country.DE); // Germany
  System.out.println(Country.IT); // Italy
  System.out.println(Country.US); // United States
}


正如Benny Neugebauer提到的,您可以覆盖toString()。但是,我更喜欢这样的方式来覆盖每个枚举字段的ToString:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public enum Country{
    SPAIN("Espa?a"),
    ITALY("Italia"),
    PORTUGAL("Portugal");


    private String value;

    Country(final String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return this.getValue();
    }
}

您还可以添加一个静态方法来检索所有字段,打印所有字段等等。只需调用getValue获取与每个枚举项关联的字符串


mode1.name()String.valueOf(mode1)。恐怕没有比这更好的了


1
2
3
4
5
6
7
8
9
10
11
12
13
public enum Modes {
  MODE1("Mode1"),
  MODE2("Mode2"),
  MODE3("Mode3");

 private String value;
 public String getValue() {
    return value;
   }
 private Modes(String value) {
  this.value = value;
 }
}

您可以在下面这样的地方进行调用,以从枚举中获取字符串形式的值。

1
Modes.MODE1.getvalue();

这将以字符串形式返回"mode1"。


您可以使用Mode.mode1.name(),但通常不需要这样做。

1
2
Mode mode =
System.out.println("The mode is"+mode);


据我所知,获得这个名字的唯一方法是

1
Mode.mode1.name();

但是,如果您真的需要它,您可以这样做:

1
2
3
4
5
6
7
8
9
10
11
public enum Modes {
    mode1 ("Mode1"),
    mode2 ("Mode2"),
    mode3 ("Mode3");

    private String name;      

    private Modes(String s) {
        name = s;
    }
}


您可以简单地使用:

1
""+ Modes.mode1


对于我的枚举,我真的不喜欢把它们每个分配一个字符串。这就是我如何在枚举上实现ToString()方法。

1
2
3
4
5
6
7
8
9
10
11
12
enum Animal
{
    DOG, CAT, BIRD;
    public String toString(){
        switch (this) {
            case DOG: return"Dog";
            case CAT: return"Cat";
            case BIRD: return"Bird";
        }
        return null;
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.common.test;

public  enum Days {


    monday(1,"Monday"),tuesday(2,"Tuesday"),wednesday(3,"Wednesday"),
    thrusday(4,"Thrusday"),friday(5,"Friday"),saturday(6,"Saturday"),sunday(7,"Sunday");

    private int id;
    private String desc;


    Days(int id,String desc){
        this.id=id;
        this.desc=desc;
    }

    public static String getDay(int id){

        for (Days day : Days.values()) {
            if (day.getId() == id) {
                return day.getDesc();
            }
        }
        return null;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }



};


枚举只是一个有点特殊的类。枚举可以存储其他字段、实现方法等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public enum Modes {
    mode1('a'),
    mode2('b'),
    mode3('c'),
    ;
    char c;

    private Modes(char c) {
        this.c = c;
    }
    public char character() {
        return c;
    }
}

现在你可以说:

System.out.println(Modes.mode1.character())

见输出:a


此方法应适用于任何enum

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public enum MyEnum {
    VALUE1,
    VALUE2,
    VALUE3;

    public int getValue() {
        return this.ordinal();
    }

    public static DataType forValue(int value) {
        return values()[value];
    }

    public String toString() {
        return forValue(getValue()).name();
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public enum Environment
{
    PROD("https://prod.domain.com:1088/"),
    SIT("https://sit.domain.com:2019/"),
    CIT("https://cit.domain.com:8080/"),
    DEV("https://dev.domain.com:21323/");

    private String url;

    Environment(String envUrl) {
        this.url = envUrl;
    }

    public String getUrl() {
        return url;
    }
}

String prodUrl = Environment.PROD.getUrl();

它将打印:

1
https://prod.domain.com:1088/

这种枚举字符串常量的设计在大多数情况下都有效。


我的解决方案!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.util.HashMap;
import java.util.Map;

public enum MapEnumSample {
    Mustang("One of the fastest cars in the world!"),
    Mercedes("One of the most beautiful cars in the world!"),
    Ferrari("Ferrari or Mercedes, which one is the best?");

    private final String description;
    private static Map<String, String> enumMap;

    private MapEnumSample(String description) {
        this.description = description;
    }

    public String getEnumValue() {
        return description;
    }

    public static String getEnumKey(String name) {
        if (enumMap == null) {
            initializeMap();
        }
        return enumMap.get(name);
    }

    private static Map<String, String> initializeMap() {
        enumMap = new HashMap<String, String>();
        for (MapEnumSample access : MapEnumSample.values()) {
            enumMap.put(access.getEnumValue(), access.toString());
        }
        return enumMap;
    }

    public static void main(String[] args) {

        // getting value from Description
        System.out.println(MapEnumSample.getEnumKey("One of the fastest cars in the world!"));

        // getting value from Constant
        System.out.println(MapEnumSample.Mustang.getEnumValue());

        System.out.println(MapEnumSample.getEnumKey("One of the most beautiful cars in the world!"));
        System.out.println(MapEnumSample.Mercedes.getEnumValue());

        // doesnt exist in Enum
        System.out.println("Mustang or Mercedes, which one is the best?");
        System.out.println(MapEnumSample.getEnumKey("Mustang or Mercedes, which one is the best?") == null ?"I don't know!" :"I believe that"
                + MapEnumSample.getEnumKey("Ferrari or Mustang, which one is the best?") +" is the best!.");

        // exists in Enum
        System.out.println("Ferrari or Mercedes, wich one is the best?");
        System.out.println(MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") == null ?"I don't know!" :"I believe that"
                + MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") +" is the best!");

    }
}


您可以尝试以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public enum Modes {
    some-really-long-string,
    mode1,
    mode2,
    mode3;

    public String toString(){
        switch(this) {
            case some-really-long-string:
                return"some-really-long-string";
            case mode2:
                return"mode2";
            default: return"undefined";
        }
    }

}


经过多次尝试,我找到了这个解决方案

16