如何使用Java中相同的键将枚举映射到枚举。 例如。
public enum FirstEnum {
A, B
}
public enum ScndEnum {
A, B, C
}
我找不到好的解决方法
答案 0 :(得分:3)
您不能直接从一种枚举类型映射到另一种枚举类型,但是可以使用name()
的值并使用valueOf()
进行映射。这两种方法都随所有枚举类一起提供:
ScndEnum aToA = ScndEnum.valueOf(FirstEnum.A.name());
如果要使它通用:
private static <E extends Enum<E>, F extends Enum<F>>
F mapEnum(E enum1, Class<F> enum2Class) {
return Enum.valueOf(enum2Class, enum1.name());
}
您可以使用类似的方式拨打电话
ScndEnum b = mapEnum(FirstEnum.B, ScndEnum.class)
答案 1 :(得分:2)
考虑到Java中的枚举定义,在枚举之间共享对象实际上没有任何意义。
也许为您提供的解决方案是一系列枚举,例如Map
(key-value pairs),其中键类型是一个枚举类,而值类型是另一个枚举类。
Map< Animal , Food > feeding =
Map.of
(
DOG , MEAT ,
CAT , MEAT ,
BIRD , SEED ,
BAT , FRUIT
)
;
Java中的枚举是一个类,其实例在编译时命名,在运行时自动实例化,并且无法重新分配。参见tutorial by Oracle。
示例:
enum Animal { DOG , CAT , BIRD , BAT ; }
enum Flavor { VANILLA , CHOCOLATE , LAVENDER , LEMON ; }
枚举中的每个名称都将分配一个对象,该对象是该枚举类的一个实例。在上面的示例中,DOG
常量保存一个Animal
对象,而LEMON
常量保存一个Flavor
对象。
当您拥有在编译时已知但在运行时未更改的特定实例实例时,在Java中使用枚举是有意义的。这意味着您不能在上面的示例中调用new Animal()
。首次加载该类时,会自动实例化四个新的Animal
对象并将其分配给每个变量名称。枚举类加载后,无法再实例化或丢弃Animal
对象。
因此,鉴于枚举的定义,您的问题实际上没有任何意义。一个枚举的对象不与另一个枚举共享。
也许您正在寻找的是枚举对象的集合。
Set
例如,在这里我们使用Set
的实现,该实现针对保存枚举对象EnumSet
进行了高度优化。
Set< Animal > furryPets = EnumSet.of( DOG , CAT ) ;
Set< Animal > flyingAnimals = EnumSet.of( BIRD , BAT ) ;
Set< Animal > featheredFlyingAnimals = flyingAnimals.clone().remove( BAT ) ;
Map
您提到要双向映射。因此,也许您想要的是Map
来跟踪一个枚举作为键,而另一个枚举作为值。当您的键是枚举时,EnumMap
类得到了高度优化。
作为示例,让我们添加另一个枚举。
enum Food { MEAT , SEED , FRUIT ; }
根据动物的食物类型对其进行映射。
Map< Animal , Food > feeding = new EnumMap<>( Animal.class ) ;
feeding.put( DOG , MEAT ) ;
feeding.put( CAT , MEAT ) ;
feeding.put( BIRD , SEED ) ;
feeding.put( BAT , FRUIT ) ;
获取要喂给蝙蝠的食物类型。
Food foodForBats = feeding.get( BAT ) ;
Java中的枚举是一种特殊的类,但仍然是一个类。因此,枚举可以像常规Java类一样具有成员字段,构造函数和访问器方法。
因此,我们可以通过使用成员字段,构造函数和访问器方法将Animal
与其Food
关联起来。
enum Animal
{
DOG( Food.MEAT ) ,
CAT( Food.MEAT ) ,
BIRD( Food.SEED ) ,
BAT( Food.FRUIT ) ;
// Member fields.
private Food food ;
// Constructor.
private Animal( Food foodArg )
{
this.food = foodArg ;
}
// Accessor "getter" method.
public Food getFood() { return this.food ; }
}
如上所述,当Animal
类加载时,其构造函数被调用四次,每个命名常量一次。指定的Food
对象会自动代表您传递给该构造函数。您可以认为该行DOG( Food.MEAT ) ,
是public static final Animal DOG = new Animal( Food.MEAT) ;
的缩写。
用法。
Food foodForBats = Animal.BAT.getFood() ;