自定义枚举实现 Java
Custom enum implementation Java
我正在尝试实现某种自定义枚举 - class 其行为类似于枚举并会实现其方法。我需要传递一组值,使它们成为最终值,并执行诸如序数、valueOf、值之类的操作。
这是我的实现:
public class CustomEnum {
private static final Map<String,CustomEnum> valuesMap = new LinkedHashMap<>();
private static final List<CustomEnum> valuesList = new ArrayList<>();
public CustomEnum(String...data) {
for(String s : data){
final CustomEnum customEnum = new CustomEnum(s);
valuesMap.put(s, customEnum);
valuesList.add(customEnum);
}
}
public CustomEnum valueOf(final String data){
if (data == null) {
throw new NullPointerException();
}
final CustomEnum customEnum = valuesMap.get(data);
if(customEnum == null){
throw new IllegalArgumentException();
}
return customEnum;
}
public CustomEnum[] values(){
return valuesList.toArray(new CustomEnum[valuesList.size()]);
}
public int ordinal(){
return valuesList.indexOf(this);
}
}
当我创建一个 class 的实例时,我收到 Whosebug 错误:
CustomEnum customEnum = new CustomEnum("white");
我明白为什么会出现这个错误,但我不知道我还能如何实现这样的 class。问题是我如何改变我的实现,但仍然保持所有方法和数据结构(数组列表、映射)的工作?
如果能提供一些帮助,我将不胜感激。
你的问题是写的构造函数实际上是一个工厂。将该功能从构造函数中移出就可以了。
public static class CustomEnum {
private static final Map<String,CustomEnum> valuesMap = new LinkedHashMap<>();
private static final List<CustomEnum> valuesList = new ArrayList<>();
private final String data;
public CustomEnum(String data) {
this.data = data;
}
public CustomEnum valueOf(final String data){
if (data == null) {
throw new NullPointerException();
}
final CustomEnum customEnum = valuesMap.get(data);
if(customEnum == null){
throw new IllegalArgumentException();
}
return customEnum;
}
public CustomEnum[] values(){
return valuesList.toArray(new CustomEnum[valuesList.size()]);
}
public int ordinal(){
return valuesList.indexOf(this);
}
public static void create(String...data) {
for(String s : data){
final CustomEnum customEnum = new CustomEnum(s);
valuesMap.put(s, customEnum);
valuesList.add(customEnum);
}
}
}
public void test(String[] args) {
CustomEnum.create("white");
}
另一个解决方案是第二个构造函数:
public CustomEnum(String s) {
valuesMap.put(s, this);
valuesList.add(this);
}
您拥有的一个构造函数正在无休止地调用自身。
你的设计有问题。
public 构造函数值 static
字段。
所以每次创建 CustomEnum
时,它们的内容都会被覆盖。
所以这些集合没有不变的元素:
private static final Map<String,CustomEnum> valuesMap = new LinkedHashMap<>();
private static final List<CustomEnum> valuesList = new ArrayList<>();
要解决您的问题,您有两种方法。
在任何情况下,您都必须使构造函数 private
允许不变并将创建所有 CustomEnum
实例的全局构造与每个实例的创建分离:
private CustomEnum(String data) {
this.data = data;
}
第一种方式:直接在 class 中提供常量值(就像枚举一样)。
static{
String[] data = {....}; // constant values
for(String s : data){
final CustomEnum customEnum = new CustomEnum(s);
valuesMap.put(s, customEnum);
valuesList.add(customEnum);
}
}
第二种方式:使字段和方法不是 static
并允许创建多个具有不同值的 CustomEnum
。
private final Map<String,CustomEnum> valuesMap = new LinkedHashMap<>();
private final List<CustomEnum> valuesList = new ArrayList<>();
public static void of(String... data) {
for(String d : data){
final CustomEnum customEnum = new CustomEnum(d);
valuesMap.put(d, customEnum);
valuesList.add(customEnum);
}
}
我正在尝试实现某种自定义枚举 - class 其行为类似于枚举并会实现其方法。我需要传递一组值,使它们成为最终值,并执行诸如序数、valueOf、值之类的操作。 这是我的实现:
public class CustomEnum {
private static final Map<String,CustomEnum> valuesMap = new LinkedHashMap<>();
private static final List<CustomEnum> valuesList = new ArrayList<>();
public CustomEnum(String...data) {
for(String s : data){
final CustomEnum customEnum = new CustomEnum(s);
valuesMap.put(s, customEnum);
valuesList.add(customEnum);
}
}
public CustomEnum valueOf(final String data){
if (data == null) {
throw new NullPointerException();
}
final CustomEnum customEnum = valuesMap.get(data);
if(customEnum == null){
throw new IllegalArgumentException();
}
return customEnum;
}
public CustomEnum[] values(){
return valuesList.toArray(new CustomEnum[valuesList.size()]);
}
public int ordinal(){
return valuesList.indexOf(this);
}
}
当我创建一个 class 的实例时,我收到 Whosebug 错误:
CustomEnum customEnum = new CustomEnum("white");
我明白为什么会出现这个错误,但我不知道我还能如何实现这样的 class。问题是我如何改变我的实现,但仍然保持所有方法和数据结构(数组列表、映射)的工作? 如果能提供一些帮助,我将不胜感激。
你的问题是写的构造函数实际上是一个工厂。将该功能从构造函数中移出就可以了。
public static class CustomEnum {
private static final Map<String,CustomEnum> valuesMap = new LinkedHashMap<>();
private static final List<CustomEnum> valuesList = new ArrayList<>();
private final String data;
public CustomEnum(String data) {
this.data = data;
}
public CustomEnum valueOf(final String data){
if (data == null) {
throw new NullPointerException();
}
final CustomEnum customEnum = valuesMap.get(data);
if(customEnum == null){
throw new IllegalArgumentException();
}
return customEnum;
}
public CustomEnum[] values(){
return valuesList.toArray(new CustomEnum[valuesList.size()]);
}
public int ordinal(){
return valuesList.indexOf(this);
}
public static void create(String...data) {
for(String s : data){
final CustomEnum customEnum = new CustomEnum(s);
valuesMap.put(s, customEnum);
valuesList.add(customEnum);
}
}
}
public void test(String[] args) {
CustomEnum.create("white");
}
另一个解决方案是第二个构造函数:
public CustomEnum(String s) {
valuesMap.put(s, this);
valuesList.add(this);
}
您拥有的一个构造函数正在无休止地调用自身。
你的设计有问题。
public 构造函数值 static
字段。
所以每次创建 CustomEnum
时,它们的内容都会被覆盖。
所以这些集合没有不变的元素:
private static final Map<String,CustomEnum> valuesMap = new LinkedHashMap<>();
private static final List<CustomEnum> valuesList = new ArrayList<>();
要解决您的问题,您有两种方法。
在任何情况下,您都必须使构造函数 private
允许不变并将创建所有 CustomEnum
实例的全局构造与每个实例的创建分离:
private CustomEnum(String data) {
this.data = data;
}
第一种方式:直接在 class 中提供常量值(就像枚举一样)。
static{
String[] data = {....}; // constant values
for(String s : data){
final CustomEnum customEnum = new CustomEnum(s);
valuesMap.put(s, customEnum);
valuesList.add(customEnum);
}
}
第二种方式:使字段和方法不是 static
并允许创建多个具有不同值的 CustomEnum
。
private final Map<String,CustomEnum> valuesMap = new LinkedHashMap<>();
private final List<CustomEnum> valuesList = new ArrayList<>();
public static void of(String... data) {
for(String d : data){
final CustomEnum customEnum = new CustomEnum(d);
valuesMap.put(d, customEnum);
valuesList.add(customEnum);
}
}