Java 中是否可以将数值赋给枚举?

问题描述 投票:0回答:6

Java 中可能有这样的事情吗?可以在 Java 中为枚举元素分配自定义数值吗?

public enum EXIT_CODE {
    A=104, B=203;
}
java enums
6个回答
237
投票
public enum EXIT_CODE {
    A(104), B(203);

    private int numVal;

    EXIT_CODE(int numVal) {
        this.numVal = numVal;
    }

    public int getNumVal() {
        return numVal;
    }
}

40
投票

,然后是文档中的一些示例:

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    // in kilograms
    private final double mass;
    // in meters
    private final double radius;
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    private double mass() { return mass; }
    private double radius() { return radius; }

    // universal gravitational 
    // constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }
}

5
投票

扩展 Bhesh Gurung 对于赋值的答案,您可以添加显式方法来设置值

   public ExitCode setValue( int value){
      //  A(104), B(203);
      switch(value){
        case 104: return ExitCode.A;
        case 203: return ExitCode.B;
        default:
                   return ExitCode.Unknown //Keep an default or error enum handy
      }
   }

来自调用应用程序

int i = 104; 
ExitCode serverExitCode = ExitCode.setValue(i);

//从现在起你的枚举就有效了

[无法评论他的答案,因此单独发布]


3
投票

如果您正在寻找一种对类中的常量进行分组的方法,您可以使用静态内部类:

public class OuterClass {
    public void exit(boolean isTrue){
        if(isTrue){
            System.exit(ExitCode.A);
        }else{
            System.exit(ExitCode.B);
        }
    }
    public static class ExitCode{
        public static final int A = 203;
        public static final int B = 204;
    }   
}

2
投票

我意识到这是一个较老的问题,但它首先出现在谷歌搜索中,在提供的优秀答案中,我没有看到任何完全全面的内容,所以我做了更多的挖掘,最终编写了一个枚举类这不仅允许我为枚举常量分配多个自定义值,我什至添加了一个方法,允许我在代码执行期间动态为它们分配值。

这个枚举类适用于我在 Raspberry Pi 上运行的“服务器”程序。该程序从客户端接收命令,然后执行终端命令,对固定在我的 3D 打印机上的网络摄像头进行调整。

使用 Pi 上的 Linux 程序“v4l2-ctl”,您可以提取给定附加网络摄像头的所有可能的调整命令,该命令还提供设置数据类型、最小值和最大值、给定值的步数值范围等,所以我将所有这些放入一个枚举中,并创建了一个枚举接口,可以轻松设置和获取每个命令的值,以及获取实际执行的终端命令的简单方法(使用进程和运行时类)以调整设置。

这是一个相当大的课程,我对此表示歉意,但对我来说,当我看到它在完整的上下文中工作时,学习东西总是更容易,所以我决定不缩小规模。然而,尽管它很大,但它绝对是简单的,并且用最少的努力就能清楚地了解课堂上发生的事情。

package constants;

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

public enum PICam {
    BRIGHTNESS                  ("brightness",                  0,      "int",      0,      100,    1,  50),
    CONTRAST                    ("contrast",                    1,      "int",      100,    100,    1,  0),
    SATURATION                  ("saturation",                  2,      "int",      100,    100,    1,  0),
    RED_BALANCE                 ("red_balance",                 3,      "intmenu",  1,      7999,   1,  1000),
    BLUE_BALANCE                ("blue_balance",                4,      "int",      1,      7999,   1,  1000),
    HORIZONTAL_FLIP             ("horizontal_flip",             5,      "bool",     0,      1,      1,  0),
    VERTICAL_FLIP               ("vertical_flip",               6,      "bool",     0,      1,      1,  0),
    POWER_LINE_FREQUENCY        ("power_line_frequency",        7,      "menu",     0,      3,      1,  1),
    SHARPNESS                   ("sharpness",                   8,      "int",      100,    100,    1,  0),
    COLOR_EFFECTS               ("color_effects",               9,      "menu",     0,      15,     1,  0),
    ROTATE                      ("rotate",                      10,     "int",      0,      360,    90, 0),
    COLOR_EFFECTS_CBCR          ("color_effects_cbcr",          11,     "int",      0,      65535,  1,  32896),
    VIDEO_BITRATE_MODE          ("video_bitrate_mode",          12,     "menu",     0,      1,      1,  0),
    VIDEO_BITRATE               ("video_bitrate",               13,     "int",      25000,  25000000,   25000,  10000000),
    REPEAT_SEQUENCE_HEADER      ("repeat_sequence_header",      14,     "bool",     0,      1,      1,  0),
    H264_I_FRAME_PERIOD         ("h_264_i_frame_period",        15,     "int",      0,      2147483647,1,   60),
    H264_LEVEL                  ("h_264_level",                 16,     "menu",     0,      11,     1,  11),
    H264_PROFILE                ("h_264_profile",               17,     "menu",     0,      4,      1,  4),
    AUTO_EXPOSURE               ("auto_exposure",               18,     "menu",     0,      3,      1,  0),
    EXPOSURE_TIME_ABSOLUTE      ("exposure_time_absolute",      19,     "int",      1,      10000,  1,  1000),
    EXPOSURE_DYNAMIC_FRAMERATE  ("exposure_dynamic_framerate",  20,     "bool",     0,      1,      1,  0),
    AUTO_EXPOSURE_BIAS          ("auto_exposure_bias",          21,     "intmenu",  0,      24,     1,  12),
    WHITE_BALANCE_AUTO_PRESET   ("white_balance_auto_preset",   22,     "menu",     0,      9,      1,  1),
    IMAGE_STABILIZATION         ("image_stabilization",         23,     "bool",     0,      1,      1,  0),
    ISO_SENSITIVITY             ("iso_sensitivity",             24,     "intmenu",  0,      4,      1,  0),
    ISO_SENSITIVITY_AUTO        ("iso_sensitivity_auto",        25,     "menu",     0,      1,      1,  1),
    EXPOSURE_METERING_MODE      ("exposure_metering_mode",      26,     "menu",     0,      2,      1,  0),
    SCENE_MODE                  ("scene_mode",                  27,     "menu",     0,      13,     1,  0),
    COMPRESSION_QUALITY         ("compression_quality",         28,     "int",      1,      100,    1,  30);


    private static final Map<String, PICam>    LABEL_MAP       = new HashMap<>();
    private static final Map<Integer, PICam>   INDEX_MAP       = new HashMap<>();
    private static final Map<String, PICam>    TYPE_MAP        = new HashMap<>();
    private static final Map<Integer, PICam>   MIN_MAP         = new HashMap<>();
    private static final Map<Integer, PICam>   MAX_MAP         = new HashMap<>();
    private static final Map<Integer, PICam>   STEP_MAP        = new HashMap<>();
    private static final Map<Integer, PICam>   DEFAULT_MAP     = new HashMap<>();
    private static final Map<Integer, Integer> THIS_VALUE_MAP  = new HashMap<>();

    private static final String                baseCommandLine = "/usr/bin/v4l2-ctl -d /dev/video0 --set-ctrl=";

    static {
        for (PICam e: values()) {
            LABEL_MAP.put(e.label, e);
            INDEX_MAP.put(e.index, e);
            TYPE_MAP.put(e.type, e);
            MIN_MAP.put(e.min, e);
            MAX_MAP.put(e.max, e);
            STEP_MAP.put(e.step, e);
            DEFAULT_MAP.put(e.defaultValue, e);
        }
    }

    public final String label;
    public final int index;
    public final String type;
    public final int min;
    public final int max;
    public final int step;
    public final int defaultValue;

    private PICam(String label, int index, String type, int min, int max, int step, int defaultValue) {
        this.label = label;
        this.index = index;
        this.type = type;
        this.min = min;
        this.max = max;
        this.step = step;
        this.defaultValue = defaultValue;
    }

    public static void setValue(Integer index, Integer value) {
        if (THIS_VALUE_MAP.containsKey(index)) THIS_VALUE_MAP.replace(index, value);
        else THIS_VALUE_MAP.put(index, value);
    }

    public Integer getValue (Integer index) {
        return THIS_VALUE_MAP.getOrDefault(index, null);
    }

    public static PICam getLabel(String label) {
        return LABEL_MAP.get(label);
    }

    public static PICam getType(String type) {
        return TYPE_MAP.get(type);
    }

    public static PICam getMin(int min) {
        return MIN_MAP.get(min);
    }

    public static PICam getMax(int max) {
        return MAX_MAP.get(max);
    }

    public static PICam getStep(int step) {
        return STEP_MAP.get(step);
    }

    public static PICam getDefault(int defaultValue) {
        return DEFAULT_MAP.get(defaultValue);
    }

    public static String getCommandFor(int index, int newValue) {
        PICam picam = INDEX_MAP.get(index);
        String commandValue = "";
        if ("bool".equals(picam.type)) {
            commandValue = (newValue == 0) ? "false" : "true";
        }
        else {
            commandValue = String.valueOf(newValue);
        }
        return baseCommandLine + INDEX_MAP.get(index).label + "=" + commandValue;
    }

    public static String getCommandFor(PICam picam, Integer newValue) {
        String commandValue = "";
        if ("bool".equals(picam.type)) {
            commandValue = (newValue == 0) ? "false" : "true";
        }
        else {
            commandValue = String.valueOf(newValue);
        }
        return baseCommandLine + INDEX_MAP.get(picam.index).label + "=" + commandValue;
    }

    public static String getCommandFor(PICam piCam) {
        int    newValue     = piCam.defaultValue;
        String commandValue = "";
        if ("bool".equals(piCam.type)) {
            commandValue = (newValue == 0) ? "false" : "true";
        }
        else {
            commandValue = String.valueOf(newValue);
        }
        return baseCommandLine + piCam.label + "=" + commandValue;
    }

    public static String getCommandFor(Integer index) {
        PICam piCam = INDEX_MAP.get(index);
        int    newValue     = piCam.defaultValue;
        String commandValue = "";
        if ("bool".equals(piCam.type)) {
            commandValue = (newValue == 0) ? "false" : "true";
        }
        else {
            commandValue = String.valueOf(newValue);
        }
        return baseCommandLine + piCam.label + "=" + commandValue;
    }
}

以下是班级互动的一些方式:

此代码:

public static void test() {
    PICam.setValue(0,127); //Set brightness to 125
    PICam.setValue(PICam.SHARPNESS,143); //Set sharpness to 125
    String command1 = PICam.getSetCommandStringFor(PICam.BRIGHTNESS); //Get command line string to include the brightness value that we previously set referencing it by enum constant.
    String command2 = PICam.getSetCommandStringFor(0); //Get command line string to include the brightness value that we previously set referencing it by index number.
    String command3 = PICam.getDefaultCamString(PICam.BRIGHTNESS); //Get command line string with the default value
    String command4 = PICam.getSetCommandStringFor(PICam.SHARPNESS); //Get command line string with the sharpness value that we previously set.
    String command5 = PICam.getDefaultCamString(PICam.SHARPNESS); //Get command line string with the default sharpness value.
    System.out.println(command1);
    System.out.println(command2);
    System.out.println(command3);
    System.out.println(command4);
    System.out.println(command5);
}

产生以下结果:

/usr/bin/v4l2-ctl -d /dev/video0 --set-ctrl=brightness=127
/usr/bin/v4l2-ctl -d /dev/video0 --set-ctrl=brightness=127
/usr/bin/v4l2-ctl -d /dev/video0 --set-ctrl=brightness=50
/usr/bin/v4l2-ctl -d /dev/video0 --set-ctrl=sharpness=143
/usr/bin/v4l2-ctl -d /dev/video0 --set-ctrl=sharpness=0

0
投票

我已经使用这种技术很多年了,但是大多数答案缺乏的一件事是对唯一性的检查。例如,当我在数据库中存储枚举值时,我通常使用 int,因此我不仅需要每个值映射到 int,而且还需要每个值都有一个唯一的 int。这是我的做法

  • 警告:相当多的样板代码
  • 另外:在这种特定情况下,我处理默认值,以防数据库中的 int 为 NULL
  • 我还免费获得了一个 O(1) 方法来通过 int id 检索我的枚举,这可能比迭代枚举值慢,除非你有几十个枚举值,但仍然如此。
  • 如果你定义了多个具有相同ID的枚举值,它不会在编译时被捕获,而是在运行时作为类解析捕获,这意味着你的单元测试将崩溃,你的应用程序将无法启动,它会提前崩溃
public enum Workflow {
  DEFAULT(0),
  WORKFLOW_TYPE_PACKAGE(1);

  final int id;

  Workflow(int id) {
    this.id = id;
    WorkflowById.put(this);
  }

  public static Workflow byId(Integer id) {
    var res = Workflow.get(id);
    if (res == null) res = Workflow.OTHER;
    return res;
  }
}

class WorkflowById {
  static final Map<Integer, Workflow> all = new HashMap<>();
  static void put(Workflow w) {
    var already = all.put(w.id, w);
    if (already != null) {
      throw new RuntimeException("Workflow#" + w.id + " is defined twice");
    }
  }
  static Workflow get(Integer id) {
    return all.get(id);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.