您的代碼示例有點讓人誤解,因爲它返回的常數與序號相同,而不是具有相同屬性值的常量。爲了抽象搜索具有屬性值的常量,必須抽象屬性,例如
interface TypeWithIntProperty {
int getProperty();
}
enum Number implements TypeWithIntProperty {
ONE(1), TWO(2), THREE(3);
private final int value;
Number(int value) {
this.value=value;
}
public int getProperty() {
return value;
}
}
enum DayOfWeek implements TypeWithIntProperty {
Monday(1), Tuesday(2), Wednesday(3), Thrusday(4), Friday(5), Saturday(6), Sunday(7);
private final int value;
DayOfWeek(int value) {
this.value=value;
}
public int getProperty() {
return value;
}
}
public class Helper {
public static <E extends Enum<E>&TypeWithIntProperty>
E getEnumItem(Class<E> type, int value) {
for(E constant: type.getEnumConstants())
if(value == constant.getProperty())
return constant;
throw new IllegalArgumentException("no constant with "+value+" in "+type);
}
}
DayOfWeek day=Helper.getEnumItem(DayOfWeek.class, 7);
Number no=Helper.getEnumItem(Number.class, 2);
如果屬性有不同的類型,可以使接口通用:
interface TypeWithIntProperty<T> {
T getProperty();
}
enum Number implements TypeWithIntProperty<String> {
ONE, TWO, THREE;
public String getProperty() {
return name().toLowerCase();
}
}
enum DayOfWeek implements TypeWithIntProperty<Integer> {
Monday(1), Tuesday(2), Wednesday(3), Thrusday(4), Friday(5), Saturday(6), Sunday(7);
private final int value;
DayOfWeek(int value) {
this.value=value;
}
public Integer getProperty() {
return value;
}
}
public class Helper {
public static <E extends Enum<E>&TypeWithIntProperty<P>,P>
E getEnumItem(Class<E> type, P value) {
for(E constant: type.getEnumConstants())
if(value.equals(constant.getProperty()))
return constant;
throw new IllegalArgumentException("no constant with "+value+" in "+type);
}
}
DayOfWeek day=Helper.getEnumItem(DayOfWeek.class, 7);
Number no=Helper.getEnumItem(Number.class, "two");
一個更清潔,更詳細(下Java 6)的替代品是的財產抽象從類型具有屬性分開:
interface Property<T,V> {
V get(T owner);
}
enum Number {
ONE, TWO, THREE;
static final Property<Number,String> NAME=new Property<Number,String>() {
public String get(Number owner) { return owner.getName(); }
};
public String getName() {
return name().toLowerCase();
}
}
enum DayOfWeek {
Monday(1), Tuesday(2), Wednesday(3), Thrusday(4), Friday(5), Saturday(6), Sunday(7);
static final Property<DayOfWeek,Integer> INDEX=new Property<DayOfWeek,Integer>() {
public Integer get(DayOfWeek owner) { return owner.getIndex(); }
};
private final int index;
DayOfWeek(int value) {
this.index=value;
}
public int getIndex() {
return index;
}
}
public class Helper {
public static <E extends Enum<E>,P>
E getEnumItem(Class<E> type, Property<E,P> prop, P value) {
for(E constant: type.getEnumConstants())
if(value.equals(prop.get(constant)))
return constant;
throw new IllegalArgumentException("no constant with "+value+" in "+type);
}
}
DayOfWeek day=Helper.getEnumItem(DayOfWeek.class, DayOfWeek.INDEX, 7);
Number no=Helper.getEnumItem(Number.class, Number.NAME, "two");
這一點在Java 8簡單得多,你可以實現Property
爲DayOfWeek::getIndex
或Number::getName
,而不是內部類,對另一方面,由於我們沒有受益於Java 6中的單一方法接口,因此我們可以通過使用可以提供功能的抽象基類將其變爲優勢,現在甚至可以使用緩存:
abstract class Property<T extends Enum<T>,V> {
final Class<T> type;
final Map<V,T> map;
Property(Class<T> type) {
this.type=type;
map=new HashMap<V, T>();
for(T constant: type.getEnumConstants())
{
T old = map.put(get(constant), constant);
if(old!=null)
throw new IllegalStateException("values not unique: "+get(constant));
}
}
abstract V get(T owner);
T getConstant(V value) {
T constant=map.get(value);
if(constant==null)
throw new IllegalArgumentException("no constant "+value+" in "+type);
return constant;
}
}
enum Number {
ONE, TWO, THREE;
static final Property<Number,String> NAME=new Property<Number,String>(Number.class) {
public String get(Number owner) { return owner.getName(); }
};
public String getName() {
return name().toLowerCase();
}
}
enum DayOfWeek {
Monday(1), Tuesday(2), Wednesday(3), Thrusday(4), Friday(5), Saturday(6), Sunday(7);
static final Property<DayOfWeek,Integer> INDEX
=new Property<DayOfWeek,Integer>(DayOfWeek.class) {
public Integer get(DayOfWeek owner) { return owner.getIndex(); }
};
private final int index;
DayOfWeek(int value) {
this.index=value;
}
public int getIndex() {
return index;
}
}
DayOfWeek day=DayOfWeek.INDEX.getConstant(7);
Number no=Number.NAME.getConstant("two");
枚舉不能擴展類,也不另一種枚舉,所以要麼你寫的方法,每進行一次(理想情況下使日e enum實現一個定義該方法的接口),或者將代碼寫入枚舉之外。 – Aaron