Convert integer value to matching Java Enum

前端 未结 11 1235
慢半拍i
慢半拍i 2020-12-02 08:18

I\'ve an enum like this:

public enum PcapLinkType {
  DLT_NULL(0)
  DLT_EN10MB(1)
  DLT_EN3MB(2),
  DLT_AX25(3),
  /*snip, 200 more enums, not always consecu         


        
相关标签:
11条回答
  • 2020-12-02 08:43

    There is no way to elegantly handle integer-based enumerated types. You might think of using a string-based enumeration instead of your solution. Not a preferred way all the times, but it still exists.

    public enum Port {
      /**
       * The default port for the push server.
       */
      DEFAULT("443"),
    
      /**
       * The alternative port that can be used to bypass firewall checks
       * made to the default <i>HTTPS</i> port.
       */
      ALTERNATIVE("2197");
    
      private final String portString;
    
      Port(final String portString) {
        this.portString = portString;
      }
    
      /**
       * Returns the port for given {@link Port} enumeration value.
       * @return The port of the push server host.
       */
      public Integer toInteger() {
        return Integer.parseInt(portString);
      }
    }
    
    0 讨论(0)
  • 2020-12-02 08:46

    This is what I use:

    public enum Quality {ENOUGH,BETTER,BEST;
                         private static final int amount = EnumSet.allOf(Quality.class).size();
                         private static Quality[] val = new Quality[amount];
                         static{ for(Quality q:EnumSet.allOf(Quality.class)){ val[q.ordinal()]=q; } }
                         public static Quality fromInt(int i) { return val[i]; }
                         public Quality next() { return fromInt((ordinal()+1)%amount); }
                        }
    
    0 讨论(0)
  • 2020-12-02 08:48

    You can do something like this to automatically register them all into a collection with which to then easily convert the integers to the corresponding enum. (BTW, adding them to the map in the enum constructor is not allowed. It's nice to learn new things even after many years of using Java. :)

    public enum PcapLinkType {
        DLT_NULL(0),
        DLT_EN10MB(1),
        DLT_EN3MB(2),
        DLT_AX25(3),
        /*snip, 200 more enums, not always consecutive.*/
        DLT_UNKNOWN(-1);
    
        private static final Map<Integer, PcapLinkType> typesByValue = new HashMap<Integer, PcapLinkType>();
    
        static {
            for (PcapLinkType type : PcapLinkType.values()) {
                typesByValue.put(type.value, type);
            }
        }
    
        private final int value;
    
        private PcapLinkType(int value) {
            this.value = value;
        }
    
        public static PcapLinkType forValue(int value) {
            return typesByValue.get(value);
        }
    }
    
    0 讨论(0)
  • 2020-12-02 08:52
    static final PcapLinkType[] values  = { DLT_NULL, DLT_EN10MB, DLT_EN3MB, null ...}    
    
    ...
    
    public static PcapLinkType  getPcapLinkTypeForInt(int num){    
        try{    
           return values[int];    
        }catch(ArrayIndexOutOfBoundsException e){    
           return DLT_UKNOWN;    
        }    
    }    
    
    0 讨论(0)
  • 2020-12-02 08:54

    I know this question is a few years old, but as Java 8 has, in the meantime, brought us Optional, I thought I'd offer up a solution using it (and Stream and Collectors):

    public enum PcapLinkType {
      DLT_NULL(0),
      DLT_EN3MB(2),
      DLT_AX25(3),
      /*snip, 200 more enums, not always consecutive.*/
      // DLT_UNKNOWN(-1); // <--- NO LONGER NEEDED
    
      private final int value;
      private PcapLinkType(int value) { this.value = value; }
    
      private static final Map<Integer, PcapLinkType> map;
      static {
        map = Arrays.stream(values())
            .collect(Collectors.toMap(e -> e.value, e -> e));
      }
    
      public static Optional<PcapLinkType> fromInt(int value) {
        return Optional.ofNullable(map.get(value));
      }
    }
    

    Optional is like null: it represents a case when there is no (valid) value. But it is a more type-safe alternative to null or a default value such as DLT_UNKNOWN because you could forget to check for the null or DLT_UNKNOWN cases. They are both valid PcapLinkType values! In contrast, you cannot assign an Optional<PcapLinkType> value to a variable of type PcapLinkType. Optional makes you check for a valid value first.

    Of course, if you want to retain DLT_UNKNOWN for backward compatibility or whatever other reason, you can still use Optional even in that case, using orElse() to specify it as the default value:

    public enum PcapLinkType {
      DLT_NULL(0),
      DLT_EN3MB(2),
      DLT_AX25(3),
      /*snip, 200 more enums, not always consecutive.*/
      DLT_UNKNOWN(-1);
    
      private final int value;
      private PcapLinkType(int value) { this.value = value; }
    
      private static final Map<Integer, PcapLinkType> map;
      static {
        map = Arrays.stream(values())
            .collect(Collectors.toMap(e -> e.value, e -> e));
      }
    
      public static PcapLinkType fromInt(int value) {
        return Optional.ofNullable(map.get(value)).orElse(DLT_UNKNOWN);
      }
    }
    
    0 讨论(0)
  • 2020-12-02 08:54

    You could add a static method in your enum that accepts an int as a parameter and returns a PcapLinkType.

    public static PcapLinkType of(int linkType) {
    
        switch (linkType) {
            case -1: return DLT_UNKNOWN
            case 0: return DLT_NULL;
    
            //ETC....
    
            default: return null;
    
        }
    }
    
    0 讨论(0)
提交回复
热议问题