我写了一个枚举类,我想要按类型获取属性并获取type by属性,但似乎不可能.
public enum AreaCode {
area1(7927),
area2(7928),
area3(7929);
private final int ac;
AreaCode(int ac) {
this.ac = ac;
}
int areaCode(){
return ac;
}
AreaCode area(int n) {
switch (n) {
case 7927: return AreaCode.area1;
case 7928: return AreaCode.area2;
case 7929: return AreaCode.area3;
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码不会编译.如何area(int n)上班?
Joa*_*uer 31
除了其他海报所指出的问题外,我会重写方法以避免重复信息(保持干燥!):
public static AreaCode area(int n) {
for (AreaCode c : values()) {
if (c.ac == n) {
return c;
}
}
// either throw the IAE or return null, your choice.
throw new IllegalArgumentException(String.valueOf(n));
}
Run Code Online (Sandbox Code Playgroud)
Mr.*_*irl 15
正如他们所说,有一种方法可以给猫皮肤.首先,枚举值应该是大写的(由下划线分隔的单词),因为它们是常量值,并且应该通过Java命名约定来对待它们.至少,它们应该以大写字母开头,因为所有类名都应该.
public enum AreaCode {
AREA_1(7927),
AREA_2(7928),
AREA_3(7929);
private int areaCode;
private AreaCode(int areaCode) {
this.areaCode = areaCode;
}
public int getAreaCode() {
return areaCode;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,有三种方法可以通过实例变量检索枚举.switch语句,具有相等条件的循环和查找映射.最后一个场景可能会为您的程序添加更多内存,但如果您需要快速查找大量枚举,这将有助于您以恒定的速率O(1)时间执行此操作.
下面的每个枚举类都是相同的,但每个类都在内部做了不同的事情.通过将以下main()方法添加到这些类中的任何一个,您将获得相同的结果.
public static void main(String[] args) {
System.out.println(retrieveByAreaCode(7928));
}
Run Code Online (Sandbox Code Playgroud)
上面的例子将打印:
AreaCode[name="AREA_2", value="7928"]
Run Code Online (Sandbox Code Playgroud)
查找是O(1)(常数时间),但您需要对每个案例进行硬编码(不是非常动态).
public enum AreaCode {
AREA_1(7927),
AREA_2(7928),
AREA_3(7929);
private int areaCode;
private AreaCode(int areaCode) {
this.areaCode = areaCode;
}
public int getAreaCode() {
return areaCode;
}
public static AreaCode retrieveByAreaCode(int n) {
switch (n) {
case 7927:
return AreaCode.AREA_1;
case 7928:
return AreaCode.AREA_2;
case 7929:
return AreaCode.AREA_3;
default:
return null;
}
}
@Override
public String toString() {
return String.format("%s[name=\"%s\", value=\"%d\"]",
this.getClass().getName(), this.name(), this.getAreaCode());
}
}
Run Code Online (Sandbox Code Playgroud)
查找是O(n)(线性时间),因此您需要遍历每个值,直到找到匹配项,但您确实需要对每个案例进行硬编码(动态).
public enum AreaCode {
AREA_1(7927),
AREA_2(7928),
AREA_3(7929);
private int areaCode;
private AreaCode(int areaCode) {
this.areaCode = areaCode;
}
public int getAreaCode() {
return areaCode;
}
public static AreaCode retrieveByAreaCode(int n) {
for (AreaCode areaCode : AreaCode.values()) {
if (areaCode.getAreaCode() == n) {
return areaCode;
}
}
return null;
}
@Override
public String toString() {
return String.format("%s[name=\"%s\", value=\"%d\"]",
this.getClass().getName(), this.name(), this.getAreaCode());
}
}
Run Code Online (Sandbox Code Playgroud)
查找是O(1)(常量时间),您不需要对每个值进行硬编码(动态),但您需要存储占用内存的映射.
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public enum AreaCode {
AREA_1(7927),
AREA_2(7928),
AREA_3(7929);
private static final Map<Integer, AreaCode> LOOKUP_MAP;
private int areaCode;
static {
LOOKUP_MAP = new HashMap<Integer, AreaCode>();
for (AreaCode areaCode : AreaCode.values()) {
LOOKUP_MAP.put(areaCode.getAreaCode(), areaCode);
}
LOOKUP_MAP = Collections.unmodifiableMap(LOOKUP_MAP);
}
private AreaCode(int areaCode) {
this.areaCode = areaCode;
}
public int getAreaCode() {
return areaCode;
}
public static AreaCode retrieveByAreaCode(int n) {
return LOOKUP_MAP.get(n);
}
@Override
public String toString() {
return String.format("%s[name=\"%s\", value=\"%d\"]",
this.getClass().getName(), this.name(), this.getAreaCode());
}
}
Run Code Online (Sandbox Code Playgroud)
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class EnumUtils {
public static interface EnumProperty<T extends Enum<T>, U> {
U getValue(T type);
}
public static <T extends Enum<T>, U> Map<U, T> createLookup(Class<T> enumTypeClass, EnumProperty<T, U> prop) {
Map<U, T> lookup = new HashMap<U, T>();
for (T type : enumTypeClass.getEnumConstants()) {
lookup.put(prop.getValue(type), type);
}
return Collections.unmodifiableMap(lookup);
}
}
Run Code Online (Sandbox Code Playgroud)
import java.util.Map;
public enum AreaCode {
AREA_1(7927),
AREA_2(7928),
AREA_3(7929);
private static final EnumUtils.EnumProperty<AreaCode, Integer> ENUM_PROP;
private static final Map<Integer, AreaCode> LOOKUP_MAP;
static {
ENUM_PROP = new EnumUtils.EnumProperty<AreaCode, Integer>() {
@Override
public Integer getValue(AreaCode code) {
return code.getAreaCode();
}
};
LOOKUP_MAP = EnumUtils.createLookup(AreaCode.class, ENUM_PROP);
}
private int areaCode;
private AreaCode(int areaCode) {
this.areaCode = areaCode;
}
public int getAreaCode() {
return areaCode;
}
public static AreaCode retrieveByAreaCode(int n) {
return LOOKUP_MAP.get(n);
}
@Override
public String toString() {
return String.format("%s[name=\"%s\", value=\"%d\"]",
this.getClass().getName(), this.name(), this.getAreaCode());
}
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*rdt 12
您需要做的就是添加一个默认大小写,以便该方法始终返回一些异常或抛出异常:
AreaCode area(int n){
switch (n) {
case 7927: return AreaCode.area1;
case 7928: return AreaCode.area2;
case 7929: return AreaCode.area3;
default: return null;
}
}
Run Code Online (Sandbox Code Playgroud)
或者更好
AreaCode area(int n){
switch (n) {
case 7927: return AreaCode.area1;
case 7928: return AreaCode.area2;
case 7929: return AreaCode.area3;
default: throw new IllegalArgumentException(String.valueOf(n));
}
}
Run Code Online (Sandbox Code Playgroud)