我有两个枚举类,一个是外部的,另一个是内部的。
public enum ExternalEnum
{
EXTERNAL_CAR, EXTERNAL_VAN, EXTERNAL_BUS
}
public enum InternalEnum
{
CAR, VAN, BUS
}
我需要将内部映射到外部,外部映射到内部。所以我做了以下工作,
public class EnumMapper
{
public ExternalEnum toExternal(InternalEnum internalEnum)
{
switch (internalEnum)
{
case BUS:
return ExternalEnum.EXTERNAL_BUS;
case CAR:
return ExternalEnum.EXTERNAL_CAR;
case VAN:
return ExternalEnum.EXTERNAL_VAN;
}
return null;
}
public InternalEnum toInternal(ExternalEnum externalEnum)
{
switch (externalEnum)
{
case EXTERNAL_BUS:
return InternalEnum.BUS;
case EXTERNAL_CAR:
return InternalEnum.CAR;
case EXTERNAL_VAN:
return InternalEnum.VAN;
}
return null;
}
}
因此,相同类型的映射在两种方法中重复。难道没有一种很好的方法可以用更少的代码来实现这一点吗?
我能够通过使用BiMap以更少的代码量实现这一点。
import com.google.common.collect.EnumBiMap;
public class EnumBiMapMapper
{
private EnumBiMap<InternalEnum, ExternalEnum> enumEnumBiMap = EnumBiMap.create(InternalEnum.class, ExternalEnum.class);
public EnumBiMapMapper()
{
enumEnumBiMap.put(InternalEnum.BUS, ExternalEnum.EXTERNAL_BUS);
enumEnumBiMap.put(InternalEnum.CAR, ExternalEnum.EXTERNAL_CAR);
enumEnumBiMap.put(InternalEnum.VAN, ExternalEnum.EXTERNAL_VAN);
}
public ExternalEnum toExternal(InternalEnum internalEnum)
{
return enumEnumBiMap.get(internalEnum);
}
public InternalEnum toInternal(ExternalEnum externalEnum)
{
return enumEnumBiMap.inverse().get(externalEnum);
}
}
Basil Bourque的答案很好,但我不喜欢使用序数()
,因为您可以轻松地旋转枚举
常量并且业务逻辑会被破坏。
您做得几乎正确,只需记住,常量是一个普通的旧java实例,可以通过其他功能进行扩展。因此,最好将所有映射器逻辑隐藏在枚举中。
public enum ExternalEnum {
EXTERNAL_CAR,
EXTERNAL_VAN,
EXTERNAL_BUS
}
public enum InternalEnum {
CAR(ExternalEnum.EXTERNAL_CAR),
VAN(ExternalEnum.EXTERNAL_VAN),
BUS(ExternalEnum.EXTERNAL_BUS);
private final ExternalEnum externalEnum;
InternalEnum(ExternalEnum externalEnum) {
this.externalEnum = externalEnum;
}
public ExternalEnum toExternal() {
return externalEnum;
}
public static Optional<InternalEnum> parseExternal(ExternalEnum externalEnum) {
for (InternalEnum internalEnum : values())
if (internalEnum.externalEnum == externalEnum)
return Optional.of(internalEnum);
return Optional.empty();
}
}
演示
ExternalEnum externalEnum = ExternalEnum.EXTERNAL_CAR;
Optional<InternalEnum> optInternalEnum = InternalEnum.parseExternal(externalEnum);
System.out.println(externalEnum);
System.out.println(optInternalEnum.orElse(null));
System.out.println(optInternalEnum.map(InternalEnum::toExternal).orElse(null));
另一种方法是只使用映射器
public final class EnumMapper {
private final Map<ExternalEnum, InternalEnum> MAP_EXT_INT = Map.of(
ExternalEnum.EXTERNAL_CAR, InternalEnum.CAR,
ExternalEnum.EXTERNAL_VAN, InternalEnum.VAN,
ExternalEnum.EXTERNAL_BUS, InternalEnum.BUS);
private final Map<InternalEnum, ExternalEnum> MAP_INT_EXT = Map.of(
InternalEnum.CAR, ExternalEnum.EXTERNAL_CAR,
InternalEnum.VAN, ExternalEnum.EXTERNAL_VAN,
InternalEnum.BUS, ExternalEnum.EXTERNAL_BUS);
public static ExternalEnum toExternal(InternalEnum internalEnum) {
return MAP_INT_EXT.get(internalEnum);
}
public InternalEnum toInternal(ExternalEnum externalEnum) {
return MAP_EXT_INT.get(externalEnum);
}
private EnumMapper() {}
}
public enum ExternalEnum {
EXTERNAL_CAR,
EXTERNAL_VAN,
EXTERNAL_BUS
}
public enum InternalEnum {
CAR,
VAN,
BUS;
}
InternalEnum.values()[ externalEnum.ordinal() ]
假设等效枚举对象以相同的顺序声明,我们可以通过访问从调用隐式public静态T[]value()
方法返回的所有枚举对象的数组来从另一个枚举对象中检索一个枚举对象(请参阅此问题)并通过从错误命名的Enum#顺序
方法中检索的从零开始的索引号进行访问。
例如,<代码>内部枚举。values()按声明顺序返回所有枚举对象的数组。然后,我们使用数组访问器来检索与另一个枚举中匹配的索引号相匹配的对象。
InternalEnum internalEnum = InternalEnum.values()[ externalEnum.ordinal() ] ;
反之亦然:
ExternalEnum externalEnum = ExternalEnum.values()[ internalEnum.ordinal() ] ;
这是示例用法。额外提示:在Java16中,我们可以在本地声明枚举——参见JEP 395:记录。
enum ExternalEnum { EXTERNAL_CAR, EXTERNAL_VAN, EXTERNAL_BUS }
enum InternalEnum { CAR, VAN, BUS }
System.out.println(
InternalEnum.values()[ ExternalEnum.EXTERNAL_VAN.ordinal() ]
);
System.out.println(
ExternalEnum.values()[ InternalEnum.VAN.ordinal() ]
);
厢式货车
EXTERNAL_VAN
我有一个实体,有一个枚举类型字段和一个具有相同枚举类型和字段名的DTO。 我使用modelMapper创建一个新对象,不需要额外的配置。 但在将dto映射到实体对象后,实体对象上的性别为空。 对象有性别,我已经检查了很多。 请帮我理解这个问题。
Spring 3.x、JPA 2.0、Hibernate 4.x、Postgresql 9.x. 使用希望映射到Postgresql枚举的枚举属性处理Hibernate映射类。 使用枚举列上的where子句进行查询会引发异常。 SQL: Hibernate xml查询: > 按而不是按枚举查询工作正常。 没有数据库交互的Java工作良好: 不是,与和相同,异常更改为: 在查看https://sta
问题内容: 假设我有这个枚举: 通过以下映射: 枚举被发送到数据库,,。我希望这些值改为存储为,或存储在varchar列中。 如何将枚举映射到varchar列? 问题答案: 将其添加为EnumType的参数: 这是因为等效于java.sql.Types.VARCHAR
问题内容: 我需要预先将未实现接口的枚举映射到现有数据库,该数据库使用将该枚举存储在与所有者类相同的表中。 在这种情况下应如何处理映射?持久化到数据库不会改变,因为实现该接口的所有枚举都将具有不同的值,但是我不确定应如何从数据库中检索对象(我是否需要自定义映射器,它将尝试实例化一个使用指定的enum类进行枚举吗?Hibernate本身是否支持此功能?)。 问题答案: 可以创建一个自定义(例如thi
问题内容: Hibernate提供的注释支持使用或的两种类型的映射。当我们使用映射时,它使用的“名称” 而不是Enum的表示形式。在数据库列仅包含一个字符的情况下,这是一个问题。例如,我有以下枚举: 当我坚持枚举使用,即hibernate尝试在数据库中存储的值是开放的。但是,我的数据库列仅包含一个字符,因此会引发异常。 克服这个问题的一个办法是改变枚举类型持有单个字符(如,代替,)。但是,这降低了
拥有Maapstruct映射接口和带有各种枚举的DTO。我有两个不同的枚举,它们的格式都是: 但它显然不知道要用参数字符串代码映射到的枚举。希望我能: 只做toEntity(fromDto)和toDto(fromStringCode,forDtoTypeAndFile) 只为每个类型添加代码,而不为每个源/目标添加代码