Option 1 is to use a private static nested class to hold the map:
public enum ExampleEnum {
EXAMPLE0(Example.example0),
EXAMPLE1(Example.example1),
EXAMPLE2(Example.example2);
public final Example identifier;
private static class MapHolder{
private static Map<Example, ExampleEnum> map = new HashMap<>();
}
private ExampleEnum(final Example identifier) {
MapHolder.map.put(this.identifier = identifier, this);
}
public ExampleEnum get(final Example identifier) {
return MapHolder.map.get(identifier);
}
}
Of course, this will compile under the hood to a syntetic class ExampleEnum$MapHolder, but in the source code it's "modular".
Option 2 is to iterate over values():
public ExampleEnum get(final Example identifier) {
for(ExampleEnum e : values()){
if(e.identifier == identifier){
return e;
}
}
throw new IllegalArgumentException(); // or return null if you want
}
Personally, I would prefer this, as it introduces no new entities purely as a workaround. As for "slow linear search", that is very much a premature optimization.
First, a "linear search" over 3 elements is actually going to be faster than using a HashMap. At what number it becomes slower would have to be tested; I'd actually bet money that it's higher than the average number of elements in a Java enum.
And even then, it's still a premature optimization. Not gonna matter unless that method gets called millions of times a second in a tight loop, which it very likely won't.
Oh, here's Option 3 for our lovers of functional programming:
public ExampleEnum get(final Example identifier) {
return Arrays.stream(values())
.filter(e->e.identifier==identifier)
.findFirst()
.orElseThrow();
}
IMO a wash with Option 2 in terms of code prettiness, probably a bit slower as well (still likely irrelevant).