enum과 int / String을 편리하게 매핑


108

유한 한 수의 값만 취할 수있는 변수 / 매개 변수로 작업 할 때 다음과 enum같이 항상 Java를 사용하려고합니다 .

public enum BonusType {
  MONTHLY, YEARLY, ONE_OFF
}

내 코드 안에 있으면 잘 작동합니다. 그러나 동일한 목적으로 일반 int(또는 String) 값을 사용하는 다른 코드와 인터페이스해야하는 경우가 많거나 데이터가 숫자 또는 문자열로 저장된 데이터베이스에서 읽거나 써야합니다.

이 경우 두 가지 방법을 모두 변환 할 수 있도록 각 열거 형 값을 정수와 연결하는 편리한 방법을 원합니다 (즉, "가역 열거 형"이 필요합니다).

enum에서 int로 이동하는 것은 쉽습니다.

public enum BonusType {
  public final int id;

  BonusType(int id) {
    this.id = id;
  }
  MONTHLY(1), YEARLY(2), ONE_OFF(3);
}

그런 다음 int 값에 BonusType x = MONTHLY; int id = x.id;.

그러나, 나는 반대로, 즉 int에서 enum으로가는 좋은 방법을 볼 수 없습니다. 이상적으로는

BonusType bt = BonusType.getById(2); 

내가 생각 해낼 수있는 유일한 해결책은 다음과 같습니다.

  • BonusType.values()"int-> enum"맵을 채우는 데 사용하는 조회 메소드를 enum 에 넣은 다음이를 캐시하여 조회에 사용합니다. 작동하지만이 메서드를 사용하는 각 열거 형에 동일하게 복사해야합니다. :-(.
  • 조회 메소드를 정적 유틸리티 클래스에 넣으십시오. 그런 다음 하나의 "조회"메서드 만 필요하지만 임의의 열거 형에 대해 작동하려면 리플렉션을 사용하여 조작해야합니다.

두 가지 방법 모두 이러한 간단한 (?) 문제에 대해 매우 어색해 보입니다.

다른 아이디어 / 통찰이 있습니까?


1
나는 <3 자바 열거 형이지만 정확히 이런 이유로 싫어합니다! 정말 못생긴 결함을 제외하고는 항상 완벽 해 보입니다 ...
— Chris Thompson

8
enum-> int의 경우 그냥 사용할 수 있습니다ordinal()
— davin

1
당신의 id-value는 당신이 결정할 수 있습니까 (즉, 당신은 사용할 수 없습니다 .ordinal()), 아니면 외부 세력에 의해 결정됩니까?
— Paŭlo Ebermann

2
@davin : 예, 누군가 열거 형 선언을 재정렬하거나 중간에있는 값을 삭제하는 순간 코드가 깨지게하십시오. 강력한 솔루션이 아닌 것 같습니다 :-/.
— sleske

1
"ordinal ()"을 사용하는 @davin은 가능한 한 피해야합니다. 언어 사양에 있습니다
— DPM

답변:


37

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

솔루션은 열거 형 정의의 일부로 int 값을 사용하여 사용자와 유사하게 시작됩니다. 그런 다음 계속해서 제네릭 기반 조회 유틸리티를 만듭니다.

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

이 솔루션은 훌륭하며 모든 열거 형 유형이 암시 적으로 Enum 인터페이스를 상속한다는 사실을 기반으로하기 때문에 '반사 처리'가 필요하지 않습니다.


서수를 사용하지 않습니까? Sleske는 열거 형 값이 다시 정렬 될 때 서 수가 변경되기 때문에 id를 사용합니다.
— extraneon

아니요, 서수를 사용하지 않습니다. 명시 적으로 정의 된 int 값에 의존합니다. 해당 int 값은 맵 키로 사용됩니다 (v.convert ()에서 반환 됨).
— 제프

2
이 솔루션이 정말 마음에 듭니다. 이것이 당신이 얻을 수있는 가장 일반적인 것 같습니다.
— sleske

+1. 내 유일한 메모는 내 백업 값이 더 클 수 있기 때문에 Number대신을 사용한다는 것 Byte입니다.
— Ivaylo Slavov

3
정말로 그리고 진정으로 질문을 읽으십시오. 자신의 코드를 통해 전파하지 않으려는 정수를 정의한 레거시 데이터베이스 또는 외부 시스템을 처리하는 경우 정확히 이러한 경우 중 하나입니다. 서수는 열거 형의 값을 유지하는 매우 취약한 방법이며 그 이상으로 질문에 언급 된 특정 경우에는 쓸모가 없습니다.
— 제프

327

열거 형 → 정수

yourEnum.ordinal()

int → 열거 형

EnumType.values()[someInt]

문자열 → 열거 형

EnumType.valueOf(yourString)

열거 형 → 문자열

yourEnum.name()

참고 :
올바르게 지적했듯이 ordinal()버전마다 "불안정"할 수 있습니다. 이것이 내가 항상 데이터베이스에 문자열로 상수를 저장하는 정확한 이유입니다. (실제로 MySql을 사용할 때 MySql 열거 형 으로 저장합니다 !)


2
+1 이것은 분명한 정답입니다. 참고, 당신은 콘크리트 열거 형을 사용하고 같은 단지 문자열을 받아 한 존재 valueOf에 대한 하나의 인자 방법이있다하더라도 (예 BonusType.valueOf("MONTHLY"))
— 팀 벤더

18
ordinal()열거 형 값 목록이 재정렬되거나 값이 삭제되면 깨지기 때문에 사용하면 문제가있는 해결책으로 떠 오릅니다. 또한 이것은 int 값이 0 ... n 인 경우에만 실용적입니다 (나는 종종 그렇지 않은 것으로 나타났습니다).
— sleske

4
@sleske, 상수 삭제를 시작하면 어쨌든 기존 지속 데이터에 문제가 있습니다. (이와 관련하여 내 답변을 업데이트했습니다.)
— aioobe

3
values()배열 사용은 모든 값이 ID에 대해 0 인덱싱되고 순서대로 선언 된 경우에만 작동합니다. (나는이 확인 테스트 당신은 선언하는 경우 FOO(0), BAR(2), BAZ(1);그 values[1] == BAR와 values[2] == BAZ전달 된 식별자에도 불구하고.)
— corsiKa

2
@glowcoder, 당연히 정수 인수는 단순히 열거 형 개체의 필드입니다. enum 객체와 관련된 서수 상수와는 아무 관련이 없습니다 (일 수도 있음 double).
— aioobe

29

나는 이것을 웹에서 발견했고, 구현하기 매우 유용하고 간단했습니다. 이 솔루션은 내가 만든 것이 아닙니다.

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

}


S / EnumSet.allOf (Status.class) /Status.values ()
— jelinson

8

이 질문에 대한 답변은 Java 8 릴리스와 함께 구식입니다.

  1. 서수는 데이터베이스와 같은 JVM 외부에서 지속되는 경우 불안정하므로 서수를 사용하지 마십시오.
  2. 키 값으로 정적지도를 만드는 것은 비교적 쉽습니다.

public enum AccessLevel {
  PRIVATE("private", 0),
  PUBLIC("public", 1),
  DEFAULT("default", 2);

  AccessLevel(final String name, final int value) {
    this.name = name;
    this.value = value;
  }

  private final String name;
  private final int value;

  public String getName() {
    return name;
  }

  public int getValue() {
    return value;
  }

  static final Map<String, AccessLevel> names = Arrays.stream(AccessLevel.values())
      .collect(Collectors.toMap(AccessLevel::getName, Function.identity()));
  static final Map<Integer, AccessLevel> values = Arrays.stream(AccessLevel.values())
      .collect(Collectors.toMap(AccessLevel::getValue, Function.identity()));

  public static AccessLevel fromName(final String name) {
    return names.get(name);
  }

  public static AccessLevel fromValue(final int value) {
    return values.get(value);
  }
}

대신 두 번째 매개 변수가 Collectors.toMap()되어야 Functions.identity()하지 null않습니까?
— Adam Michalik 2015

예, 나는 null을 정체성으로 변환하는 guava와 함께 사용하는 도우미 클래스에서 이것을 채택했습니다.
— John Meyer

이것은 Java 8의 새로운 기능을 깔끔하게 사용한 것입니다. 그러나 여전히 코드가 모든 열거 형에서 반복되어야 함을 의미하며 내 질문은 (구조적으로) 반복되는 상용구를 피하는 것이 었습니다.
— sleske

5

org.apache.commons.lang.enums.ValuedEnum;

많은 상용구 코드를 작성하거나 각 Enum에 대한 코드를 복제하지 않기 위해 ValuedEnum대신 Apache Commons Lang을 사용했습니다.

정의 :

public class NRPEPacketType extends ValuedEnum {    
    public static final NRPEPacketType TYPE_QUERY = new NRPEPacketType( "TYPE_QUERY", 1);
    public static final NRPEPacketType TYPE_RESPONSE = new NRPEPacketType( "TYPE_RESPONSE", 2);

    protected NRPEPacketType(String name, int value) {
        super(name, value);
    }
}

용법:

int-> ValuedEnum :

NRPEPacketType packetType = 
 (NRPEPacketType) EnumUtils.getEnum(NRPEPacketType.class, 1);

좋은 생각입니다. 이것이 존재한다는 것을 몰랐습니다. 공유해 주셔서 감사합니다!
— Keith P

3

아마도 다음과 같은 것을 사용할 수 있습니다.

interface EnumWithId {
    public int getId();

}


enum Foo implements EnumWithId {

   ...
}

그러면 유틸리티 클래스에서 반영 할 필요가 줄어 듭니다.


이 스 니펫을 사용하는 방법의 예를 제공 할 수 있습니까?
— IgorGanapolsky

3

이 코드에서는 영구적이고 집중적 인 검색을 위해 사용할 메모리 또는 프로세스가 있고 변환기 배열을 인덱스로 사용하여 메모리를 선택합니다. 도움이 되었기를 바랍니다.

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

2

인터페이스를 사용하여 누가 보스인지 보여주세요.

public interface SleskeEnum {
    int id();

    SleskeEnum[] getValues();

}

public enum BonusType implements SleskeEnum {


  MONTHLY(1), YEARLY(2), ONE_OFF(3);

  public final int id;

  BonusType(int id) {
    this.id = id;
  }

  public SleskeEnum[] getValues() {
    return values();
  }

  public int id() { return id; }


}

public class Utils {

  public static SleskeEnum getById(SleskeEnum type, int id) {
      for(SleskeEnum t : type.getValues())
          if(t.id() == id) return t;
      throw new IllegalArgumentException("BonusType does not accept id " + id);
  }

  public static void main(String[] args) {

      BonusType shouldBeMonthly = (BonusType)getById(BonusType.MONTHLY,1);
      System.out.println(shouldBeMonthly == BonusType.MONTHLY);

      BonusType shouldBeMonthly2 = (BonusType)getById(BonusType.MONTHLY,1);
      System.out.println(shouldBeMonthly2 == BonusType.YEARLY);

      BonusType shouldBeYearly = (BonusType)getById(BonusType.MONTHLY,2);
      System.out.println(shouldBeYearly  == BonusType.YEARLY);

      BonusType shouldBeOneOff = (BonusType)getById(BonusType.MONTHLY,3);
      System.out.println(shouldBeOneOff == BonusType.ONE_OFF);

      BonusType shouldException = (BonusType)getById(BonusType.MONTHLY,4);
  }
}

그 결과 :

C:\Documents and Settings\user\My Documents>java Utils
true
false
true
true
Exception in thread "main" java.lang.IllegalArgumentException: BonusType does not accept id 4
        at Utils.getById(Utils.java:6)
        at Utils.main(Utils.java:23)

C:\Documents and Settings\user\My Documents>

1
Turd Ferguson의 대답과 마찬가지로, 그것은 제가 피하고 개선하고 싶은 불법적 인 해결책입니다 ...
— sleske

일반적으로 id로 값을 요청할 때마다 values ​​()를 반복 할 필요가 없도록 static {} 블록에서 역 매핑을 만듭니다. 또한 일반적으로 valueOf (int) 메서드를 호출하여 Strings (OP 질문의 일부)에 대해 이미있는 valueOf (String) 메서드와 비슷하게 표시되도록합니다. Effective Java : tinyurl.com/4ffvc38의
— Fredrik

@Sleske 더 세련된 솔루션으로 업데이트되었습니다. @Fredrik은 흥미롭지 만 반복이 중요한 문제가 될 것 같지 않습니다.
— corsiKa

@glowcoder 글쎄요, 한 번 이상 반복 할 필요가 없다는 것은 매우 중요한 문제가 될 수있는 경우 초당 수천 번 수행하거나 두 번 호출하는 것이 중요하지 않다는 것을 의미합니다.
— Fredrik

@Fredrik 나는 최적화가 필요할 때가 있다는 것을 인정할 것입니다. 또한 확인 된 성능 문제가 될 때까지 최적화하지 마십시오.
— corsiKa

2

.ordinal()및 둘 다 values()[i]열거 형 순서에 종속되기 때문에 불안정합니다. 따라서 열거 형의 순서를 변경하거나 일부를 추가 / 삭제하면 프로그램이 중단됩니다.

enum과 int를 매핑하는 간단하면서도 효과적인 방법이 있습니다.

public enum Action {
    ROTATE_RIGHT(0), ROTATE_LEFT(1), RIGHT(2), LEFT(3), UP(4), DOWN(5);

    public final int id;
    Action(int id) {
        this.id = id;
    }

    public static Action get(int id){
        for (Action a: Action.values()) {
            if (a.id == id)
                return a;
        }
        throw new IllegalArgumentException("Invalid id");
    }
}

문자열에 적용하는 것은 어렵지 않습니다.


예, 저는 그렇게 할 수 있다는 것을 알고 있습니다. 모든 값을 반복하는 대신 역방향 조회를 위해 맵을 사용하는 것이 더 좋습니다. 나는 내 질문에서 이것을 언급했으며 각 열거 형에 상용구 코드를 사용하지 않기 위해 더 나은 솔루션을 찾고 있다고 언급했습니다.
— sleske

2

Reverse Enum의 매우 깨끗한 사용 예

1 단계interface EnumConverter 정의

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

2 단계

클래스 이름 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);
    }
}

3 단계

당신로 이동 Enum클래스와 implement그것과 EnumConverter<ContentType>물론 재정의 인터페이스 방법. 또한 정적 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);
    }
}

4 단계

이제 생성 Communication클래스 파일과는 변환 할 수있는 새로운 방법의 부름 Enum에 String와 String에 Enum. 설명 목적으로 주요 방법을 넣었습니다.

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

자세한 설명을 보려면 클릭하십시오.


1
이것은 정말, 정말 좋아합니다. 저는 지금이 문제에 대한 확실한 해결책을 찾고있었습니다. 내가 만든 유일한 변경 사항은 ContentType convert(String pKey)정적 으로 만드는 것이 었는데 , 이는 Communication클래스 의 필요성을 제거하고 내 취향에 더 적합했습니다. +1
— Chris Mantle

1

Java에서 동일한 지 확실하지 않지만 C의 열거 형 유형도 자동으로 정수로 매핑되므로 유형 또는 정수를 사용하여 액세스 할 수 있습니다. 아직 정수로 간단히 액세스 해 보셨습니까?


2
Java의 열거 형은 그렇게 작동하지 않습니다. 그들은 명시적인 유형입니다.
— Chris Thompson

각 열거 형 개체에는 내부 번호 (즉, 선언 된 위치)가 있으며 .ordinal()메서드에서 액세스 할 수 있습니다 . (또는를 사용하십시오 BonusType.values()[i].) 그러나 위에 인용 된 예에서는 여기에있는 색인과 외부 값이 일치하지 않습니다.
— Paŭlo Ebermann

1

정말 좋은 질문 :-) 언젠가 퍼거슨 씨와 비슷한 솔루션을 사용했습니다. 디 컴파일 된 열거 형은 다음과 같습니다.

final class BonusType extends Enum
{

    private BonusType(String s, int i, int id)
    {
        super(s, i);
        this.id = id;
    }

    public static BonusType[] values()
    {
        BonusType abonustype[];
        int i;
        BonusType abonustype1[];
        System.arraycopy(abonustype = ENUM$VALUES, 0, abonustype1 = new BonusType[i = abonustype.length], 0, i);
        return abonustype1;
    }

    public static BonusType valueOf(String s)
    {
        return (BonusType)Enum.valueOf(BonusType, s);
    }

    public static final BonusType MONTHLY;
    public static final BonusType YEARLY;
    public static final BonusType ONE_OFF;
    public final int id;
    private static final BonusType ENUM$VALUES[];

    static 
    {
        MONTHLY = new BonusType("MONTHLY", 0, 1);
        YEARLY = new BonusType("YEARLY", 1, 2);
        ONE_OFF = new BonusType("ONE_OFF", 2, 3);
        ENUM$VALUES = (new BonusType[] {
            MONTHLY, YEARLY, ONE_OFF
        });
    }
}

이것을 보는 것이 왜 ordinal()불안정한 지 분명 합니다. 그것은이다 i에서 super(s, i);. 나는 또한 당신이 이미 열거 한 것보다 더 우아한 해결책을 생각할 수 있다는 비관적이다. 모든 열거 형은 최종 클래스와 같은 클래스입니다.


1

완전성을 위해 모든 열거 형 유형에서 인덱스별로 열거 형 값을 검색하는 일반적인 방법은 다음과 같습니다. 내 의도는 메서드를 Enum.valueOf (Class, String) 처럼 보이고 느끼도록 만드는 것이 었습니다 . 참고로 여기 에서이 방법을 복사했습니다 .

인덱스 관련 문제 (이미 여기서 자세히 논의 됨)는 여전히 적용됩니다.

/**
 * Returns the {@link Enum} instance for a given ordinal.
 * This method is the index based alternative
 * to {@link Enum#valueOf(Class, String)}, which
 * requires the name of an instance.
 * 
 * @param <E> the enum type
 * @param type the enum class object
 * @param ordinal the index of the enum instance
 * @throws IndexOutOfBoundsException if ordinal < 0 || ordinal >= enums.length
 * @return the enum instance with the given ordinal
 */
public static <E extends Enum<E>> E valueOf(Class<E> type, int ordinal) {
    Preconditions.checkNotNull(type, "Type");
    final E[] enums = type.getEnumConstants();
    Preconditions.checkElementIndex(ordinal, enums.length, "ordinal");
    return enums[ordinal];
}

이것은 할당 된 정수 ID가 아닌 서 수로 만 열거 형 값을 검색하기 때문에 내가 찾고있는 것이 아닙니다 (제 질문 참조). 또한 원하는 경우 MyEnumType.values()정적 도우미 메서드를 사용할 필요가 없습니다.
— sleske

0
Int -->String :

public enum Country {

    US("US",0),
    UK("UK",2),
    DE("DE",1);


    private static Map<Integer, String> domainToCountryMapping; 
    private String country;
    private int domain;

    private Country(String country,int domain){
        this.country=country.toUpperCase();
        this.domain=domain;
    }

    public String getCountry(){
        return country;
    }


    public static String getCountry(String domain) {
        if (domainToCountryMapping == null) {
            initMapping();
        }

        if(domainToCountryMapping.get(domain)!=null){
            return domainToCountryMapping.get(domain);
        }else{
            return "US";
        }

    }

     private static void initMapping() {
         domainToCountryMapping = new HashMap<Integer, String>();
            for (Country s : values()) {
                domainToCountryMapping.put(s.domain, s.country);
            }
        }

0

일반적인 접근 방식을 사용하고 싶었 기 때문에 다른 것이 필요했습니다. 열거 형과 바이트 배열을 읽고 있습니다. 이것이 내가 생각하는 곳입니다.

public interface EnumConverter {
    public Number convert();
}



public class ByteArrayConverter {
@SuppressWarnings("unchecked")
public static Enum<?> convertToEnum(byte[] values, Class<?> fieldType, NumberSystem numberSystem) throws InvalidDataException {
    if (values == null || values.length == 0) {
        final String message = "The values parameter must contain the value";
        throw new IllegalArgumentException(message);
    }

    if (!dtoFieldType.isEnum()) {
        final String message = "dtoFieldType must be an Enum.";
        throw new IllegalArgumentException(message);
    }

    if (!EnumConverter.class.isAssignableFrom(fieldType)) {
        final String message = "fieldType must implement the EnumConverter interface.";
        throw new IllegalArgumentException(message);
    }

    Enum<?> result = null;
    Integer enumValue = (Integer) convertToType(values, Integer.class, numberSystem); // Our enum's use Integer or Byte for the value field.

    for (Object enumConstant : fieldType.getEnumConstants()) {
        Number ev = ((EnumConverter) enumConstant).convert();

        if (enumValue.equals(ev)) {
            result = (Enum<?>) enumConstant;
            break;
        }
    }

    if (result == null) {
        throw new EnumConstantNotPresentException((Class<? extends Enum>) fieldType, enumValue.toString());
    }

    return result;
}

public static byte[] convertEnumToBytes(Enum<?> value, int requiredLength, NumberSystem numberSystem) throws InvalidDataException {
    if (!(value instanceof EnumConverter)) {
        final String message = "dtoFieldType must implement the EnumConverter interface.";
        throw new IllegalArgumentException(message);
    }

    Number enumValue = ((EnumConverter) value).convert();
    byte[] result = convertToBytes(enumValue, requiredLength, numberSystem);
    return result;
}

public static Object convertToType(byte[] values, Class<?> type, NumberSystem numberSystem) throws InvalidDataException {
    // some logic to convert the byte array supplied by the values param to an Object.
}

public static byte[] convertToBytes(Object value, int requiredLength, NumberSystem numberSystem) throws InvalidDataException {
    // some logic to convert the Object supplied by the'value' param to a byte array.
}
}

열거 형의 예 :

public enum EnumIntegerMock implements EnumConverter {
    VALUE0(0), VALUE1(1), VALUE2(2);

    private final int value;

    private EnumIntegerMock(int value) {
        this.value = value;
    }

public Integer convert() {
    return value;
}

}

public enum EnumByteMock implements EnumConverter {
    VALUE0(0), VALUE1(1), VALUE2(2);

    private final byte value;

    private EnumByteMock(int value) {
        this.value = (byte) value;
    }

    public Byte convert() {
        return value;
    }
}

0

수락 된 답변이 자체 포함되지 않기 때문에 :

지원 코드 :

public interface EnumWithCode<E extends Enum<E> & EnumWithCode<E>> {

    public Integer getCode();

    E fromCode(Integer code);
}


public class EnumWithCodeMap<V extends Enum<V> & EnumWithCode<V>> {

    private final HashMap<Integer, V> _map = new HashMap<Integer, V>();

    public EnumWithCodeMap(Class<V> valueType) {
        for( V v : valueType.getEnumConstants() )
            _map.put(v.getCode(), v);
    }

    public V get(Integer num) {
        return _map.get(num);
    }
}

사용 예 :

public enum State implements EnumWithCode<State> {
    NOT_STARTED(0), STARTED(1), ENDED(2);

    private static final EnumWithCodeMap<State> map = new EnumWithCodeMap<State>(
            State.class);

    private final int code;

    private State(int code) {
        this.code = code;
    }

    @Override
    public Integer getCode() {
        return code;
    }

    @Override
    public State fromCode(Integer code) {
        return map.get(code);
    }

}

0

주어진:

public enum BonusType {MONTHLY (0), YEARLY (1), ONE_OFF (2)}

BonusType 보너스 = YEARLY;

System.out.println (bonus.Ordinal () + ":"+ 보너스)

산출 : 1 : YEARLY


0

클래스 카가있는 경우

public class Car {
    private Color externalColor;
}

그리고 속성 Color 는 클래스입니다.

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

그리고 Color 를 Enum 으로 변환하고 싶습니다.

public class CarDTO {
    private ColorEnum externalColor;
}

간단히에 메소드를 추가 색상 변환 클래스 색상 에 ColorEnum

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

    public ColorEnum getEnum(){
        ColorEnum.getById(id);
    }
}

ColorEnum 내부에서 getById () 메소드를 구현합니다.

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

이제 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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.