93

以前,我将 LegNo 枚举简单地定义为:

NO_LEG, LEG_ONE, LEG_TWO

通过调用return LegNo.values()[i];,我能够获得与每个枚举关联的值。

但是现在我决定我希望LegNo枚举NO_LEG是 int -1 而不是 0 所以我决定使用私有构造函数来初始化并设置它的 int 值

NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

private LegNo(final int leg) { legNo = leg; }

现在唯一的事情是,因为我是这样做的,所以该values()方法不适用于NO_LEG枚举。如何获取与 int 关联的枚举?除了使用 case switch 语句或 if-elseif-elseif 之外,还有其他有效的方法吗?

我可以看到很多与从枚举中获取 int 值有关的 SO 问题,但我追求的是相反的。

4

8 回答 8

154

编辑 2018 年 8 月

今天我将按如下方式实现

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int value;

    LegNo(int value) {
        this.value = value;
    }

    public static Optional<LegNo> valueOf(int value) {
        return Arrays.stream(values())
            .filter(legNo -> legNo.value == value)
            .findFirst();
    }
}

您必须在枚举中维护一个映射。

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private int legNo;

    private static Map<Integer, LegNo> map = new HashMap<Integer, LegNo>();

    static {
        for (LegNo legEnum : LegNo.values()) {
            map.put(legEnum.legNo, legEnum);
        }
    }

    private LegNo(final int leg) { legNo = leg; }

    public static LegNo valueOf(int legNo) {
        return map.get(legNo);
    }
}

静态块只会被调用一次,所以这里实际上没有性能问题。

编辑:将该方法重命名为,valueOf因为它与其他 Java 类更加内联。

于 2012-06-15T09:15:18.633 回答
24

您还可以在枚举中包含一个静态方法,该方法遍历所有成员并返回正确的成员。

public enum LegNo {
   NO_LEG(-1),
   LEG_ONE(1),
   LEG_TWO(2);

   private int legIndex;

   private LegNo(int legIndex) { this.legIndex = legIndex; }

   public static LegNo getLeg(int legIndex) {
      for (LegNo l : LegNo.values()) {
          if (l.legIndex == legIndex) return l;
      }
      throw new IllegalArgumentException("Leg not found. Amputated?");
   }
}

现在,如果您想通过整数获取 Enum 值,您只需使用:

int myLegIndex = 1; //expected : LEG_ONE
LegNo myLeg = LegNo.getLeg(myLegIndex);
于 2012-06-15T10:02:45.477 回答
17

adarshr 的答案适用于 Java 8:

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toMap;

import java.util.Map;

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int legNo;

    private final static Map<Integer, LegNo> map =
            stream(LegNo.values()).collect(toMap(leg -> leg.legNo, leg -> leg));

    private LegNo(final int leg) {
        legNo = leg;
    }

    public static LegNo valueOf(int legNo) {
        return map.get(legNo);
    }
}
于 2015-02-20T22:03:51.473 回答
12

您还可以通过在枚举 LegNo 上调用 values() 方法来访问与给定整数值对应的枚举值。它返回 LegNo 枚举的字段: LegNo.values()[0]; //returns LEG_NO LegNo.values()[1]; //returns LEG_ONE LegNo.values()[2]; //returns LEG_TWO

不正是他正在寻找的东西,但非常接近并且确实非常简单。(虽然主题已经死了,但它可能对其他人有用。)

于 2016-03-18T15:36:04.880 回答
6

具有默认值的 Java 8 方式:

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int legNo;

    LegNo(int legNo) {
        this.legNo = legNo;
    }

    public static LegNo find(int legNo, Supplier<? extends LegNo> byDef) {
        return Arrays.asList(LegNo.values()).stream()
                .filter(e -> e.legNo == legNo).findFirst().orElseGet(byDef);
    }
}

打电话:

LegNo res = LegNo.find(0, () -> LegNo.NO_LEG);

或有例外:

LegNo res = LegNo.find(0, () -> {
    throw new RuntimeException("No found");
});
于 2017-03-21T11:43:36.963 回答
2
public enum LegNo {

  NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

  private final int code;

  LegNo(int code) {
    this.code = code;
    ReverseStorage.reverseMap.put(code, this);
  }

  public static Optional<LegNo> getByCode(int code) {
    return Optional.ofNullable(ReverseStorage.reverseMap.get(code));
  }

  private static final class ReverseStorage {
    private static final Map<Integer, LegNo> reverseMap = new LinkedHashMap<>();
  }
}
于 2020-03-10T11:40:12.233 回答
1

由于您的枚举仅包含 3 个元素,因此最快的方法是使用一系列if else,就像您建议的那样。

编辑: adarshr 提供的答案更适合一般情况,其中有很多枚举值,但我认为这对您的问题来说是过度的。

于 2012-06-15T09:21:31.587 回答
1
public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private int legNo;

    private LegNo(int leg) { legNo = leg; }

    public static LegNo valueOf(int legNo) {
        for (LegNo leg : LegNo.values()) {
            if (leg.legNo == legNo) return leg;
        }   
    }
}

assert LegNo.valueOf(2) == LegNo.LEG_TWO
assert LegNo.valueOf(3) == null
于 2013-11-16T04:07:53.100 回答