Java中的嵌套枚举?
我想为web应用程序中提供的各种ajax服务定义一些枚举,如:Java中的嵌套枚举?,java,enums,Java,Enums,我想为web应用程序中提供的各种ajax服务定义一些枚举,如: Enum Service { REGISTER, LOGIN, NEWS, FAQ } 但是,这些枚举中的每一个都有特定的状态,如失败、已加载等。因此,我希望能够使用REGISTER.Loaded、LOGIN.Loaded等在我的事件总线上触发事件。但是,每个状态枚举必须是唯一的。例如,Register.LOADED必须与FAQ.LOADED不同,依此类推 编辑:此外,我必须能够在同一个hashma
Enum Service
{
REGISTER,
LOGIN,
NEWS,
FAQ
}
但是,这些枚举中的每一个都有特定的状态,如失败、已加载等。因此,我希望能够使用REGISTER.Loaded
、LOGIN.Loaded
等在我的事件总线上触发事件。但是,每个状态枚举必须是唯一的。例如,Register.LOADED
必须与FAQ.LOADED
不同,依此类推
编辑:此外,我必须能够在同一个hashmap中存储所有状态,例如Register.LOADED
和Login.LOADED
必须存储在同一个hashmap中。父服务枚举,即LOGIN、REGISTER
等,也必须可以存储在相同的hashmap中
实现这一点的最佳方法是什么?只需将“外部”枚举转换为一个类,并用“内部”枚举填充它:
或者将其作为
public static
嵌套到handler类中,如果是这样的话。在OP的一些注释之后,我更新了我的代码。用法语法变得难看,在switch
块中可能无法很好地工作,但我相信这实现了OP的目标:
import java.util.*;
public class HelloWorld
{
public static void main(String []args)
{
// Different services are not equal
System.out.println(Service.REGISTER + "==" + Service.LOGIN + " :: " + Service.REGISTER.equals(Service.LOGIN));
// Same service is equal
System.out.println(Service.REGISTER + "==" + Service.REGISTER + " :: " + Service.REGISTER.equals(Service.REGISTER));
// Even after changing the state
Service tmp = Service.REGISTER;
Service.REGISTER.setState(Service.ServiceState.State.FAILED);
System.out.println(Service.REGISTER + "==" + tmp + " :: " + Service.REGISTER.equals(tmp));
Service.REGISTER.setState(Service.ServiceState.State.LOADED);
// Different service, same state is not equal
System.out.println(Service.REGISTER + "." + Service.REGISTER.state + "==" + Service.LOGIN + "." + Service.LOGIN.state + " :: " + Service.REGISTER.state.equals(Service.LOGIN.state));
// Same service, same state is equal (even when changing state around)
Service.ServiceState.State temp = Service.REGISTER.getState();
Service.REGISTER.setState(Service.ServiceState.State.LOADED);
System.out.println(Service.REGISTER + "." + Service.REGISTER.state + "==" + tmp + "." + temp + " :: " + temp.equals(Service.REGISTER.getState()));
// Same service, different state is not equal
Service.REGISTER.setState(Service.ServiceState.State.FAILED);
System.out.println(Service.REGISTER + "." + Service.REGISTER.state + "==" + tmp + "." + temp + " :: " + temp.equals(Service.REGISTER.getState()));
// Both service and state can be used as map keys
Map<Service, String> map = new HashMap<Service, String>();
Map<Service.ServiceState.State, String> map2 = new HashMap<Service.ServiceState.State, String>();
}
}
enum Service
{
REGISTER(),
LOGIN(),
NEWS(),
FAQ();
public ServiceState state;
Service()
{
this.state = new ServiceState();
}
public void setState(ServiceState.State s)
{
state.state = s;
}
public ServiceState.State getState() { return state.state; }
public static class ServiceState
{
public enum State
{
LOADED,
FAILED
}
public State state = State.LOADED;
public ServiceState(){}
public String toString() { return state.toString(); }
public int hashCode()
{
return state.hashCode();
}
public boolean equals(Object obj)
{
return state.equals(obj);
}
}
}
原始答复: 使用您想要的语法不太可能,但Java枚举基本上只是另一个名称的类。(事实上,一旦编译,它们就是扩展
java.lang.Enum
的类)
输出:
REGISTER==LOGIN :: false
REGISTER==REGISTER :: true
REGISTER==REGISTER :: true
REGISTER.LOADED==LOGIN.LOADED :: false
REGISTER.LOADED==REGISTER.LOADED :: true
REGISTER.FAILED==REGISTER.LOADED :: false
寄存器已加载
另一个选项是创建几个枚举。其中一个列出了服务:
enum Service {
REGISTER, LOGIN, NEWS, FAQ;
}
下一个列表列出了所有状态:
enum State { LOADED, FAILED }
现在,您可以拥有一个类,该类在构造函数中接受服务和状态,并重写equals()和hashCode()以区分它们:
new ServiceState(REGISTER, LOADED)
或者创建另一个列出有效组合的枚举:
enum ServiceState {
REGISTER_LOADED(REGISTER, LOADED), ...
}
但是这个枚举将非常大,要键入的数量将很快变得非常大(如果将一个值添加到其他枚举,则需要将N个枚举添加到ServiceState
)一个解决方案是
enum Service {
REGISTER, LOGIN, NEWS, FAQ;
public final class State {
final ServiceState state;
private State(ServiceState st) {
state=st;
}
@Override
public String toString() {
return Service.this+"."+state;
}
}
final EnumMap<ServiceState, State> map=new EnumMap<>(ServiceState.class);
Service() {
for(ServiceState s:ServiceState.values()) map.put(s,new State(s));
}
public State state(ServiceState s) { return map.get(s); }
}
enum ServiceState { LOADED, FAILED }
另一种选择是:
enum Service {
REGISTER, LOGIN, NEWS, FAQ;
public final class State {
final ServiceState state;
private State(ServiceState st) {
state=st;
}
@Override
public String toString() {
return Service.this+"."+state;
}
}
public final State LOADED=new State(ServiceState.LOADED);
public final State FAILED=new State(ServiceState.FAILED);
}
enum ServiceState { LOADED, FAILED }
这需要在更改可能的ServiceState
s时手动更新字段,但在使用这些字段时,它的语法更具吸引力:
Service.State ss=Service.LOGIN.LOADED;
您还可以将服务状态
枚举
替换为字符串
s“已加载”
,“失败”
等。因此,您不需要保持枚举
与服务
中的字段同步
请注意,这两种解决方案都依赖于这样一个事实,即
Service.State
的构造函数是private
,因此只有在enum
中创建的规范实例才存在。因此,您不需要覆盖equals
或hashCode
。如果您决定将类序列化
,还应添加一个readResolve
方法,该方法返回反序列化实例的规范表示。虽然有一些很好的答案,可能适用于其他情况,我决定采用以下解决方案,因为它最适合我的情况:
public enum Service
{
LOGIN,
REGISTER,
NEWS;
private final long LOADED, FAILED;
private RequestType()
{
LOADED = strToAscii(this.name() + "_LOADED" );
FAILED = strToAscii(this.name() + "_FAILED" );
}
public static long strToAscii(String str)
{
StringBuilder sb = new StringBuilder();
for (char c: str.toCharArray() )
{
sb.append( (int) c );
}
return Long.parseLong( sb.toString() );
}
}
这对我来说效果很好,因为我现在可以按我最初想要的那样执行
RequestType.LOGIN.LOADED==RequestType.REGISTER.LOADED
。如果有人有任何改进建议,请随时提出。这只有一个问题,我无法将Login.LOADED
与Register.LOADED
进行比较。我需要所有枚举的状态都是相同的类型,这样我就可以将它们都存储在同一个hashmap中。@ClickUpvote:你错了。使用这种设计,所有枚举的状态都是相同的。@Aarondigula如果我想比较Register.LOADED
和Login.LOADED
,我会得到不同的值吗?@ClickUpvote,试试看System.out.println(Service.REGISTER.state==Service.LOGIN.state)
生成true
(假设您没有更改任何一个上的state
的值)。@BrianS那么这并不能解决我的问题,我需要每个服务类型的状态都是唯一的,否则,的所有侦听器都要注册.LOADED,Login.LOADED,常见问题解答。任何服务的状态设置为LOADED
时,都会触发LOADED
等。如果这样做,我是否能够将注册、登录
等存储在同一哈希映射中?在同一个hashmap中存储Register.LOADED
和Login.LOADED
怎么样?如果没有其他解决方案,ServiceState
类而不是枚举,我宁愿在每个实例化为this.name()+“_LOADED”
的服务上都有公共字符串?
enum Service {
REGISTER, LOGIN, NEWS, FAQ;
public final class State {
final ServiceState state;
private State(ServiceState st) {
state=st;
}
@Override
public String toString() {
return Service.this+"."+state;
}
}
public final State LOADED=new State(ServiceState.LOADED);
public final State FAILED=new State(ServiceState.FAILED);
}
enum ServiceState { LOADED, FAILED }
Service.State ss=Service.LOGIN.LOADED;
public enum Service
{
LOGIN,
REGISTER,
NEWS;
private final long LOADED, FAILED;
private RequestType()
{
LOADED = strToAscii(this.name() + "_LOADED" );
FAILED = strToAscii(this.name() + "_FAILED" );
}
public static long strToAscii(String str)
{
StringBuilder sb = new StringBuilder();
for (char c: str.toCharArray() )
{
sb.append( (int) c );
}
return Long.parseLong( sb.toString() );
}
}