enumとint / Stringの間の便利なマッピング


108

唯一の有限個の値を取ることができ、変数/パラメータを操作するとき、私はいつも、Javaのを使用しようとするenumのように、

public enum BonusType {
  MONTHLY, YEARLY, ONE_OFF
}

コード内にいる限り、問題なく動作します。ただし、同じ目的でプレーンint(またはString)の値を使用する他のコードとやり取りする必要がある場合や、データが数値または文字列として格納されているデータベースとの間で読み書きを行う必要があります。

その場合、両方の方法で変換できるように、各enum値を整数に関連付ける便利な方法が必要です(つまり、「可逆enum」が必要です)。

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

私が思いつくことができる唯一の解決策は:

  • ルックアップメソッドをenumに入れます。これはBonusType.values()、マップ「int-> enum」を埋めるために使用し、それをキャッシュしてルックアップに使用します。動作しますが、このメソッドを使用する各列挙型に同じようにコピーする必要があります:-(。
  • ルックアップメソッドを静的ユーティリティクラスに配置します。次に、必要なのは1つの「ルックアップ」メソッドだけですが、任意の列挙型で機能させるには、リフレクションをいじる必要があります。

どちらの方法も、このような単純な(?)問題にはひどく扱いにくいようです。

他のアイデア/洞察?


1
私は3つ以下のJava列挙型ですが、この理由でそれらを正確に嫌います 本当に醜い欠陥を除けば、彼らは完璧だといつも思われます...
クリストンプソン

8
enum-> intの場合はそのまま使用できますordinal()
davin

1
あなたのid値はあなた.ordinal()が決めることができますか(つまり、あなたは単に使うことができませんでした)、またはそれらは外部の力によって決定されますか?
–PaŭloEbermann、2011

2
@davin:はい。誰かが列挙型宣言を並べ替えたり、途中で値を削除したりしたときに、コードを中断させます。私はそれが堅牢な解決策ではないことを恐れています:-/。
sleske 2011

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 2013年

3
本当にそして本当に質問を読んでください。独自のコードを通じて伝播したくない整数が定義されているレガシーデータベースまたは外部システムを扱っている場合、これはまさにその1つのケースです。序数は、列挙型の値を永続化するための非常に壊れやすい方法であり、それを超えて、質問で言及されている特定のケースでは役に立たない。
ジェフ

327

列挙型→整数

yourEnum.ordinal()

int→列挙型

EnumType.values()[someInt]

文字列→列挙型

EnumType.valueOf(yourString)

列挙型→文字列

yourEnum.name()

補足:
正しく指摘したように、ordinal()バージョンごとに「不安定」になる可能性があります。これが、データベースに定数を常に文字列として保存するまさにその理由です。(実際、MySqlを使用するときは、MySql列挙型として保存します!)


2
+1これは明らかに正しい答えです。注意、あなたがコンクリート列挙型を使用しているとしてだけで文字列を取り、限り存在するのvalueOfのための単一の引数の方法がありますが、(例えばBonusType.valueOf("MONTHLY")
ティム・ベンダー

18
ordinal()enum値のリストが再配置されるか、値が削除されると壊れるので、問題のある解決策としてストライキを使用します。また、これはint値が0 ... nである場合にのみ実用的です(私はしばしばそうではないことがわかりました)。
sleske 2011

4
@sleske、定数の削除を開始すると、とにかく既存の永続化データに問題が発生します。(この点に関する私の答えを更新しました。)
aioobe

3
values()配列の使用は、すべての値のIDに0のインデックスが付けられ、順番に宣言されている場合にのみ機能します。(私はこれをテストして、あなたがそれを宣言した場合FOO(0), BAR(2), BAZ(1);values[1] == BARそしてvalues[2] == BAZ渡されたIDにもかかわらず、それを検証しました。)
corsiKa

2
@glowcoderはもちろん、整数の引数はenum-objectのフィールドにすぎません。これは、enumオブジェクトに関連付けられた序数定数とは何の関係もありません(それもaであった可能性がありますdouble)。
aioobe 2011

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 2015年

8

この質問に対する答えは、Java 8のリリースでは古くなっているようです。

  1. ordinalは、データベースなどの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をIDに変換する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);

これが存在することに気づかなかった。共有してくれてありがとう!
キースP

3

あなたはおそらく次のようなものを使うことができます

interface EnumWithId {
    public int getId();

}


enum Foo implements EnumWithId {

   ...
}

これにより、ユーティリティクラスでのリフレクションの必要性が減少します。


このスニペットの使用例を教えていただけますか?
IgorGanapolsky 2017

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()をループする必要がないように、静的{}ブロックで逆マッピングを作成します。私は通常、メソッドvalueOf(int)を呼び出して、StringsのvalueOf(String)メソッドのように見えるようにします(これもOPの質問の一部です)。有効なJavaの項目33とやや似ている:tinyurl.com/4ffvc38
Fredrik

@Sleskeより洗練されたソリューションで更新されました。@Fredrikは興味深いですが、反復が重要な問題になるとは思えません。
corsiKa 2011

@glowcoderまあ、2回以上繰り返す必要がないということは、1秒間に1,000回実行しても、非常に重大な問題になるか、2回呼び出すだけでも問題ないことを意味します。
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 2013年

2

逆列挙の非常にクリーンな使用例

ステップ1interface 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クラスに行きimplementEnumConverter<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をto StringStringto に変換する新しいメソッドを呼び出します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
クリスマントル

1

Javaでも同じかどうかはわかりませんが、Cの列挙型は自動的に整数にもマッピングされるため、型または整数を使用してアクセスできます。単純に整数でアクセスしてみましたか?


2
Javaの列挙型はそのように動作しません。それらは明示的なタイプです。
Chris Thompson

各enumオブジェクトには内部番号(つまり、それが宣言された位置)があり、.ordinal()メソッドからアクセスできます。(逆の場合はを使用しますBonusType.values()[i]。)しかし、上記の例では、ここのインデックスと外部の値は一致していません。
–PaŭloEbermann、2011

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)のようにすることでした。Fyi、私はここからこのメソッドをコピーしました

索引に関連する問題(すでにここで詳細に説明されています)が引き続き適用されます。

/**
 * 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

与えられた:

パブリック列挙型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;
}

そして、あなたはを列挙型に変換したい

public class CarDTO {
    private ColorEnum externalColor;
}

Colorクラスにメソッドを追加して、ColorEnumでColorを変換するだけです

@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.