我有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)来获取枚举名称(PASSED
,AVERAGE
,GOOD
)。我该怎么做?
答案 0 :(得分:52)
在enum
中创建一个静态方法,搜索values
(隐式方法/成员,不确切知道它是哪个)并返回相应的值。对于方法无法找到匹配值的情况,您应该创建一个特殊条目,例如UNKNOWN
,您可以返回。这样,您就不必返回null
,这总是一个坏主意。
public static EnumStatus getById(Long id) {
for(EnumStatus e : values()) {
if(e.id.equals(id)) return e;
}
return UNKNOWN;
}
顺便说一下 - 你的代码似乎错了。 GOOD
之后的括号似乎不属于那里。
答案 1 :(得分:11)
这可以使用静态地图和静态初始化程序来完成:
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。
答案 2 :(得分:3)
您按照以下方式开展此工作:
public static String fromId(long id) {
for (EnumStatus es : EnumStatus.values()) {
if (es.id.equals(id)) {
return es.getName();
}
}
throw new IllegalArgumentException();
}
答案 3 :(得分:1)
在Enum
中添加一个方法,然后通过传递ID来获取它。
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;
}
答案 4 :(得分:1)
public static EnumStatus getById(long id)
{
for (EnumStatus e : EnumStatus.values())
{
if (id == e.getId()) return e;
}
throw new IllegalArgumentException("oh no");
}
答案 5 :(得分:0)
迭代所有值并比较Id
for (EnumStatus enumStatus : EnumStatus.values()) {
if (..) {..}
}
答案 6 :(得分:0)
有时enum的序数与这种id有明确的关系,能够以一种巧妙的方式在这些方法中获得O(1)。在您的代码中,很明显
EnumStatus.X = 40 + 20 * ordinal
,
因此您可以利用static array that is generated under the hoods。
public static EnumStatus fromId(Long id) {
int index = (id - 40L) / 20L;
return values()[index];
}
答案 7 :(得分: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;
}
}
<强>辅助/的Util 强>
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;
}
}
答案 8 :(得分:0)
Nihal,您收到了很多答复,回答如何找到正确的枚举元素。 但是我觉得您还希望使用“通过”之类的元素名称,而不是“已通过” 。
请致电 .name()以获得“通过” 。
扩展Josua的答案:getById(40L).name();
和EnumStatus.PASSED.getName()以获取您的情况“已通过” 。
答案 9 :(得分:0)
此模式可以为您提供帮助:
public interface Identifiable<T extends Number> {
@Nonnull
T getId();
}
public final class GettableById<K extends Number, V extends Enum<V> & Identifiable<K>> {
@Nonnull
private final Map<K, V> idToValue;
public GettableById(@Nonnull V[] values) {
this.idToValue = Arrays.stream(values)
.collect(Collectors.toUnmodifiableMap(Identifiable::getId, v -> v));
}
@Nonnull
public V getById(@Nonnull K id) {
var value = idToValue.get(id);
if (value != null) {
return value;
}
throw new NullPointerException("Cannot get value by id: %s".formatted(id));
}
}
public enum DataType implements Identifiable<Short> {
ANNUAL((short) 1), QUARTERLY((short) 2);
private static final GettableById<Short, DataType> companion = new GettableById<>(values());
@Nonnull
private final Short id;
public static DataType getById(Short id) {
return companion.getById(id);
}
DataType(@Nonnull Short id) {
this.id = id;
}
@Nonnull
@Override
public Short getId() {
return id;
}
}
答案 10 :(得分: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();
}
或使用Stream API:
public static Optional<EnumStatus> fromId(Long id) {
return Stream.of(values())
.filter(e -> e.id.equals(id))
.findFirst();
}
有效Java第三版一书中的作者 Joshua Bloch 推荐了一种有效的解决方案,该解决方案也使用Optional
作为返回类型:
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));
}
Bloch使用Optional
的理由:
...请注意,
fromString
方法返回一个Optional<Operation>
。这个 允许方法指示传入的字符串不代表 有效的操作,它迫使客户面对这种可能性