我正在尝试实现某种自定义枚举 - 一个类似于枚举的类,并将实现其方法。我需要传递一组值使它们成为最终值并执行像ordinal,valueOf,values这样的操作。 这是我的实施:
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);
}
}
当我创建一个类的实例时,我得到了StackOverflow错误:
CustomEnum customEnum = new CustomEnum("white");
我理解为什么会发生这种错误,但我不知道我怎么能实现这样的类。问题是我如何改变我的实现,但仍然保持所有的方法和数据结构(arraylists,map)工作? 我会非常感谢你的帮助。
答案 0 :(得分:2)
另一个解决方案是第二个构造函数:
public CustomEnum(String s) {
valuesMap.put(s, this);
valuesList.add(this);
}
你拥有的一个构造函数无休止地呼唤着自己。
答案 1 :(得分:1)
你的问题是写的构造函数实际上是一个工厂。将该功能移出构造函数,您就会感觉良好。
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");
}
答案 2 :(得分:1)
你有设计问题
公共构造函数值为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;
}
第一种方法:直接在类中提供常量值(如枚举一样)。
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);
}
}