I want to define some enums for the various ajax services that I have available in my web application, like:
Enum Service
{
REGISTER,
LOGIN,
NEWS,
FAQ
}
However, each of these enums will also have a certain state like Failed, Loaded, etc. So I want to be able to use REGISTER.LOADED
, LOGIN.LOADED
etc, to fire up events on my event bus. However each state enum must be unique. I.e Register.LOADED
must be different from FAQ.LOADED
, and so on.
Edit: Also, I must be able to store all states in the same hashmap, e.g Register.LOADED
and Login.LOADED
must be storable in the same hashmap. And the parent service enums, i.eLOGIN, REGISTER
etc must be storable in the same hashmap as well.
What's the best way to accomplish this?
After some comments from the OP, I've updated my code. The usage syntax gets ugly, and it may not work particularly well in switch
blocks, but I believe this achieves what the OP is looking for:
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);
}
}
}
Output:
REGISTER==LOGIN :: false
REGISTER==REGISTER :: true
REGISTER==REGISTER :: true
REGISTER.LOADED==LOGIN.LOADED :: false
REGISTER.LOADED==REGISTER.LOADED :: true
REGISTER.FAILED==REGISTER.LOADED :: false
Not quite possible with the syntax you want, but Java enums are basically just classes by another name. (In fact, once compiled, they are classes which extend java.lang.Enum<E extends Enum<E>>
)
public class HelloWorld
{
public static void main(String []args)
{
Service a = Service.REGISTER;
a.state = Service.ServiceState.LOADED;
System.out.println(a);
}
}
enum Service
{
REGISTER(),
LOGIN(),
NEWS(),
FAQ();
public ServiceState state;
Service()
{
this.state = ServiceState.LOADED;
}
public String toString()
{
return super.toString() + "." + state.toString();
}
public enum ServiceState
{
LOADED,
FAILED
}
}
Output:
REGISTER.LOADED
Another option is to create several enums. One lists the services:
enum Service {
REGISTER, LOGIN, NEWS, FAQ;
}
the next one lists all states:
enum State { LOADED, FAILED }
Now you can either have a class which takes a service and a state in the constructor and which overrides equals() and hashCode() to distinguish them:
new ServiceState(REGISTER, LOADED)
or you create another enum which list valid combinations:
enum ServiceState {
REGISTER_LOADED(REGISTER, LOADED), ...
}
but this enum will be very big and the amount to type will soon become very big (if you add one value to the other enums, you need to add N enums to ServiceState
)
Just turn the "external" enum into a class and fill it with "internal" enums:
public class Service {
public enum REGISTER {
CANCELLED
}
// ...
public enum LOGIN {
LOADED
}
}
or nest it as public static
into the handler class, if it is the case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With