39

私は次のようにしてenumいます:

public enum EnumStatus {

    PASSED(40L, "Has Passed"),
    AVERAGE(60L, "Has Average Marks"),
    GOOD(80L, "Has Good Marks");

    private java.lang.String name;

    private java.lang.Long id;

    EnumStatus(Long id, java.lang.String name) {
        this.name = name;
        this.id = id;
    }

    public java.lang.String getName() {
        return name;
    }

    public java.lang.Long getId() {
        return id;
    }
}

IDのみ(40、60、80)を使用して列挙型names(、、)を取得する必要がありPASSEDますAVERAGEGOODどうすればいいのですか?

4

11 に答える 11

68

(暗黙のメソッド/メンバー、それが正確にはわからない)enumを検索する静的メソッドを作成し、対応する値を返します。valuesメソッドが一致する値を見つけられない場合は、たとえばUNKNOWNを返すことができる特別なエントリを作成する必要があります。nullこの方法では、常に悪い考えであるを返す必要はありません。

public static EnumStatus getById(Long id) {
    for(EnumStatus e : values()) {
        if(e.id.equals(id)) return e;
    }
    return UNKNOWN;
}

ところで - あなたのコードは間違っているようです。後のブラケットGOODはそこに属していないようです。

于 2013-03-13T08:35:02.940 に答える
15

これは、静的マップと静的初期化子を使用して行うことができます。

public enum EnumStatus {

    PASSED(40L, "Has Passed"),
    AVERAGE(60L, "Has Average Marks"),
    GOOD(80L, "Has Good Marks");

    private static final Map<Long, EnumStatus> byId = new HashMap<Long, EnumStatus>();
    static {
        for (EnumStatus e : EnumStatus.values()) {
            if (byId.put(e.getId(), e) != null) {
                throw new IllegalArgumentException("duplicate id: " + e.getId());
            }
        }
    }

    public static EnumStatus getById(Long id) {
        return byId.get(id);
    }

    // original code follows

    private java.lang.String name;

    private java.lang.Long id;

    EnumStatus(Long id, java.lang.String name) {
        this.name = name;
        this.id = id;
    }

    public java.lang.String getName() {
        return name;
    }

    public java.lang.Long getId() {
        return id;
    }

}

これによりO(1) getById()メソッドが提供され、列挙型に誤って重複した ID があるかどうかが自動的に検出されます。

于 2013-03-13T08:35:00.800 に答える
3

この作業は次のように行います。

public static String fromId(long id) {
        for (EnumStatus es : EnumStatus.values()) {
            if (es.id.equals(id)) {
                return es.getName();
            }
        }
        throw new IllegalArgumentException();
}
于 2013-03-13T08:39:22.407 に答える
2
public static EnumStatus getById(long id)
{
  for (EnumStatus e : EnumStatus.values())
  {
    if (id == e.getId()) return e;
  } 
  throw new IllegalArgumentException("oh no");
}
于 2013-03-13T08:41:36.787 に答える
1

メソッドを追加し、Enumid を渡して取得します。

 public static ArrayList<EnumStatus> getEnumStatusById(ArrayList<Long> idList) {
    ArrayList<EnumStatus> listById = new ArrayList();
    for(EnumStatus es: EnumStatus.values()) {
        if( idList.contains(es.getId())) {
            listById.add(es);
        }
    }
    return listById;
}
于 2013-03-13T08:38:30.913 に答える
0

列挙型の序数は、この種の id と明確な関係を持っている場合があり、これらのメソッドで O(1) を取得するための適切な方法を可能にします。あなたのコードでは、それは明らかです

EnumStatus.X = 40 + 20 * ordinal

そのため、内部で生成される静的配列を活用できます。

public static EnumStatus fromId(Long id) {
    int index = (id - 40L) / 20L;
    return values()[index];
}
于 2013-03-13T09:02:05.887 に答える
0

すべての値を反復し、Id を比較します

for (EnumStatus  enumStatus : EnumStatus.values()) {
   if (..) {..}
}
于 2013-03-13T08:35:10.057 に答える
0

契約の定義

/**
 * Contract that will allow Types with id to have generic implementation.
 */
public interface IdentifierType<T> {
  T getId();
}

契約を申し込む

public enum EntityType implements IdentifierType<Integer> {
  ENTITY1(1, "ONE), ENTITY2(2, "TWO");

  private Integer id;
  private String name;

  private EntityType(int id, String name) {
    this.id = id;
    this.name = name;
  }

  public static EntityType valueOf(Integer id) {
    return EnumHelper.INSTANCE.valueOf(id, EntityType.values());
  }

  @Override
  public Integer getId() {
    return id;
  }
}

ヘルパー/ユーティリティ

public enum EnumHelper {
  INSTANCE;

  /**
   * This will return {@link Enum} constant out of provided {@link Enum} values with the specified id.
   * @param id the id of the constant to return.
   * @param values the {@link Enum} constants of specified type.
   * @return the {@link Enum} constant.
   */
  public <T extends IdentifierType<S>, S> T valueOf(S id, T[] values) {
    if (!values[0].getClass().isEnum()) {
        throw new IllegalArgumentException("Values provided to scan is not an Enum");
    }

    T type = null;

    for (int i = 0; i < values.length && type == null; i++) {
        if (values[i].getId().equals(id)) {
            type = values[i];
        }
    }

    return type;
  }
}
于 2016-08-10T10:33:43.910 に答える
0

Java 8 が導入さOptionalれたため、戻り値の型として使用できます。次のような実装を検討してください。

public static Optional<EnumStatus> fromId(Long id) {
    for (EnumStatus e: values()) {
        if (e.id.equals(id)) {
            return Optional.of(e);
        }
    }
    return Optional.empty();
}

またはストリーム API を使用します。

public static Optional<EnumStatus> fromId(Long id) {
    return Stream.of(values())
            .filter(e -> e.id.equals(id))
            .findFirst();
}

『 Effective Java 3rd Edition』という本の中で、著者のJoshua BlochOptionalは、戻り値の型としても使用する効果的なソリューションを推奨しています。

private static final Map<String, Operation> stringToEnum =
    Stream.of(values()).collect(
        toMap(Object::toString, e -> e));

public static Optional<Operation> fromString(String symbol) {
    return Optional.ofNullable(stringToEnum.get(symbol));
}

を使用するブロッホの推論Optional:

fromString...メソッドが を返すことに注意してくださいOptional<Operation>。これにより、メソッドは、渡された文字列が有効な操作を表していないことを示すことができ、クライアントはこの可能性に直面することになります。

于 2020-11-16T13:46:00.010 に答える