Reputation: 3920
I have a map like below to hold some constant values. Keeping values in a Map is not a good practice. Instead I can use an enum to hold these values. But I'm a bit confused about how to create an enum for the below mapping
//Map to store the events
public static final Map<String, Integer[]> OLYMPICS_SPORT_ID_PARAMS = new HashMap<>();
public static final Map<String, Integer[]> OLYMPICS_EVENT_ID_PARAMS = new HashMap<>();
public static final Map<String, Integer[]> OLYMPICS_PHASE_ID_PARAMS = new HashMap<>();
static {
OLYMPICS_SPORT_ID_PARAMS.put("sportId", VALID_SPORT_IDS);
OLYMPICS_EVENT_ID_PARAMS.put("n_EventID", VALID_EVENT_IDS);
OLYMPICS_PHASE_ID_PARAMS.put("n_EventPhaseID", VALID_EVENT_PHASE_IDS);
}
public static final Map<String, Map<String, Integer[]>> OLYMPICS_EVENTS_MAP = new HashMap<>();
static {
OLYMPICS_EVENTS_MAP.put("sportId", OLYMPICS_SPORT_ID_PARAMS);
OLYMPICS_EVENTS_MAP.put("eventId", OLYMPICS_EVENT_ID_PARAMS);
OLYMPICS_EVENTS_MAP.put("eventPhaseId", OLYMPICS_PHASE_ID_PARAMS);
}
Any idea to create an ENUM class to map OLYMPICS_EVENTS_MAP ?
Upvotes: 2
Views: 5092
Reputation: 1384
In my HO, generally you want to write the statement like this:
OlimpicSportEvent olSpEv = new OlimpicSportEvent(
Sport.ATHLETIC, Event.SPRINT_100_M, Phase.SEMIFINAL);
To be able to do so, you have to be sure that your Event.SPRINT_100_M
have Phase.SEMIFINAL
AND Sport.ATHLETIC
have Event.SPRINT_100_M
.
I'll not write the entire code here, but I'd try to explain my approach. First of all, you should write not only one, but three enums. I hope the code will tell you more than words. E.g.
public enum Sport {
ATHLETIC (0,
Arrays.asList( Event.SPRINT_100_M,
Event.MARATHON)
),
//...
SOCCER (109,
Arrays.asList( Event.TEAM_MATCH)
);
private final int id;
private final List<Event> events;
Sport(int id, List<Event> events){
this.id = id;
this.events = events;
}
public int getId(){
return id;
}
protected List<Event> getEvents(){
return this.events;
}
}
enum Event {
SPRINT_100_M, // similar to enum Sport, params goes here
//...
TEAM_MATCH,
MARATHON;
}
enum Phase {
FIRST_ROUND, // params goes here
//...
SEMIFINAL,
FINAL
}
As you see, I only wrote the enum Sport
to the end.
Now, I wrote 'test' sample like this (note that you must implement the validate method to meet your request as well as you must write the complete code for Event
and Phase
enums...
public class Answer {
static class OlimpicSportEvent {
//private other field
//private other field
private final Sport sport;
private final Event event;
private final Phase phase;
OlimpicSportEvent(Sport sport, Event event, Phase phase) throws Exception{
this.sport = sport;
this.event = event;
this.phase = phase;
if(!this.validate()){
throw new Exception();
}
}
public Sport getSport() {
return sport;
}
public Event getEvent() {
return event;
}
public Phase getPhase() {
return phase;
}
private boolean validate(){
return this.sport.getEvents().contains(this.event);
}
}
public static void main(String[] args) {
try {
OlimpicSportEvent olSpEv = new OlimpicSportEvent(
Sport.ATHLETIC, Event.SPRINT_100_M, Phase.SEMIFINAL);
System.out.println("olSpEv created!");
// do whatever you want
} catch (Exception ex) {
System.out.println("olSpEv invalid!");
// handle ex
}
}
}
Upvotes: 1
Reputation: 14999
You'd define it like this
enum IdParams {
OLYMPICS_SPORT_ID_PARAMS(VALID_SPORT_IDS),
OLYMPICS_EVENT_ID_PARAMS(VALID_EVENT_IDS),
OLYMPICS_PHASE_ID_PARAMS(VALID_EVENT_PHASE_IDS);
private Integer[] params;
private IdParams(Integer[] p) {
params = p;
}
public Integer[] getParameters() {
return params;
}
}
Be aware that an array is a very dangerous thing to have around like this though; client classes will be able to manipulate the individual values. I recommend you make it a List<Integer>
and return an unmodifiable version:
List<Integer> params;
// ...
private IdParams(Integer[] p) {
params = new ArrayList<>(Arrays.asList(p));
}
public List<Integer> getParamters() {
return Collections.unmodifiableList(params);
}
Upvotes: 2
Reputation: 45319
The first option to replace your initial implementation would be to use an enum map, java.util.EnumMap<K, V>
, which is aware of the enum type.
However, if you need to use an enum for this, a valid enum recording both the ID and the int array could look like:
enum OlympicEvents {
OLYMPICS_EVENTS_MAP("sportId", new Integer[] { 1, 2, 3 }),
OLYMPICS_EVENT_ID_PARAMS("eventId", new Integer[] { 1, 2, 3 }),
OLYMPICS_PHASE_ID_PARAMS("eventPhaseId", new Integer[] { 1, 2, 3 });
private String eventId;
private Integer[] eventParams;
private OlympicEvents (String eventId, Integer[] eventParams) {
this.eventId = eventId;
this.eventParams = eventParams;
}
public String getEventId() {
return eventId;
}
public Integer[] getEventParams() {
return eventParams;
}
}
Upvotes: 1
Reputation: 1827
You can use the ENUM
class to store your constants by creating constructor and getters for the ENUM
with body. Like this:
public enum MyEnum {
FIRST("1", "my first"),
SECOND("2", "my second"),
THIRD("3", "my third");
private final String value;
private final String description;
MyEnum(String value, String description) {
this.value = value;
this.description = description;
}
public String getValue() {
return value;
}
public String getDescription() {
return description;
}
}
And access your value or description by using: MyEnum.FIRST.getValue();
.
Upvotes: 3