Conveniently map between enum and int / String

前端 未结 18 1713
陌清茗
陌清茗 2020-11-28 01:07

When working with variables/parameters that can only take a finite number of values, I try to always use Java\'s enum, as in

public enum BonusT         


        
相关标签:
18条回答
  • 2020-11-28 01:11

    In this code, for permanent and intense search , have memory or process for use, and I select memory, with converter array as index. I hope it's helpful

    public enum Test{ 
    VALUE_ONE(101, "Im value one"),
    VALUE_TWO(215, "Im value two");
    private final int number;
    private final byte[] desc;
    
    private final static int[] converter = new int[216];
    static{
        Test[] st = values();
        for(int i=0;i<st.length;i++){
            cv[st[i].number]=i;
        }
    }
    
    Test(int value, byte[] description) {
        this.number = value;
        this.desc = description;
    }   
    public int value() {
        return this.number;
    }
    public byte[] description(){
        return this.desc;
    }
    
    public static String description(int value) {
        return values()[converter[rps]].desc;
    }
    
    public static Test fromValue(int value){
    return values()[converter[rps]];
    }
    }
    
    0 讨论(0)
  • 2020-11-28 01:11

    If you have a class Car

    public class Car {
        private Color externalColor;
    }
    

    And the property Color is a class

    @Data
    public class Color {
        private Integer id;
        private String name;
    }
    

    And you want to convert Color to an Enum

    public class CarDTO {
        private ColorEnum externalColor;
    }
    

    Simply add a method in Color class to convert Color in ColorEnum

    @Data
    public class Color {
        private Integer id;
        private String name;
    
        public ColorEnum getEnum(){
            ColorEnum.getById(id);
        }
    }
    

    and inside ColorEnum implements the method getById()

    public enum ColorEnum {
    ...
        public static ColorEnum getById(int id) {
            for(ColorEnum e : values()) {
                if(e.id==id) 
                    return e;
            }
        }
    }
    

    Now you can use a classMap

    private MapperFactory factory = new DefaultMapperFactory.Builder().build();
    ...
    factory.classMap(Car.class, CarDTO.class)
        .fieldAToB("externalColor.enum","externalColor")
        .byDefault()
        .register();
    ...
    CarDTO dto = mapper.map(car, CarDTO.class);
    
    0 讨论(0)
  • 2020-11-28 01:13

    enum → int

    yourEnum.ordinal()
    

    int → enum

    EnumType.values()[someInt]
    

    String → enum

    EnumType.valueOf(yourString)
    

    enum → String

    yourEnum.name()
    

    A side-note:
    As you correctly point out, the ordinal() may be "unstable" from version to version. This is the exact reason why I always store constants as strings in my databases. (Actually, when using MySql, I store them as MySql enums!)

    0 讨论(0)
  • 2020-11-28 01:15

    http://www.javaspecialists.co.za/archive/Issue113.html

    The solution starts out similar to yours with an int value as part of the enum definition. He then goes on to create a generics-based lookup utility:

    public class ReverseEnumMap<V extends Enum<V> & EnumConverter> {
        private Map<Byte, V> map = new HashMap<Byte, V>();
        public ReverseEnumMap(Class<V> valueType) {
            for (V v : valueType.getEnumConstants()) {
                map.put(v.convert(), v);
            }
        }
    
        public V get(byte num) {
            return map.get(num);
        }
    }
    

    This solution is nice and doesn't require 'fiddling with reflection' because it's based on the fact that all enum types implicitly inherit the Enum interface.

    0 讨论(0)
  • 2020-11-28 01:16

    A very clean usage example of reverse Enum

    Step 1 Define an interface EnumConverter

    public interface EnumConverter <E extends Enum<E> & EnumConverter<E>> {
        public String convert();
        E convert(String pKey);
    }
    

    Step 2

    Create a class name ReverseEnumMap

    import java.util.HashMap;
    import java.util.Map;
    
    public class ReverseEnumMap<V extends Enum<V> & EnumConverter<V>> {
        private Map<String, V> map = new HashMap<String, V>();
    
        public ReverseEnumMap(Class<V> valueType) {
            for (V v : valueType.getEnumConstants()) {
                map.put(v.convert(), v);
            }
        }
    
        public V get(String pKey) {
            return map.get(pKey);
        }
    }
    

    Step 3

    Go to you Enum class and implement it with EnumConverter<ContentType> and of course override interface methods. You also need to initialize a static ReverseEnumMap.

    public enum ContentType implements EnumConverter<ContentType> {
        VIDEO("Video"), GAME("Game"), TEST("Test"), IMAGE("Image");
    
        private static ReverseEnumMap<ContentType> map = new ReverseEnumMap<ContentType>(ContentType.class);
    
        private final String mName;
    
        ContentType(String pName) {
            this.mName = pName;
        }
    
        String value() {
            return this.mName;
        }
    
        @Override
        public String convert() {
            return this.mName;
        }
    
        @Override
        public ContentType convert(String pKey) {
            return map.get(pKey);
        }
    }
    

    Step 4

    Now create a Communication class file and call it's new method to convert an Enum to String and String to Enum. I have just put main method for explanation purpose.

    public class Communication<E extends Enum<E> & EnumConverter<E>> {
        private final E enumSample;
    
        public Communication(E enumSample) {
            this.enumSample = enumSample;
        }
    
        public String resolveEnumToStringValue(E e) {
            return e.convert();
        }
    
        public E resolveStringEnumConstant(String pName) {
            return enumSample.convert(pName);
        }
    
    //Should not put main method here... just for explanation purpose. 
        public static void main(String... are) {
            Communication<ContentType> comm = new Communication<ContentType>(ContentType.GAME);
            comm.resolveEnumToStringValue(ContentType.GAME); //return Game
            comm.resolveStringEnumConstant("Game"); //return GAME (Enum)
        }
    }
    

    Click for for complete explanation

    0 讨论(0)
  • 2020-11-28 01:17

    I found this on the web, it was very helpful and simple to implement. This solution was NOT made by me

    http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks

    public enum Status {
     WAITING(0),
     READY(1),
     SKIPPED(-1),
     COMPLETED(5);
    
     private static final Map<Integer,Status> lookup 
          = new HashMap<Integer,Status>();
    
     static {
          for(Status s : EnumSet.allOf(Status.class))
               lookup.put(s.getCode(), s);
     }
    
     private int code;
    
     private Status(int code) {
          this.code = code;
     }
    
     public int getCode() { return code; }
    
     public static Status get(int code) { 
          return lookup.get(code); 
     }
    

    }

    0 讨论(0)
提交回复
热议问题