Equivalent to Java's Optional.orElse in C# - java

I'm looking for nice syntax for providing a default value in the case of null. I've been used to using Optional's instead of null in Java where API's are concerned, and was wondering if C#'s nicer nullable types have an equivalent?
Optionals
Optional<String> x = Optional<String>.absent();
String y = x.orElse("NeedToCheckforNull"); //y = NeedToCheckforNull
#nullable
String x = null;
String y = x == null ? "NeedToCheckforNull" : x ; //y = NeedToCheckforNull
How would I make the above more readable in C#?
JavaScript would allow y = x | "NeedToCheckforNull"

You can use the ?? operator.
Your code will be updated to:
string x = null;
string y = x ?? "NeedToCheckforNull";
See: ?? Operator (C# Reference)

C# has the special Nullable<T> type which can be declared with int?, decimal?, etc. These can provide a default value by using .GetValueOrDefault(), T GetValueOrDefault(T defaultValue), and the ?? operator.
string x = null;
Console.WriteLine(x ?? "NeedToCheckforNull");

.Net developers always try to compare C# feature to java. This is their big mistake. Microsoft always teach them like that. But they don't know how java capable of. Optional is not only nullable type. Nullable type is one of the its feature. But main purpose of Optional is single stream. You can use map(), flatMap() and filter() Lambda expression functions. There is no such alternative in .Net world unfortunately.
However there is lambda expression on List if you want to use as Optional.
But for single item, there is not such feature in .Net

I've created my own.
public class Optional<T> {
private T value;
public bool IsPresent { get; private set; } = false;
private Optional() { }
public static Optional<T> Empty() {
return new Optional<T>();
}
public static Optional<T> Of(T value) {
Optional<T> obj = new Optional<T>();
obj.Set(value);
return obj;
}
public void Set(T value) {
this.value = value;
IsPresent = true;
}
public T Get() {
return value;
}
}

consider using language extensions option type
int x = optional.IfNone("NeedToCheckforNull");

Thanks for the inspiration #sm-adnan
using System;
using System.Diagnostics.CodeAnalysis;
namespace Common;
public readonly struct Optional<T>
{
private readonly T _value;
private Optional(T value)
{
_value = value;
}
public static Optional<T> Empty() => new Optional<T>(default);
public static Optional<T> Of([AllowNull] T value)
{
return value is null ? Empty() : new Optional<T>(value);
}
public T GetValue()
{
if (HasValue()) return _value;
throw new InvalidOperationException("No value present");
}
public bool HasValue()
{
return _value is not null;
}
public void HasValue(Action<T> method)
{
if (HasValue()) method.Invoke(_value);
}
public void HasValue(Func<object> method)
{
if (HasValue()) method.Invoke();
}
public T OrElse(T other)
{
return HasValue() ? _value : other;
}
public T OrElseGet(Func<T> method)
{
return HasValue() ? _value : method.Invoke();
}
public T OrElseThrow(Func<Exception> method)
{
return HasValue() ? _value : throw method.Invoke();
}
public Optional<TU> Map<TU>(Func<T, TU> method)
{
return HasValue() ? new Optional<TU>(method.Invoke(_value)) : default;
}
}

Related

Check not null in Java

Imagine I have, say, XML-generated entity in Java that holds some data I need.
For example:
<Car>
<Engine>
<Power>
175
</Power>
</Engine>
</Car>
So if I need an engine power, I, followed by the best practices of business software development, will do the next thing:
Car car = dao.getCar()
Power power = car != null && car.engine != null ? power : null
return power
I hate this. Sometimes it seems that half of the code is just null checks.
Any ideas?
Take a look at Java 8 Optional class.
It does exactly that: it avoids the ugly checks on null.
In your case, you could use this snippet of code to avoid them:
Car car = dao.getCar();
Optional<Car> optionalCar = Optional.ofNullable(car);
Optional<Power> optionalPower = getPowerIfPresent(optionalCar);
Power power = Optional.empty();
if(optionalPower.isPresent()) {
power = optionalPower.get();
}
after writing a function that returns the power of a given car:
public static Optional<Power> getPowerIfPresent(Optional<Car> car) {
return car
.flatMap(c -> c.getEngine())
.map(e -> e.getPower());
}
This is the same as using of Optional, but might be more readable:
public class NullSafe<T> {
private final T value;
public NullSafe(#Nullable T value) { this.value = value; }
public static <T> NullSafe<T> of(#Nullable T value) { return new NullSafe<>(value); }
public <R> NullSafe<R> get(Function<T,R> mapper) {
R newValue = (value != null) ? mapper.apply(value) : null;
return new NullSafe<>(newValue);
}
public T nullable() { return value; }
public T orDefault(T defaultValue) { return (value != null) ? value : defaultValue; }
}
And usage:
Power power = NullSafe.of(dao.getCar())
.get(Car::getEngine)
.get(Engine::getPower)
.nullable(); // .orDefault(Power.defaultPower());
An alternative can be static methods:
public static <R> R get(Supplier<R> supplier, R defaultValue) {
try { return supplier.get(); }
catch (NullPointerException ex) { return defaultValue; }
}
public static <R> R getNullable(Supplier<R> supplier) { return get(supplier, null); }
And usage:
Power power = NullSafe.get(() -> dao.getCar().getEngine().getPower(), Power.defaultPower());
Power powerOrNull = NullSafe.getNullable(() -> dao.getCar().getEngine().getPower());
My own approach kind of this now:
public class CarDataExtractor {
private final Car car;
private CarDataExtractor(Car car) {
this.car = car;
}
public static CarDataExtractor on(Car car) {
return new CarDataExtractor(car);
}
public EngineDataExtractor engine() {
return car != null && car.getEngine() != null
? EngineDataExtractor.on(car.getEngine())
: EngineDataExtractor.on(null);
}
public Car self() {
return car;
}
}
public class EngineDataExtractor {
private final Engine engine;
private EngineDataExtractor(Engine engine) {
this.engine = engine;
}
public static EngineDataExtractor on(Engine engine) {
return new EngineDataExtractor(engine);
}
public PowerDataExtractor engine() {
return engine != null && engine.getPower() != null
? PowerDataExtractor.on(engine.getPower())
: PowerDataExtractor.on(null);
}
public Engine self() {
return engine;
}
}
...
Power power = CarDataExtractor.on(dao.getCar()).engine().power().self()
It is because I am restricted to Java 6...
Or maybe create some util method:
static <T> Optional<T> tryGet(Supplier<T> getter) {
try {
return Optional.ofNullable(getter.get());
} catch(NullPointerException ignored) {
return Optional.empty();
}
}
Then you could use it like this:
System.out.println(tryGet(() -> car.engine.power).orElse(new Power()));
There is a library no-exception that does that, but you cannot specify it to only "silence" NPEs.
Exceptions.silence().get(() -> car.engine.power).orElse(new Power())
There is also another option, you could use, which might be helpful for you if you're using Spring.
If you're not using Spring you would need to add additional dependency to your project.
Using Spel you could do:
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(dao.getCar());
Power power = parser.parseExpression("engine?.power").getValue(context, Power.class);
In expression engine?.power safe navigation operator is being used. In case engine is null, then the whole expression will evaluate to null.
This solution will work on Java 6.

Switch according to input and return dynamic value

In this method I get string as input and according to the string name I need to return value sometimes its string sometime int ,double,int64 ,bool etc
Since its dynamic type i don't know how to define it in the method return type
and how to add to it the value and how to call to this method that the return type is dynamic ,any idea?
public static ? SwitchInput(String TypeName) {
if (TypeName == "java.lang.String" ) {
Return = "A";
}
else if (TypeName == "int" ) {
Return = 1;
}
else if (TypeName == "double") {
Return = 1.00
}
etc for bool and all the other types
}
Object will be your best bet, unless returned type shares an Ancestor
Example :
public static Object switchInput(String typeName) {
if ("java.lang.String".equals(typeName)) {
return "A";
}
else if ("int".equals(typeName)) {
return 1i;
}
else if ("double".equals(typeName)) {
return 1.0d
}
}
Another example with generics
static <T> T switchInput(String typeName){
if ("java.lang.String".equals(typeName)) {
return "A";
}
else if ("int".equals(typeName)) {
return 1i;
}
else if ("double".equals(typeName)) {
return 1.0d
}
}
String str = MyClass.switchInput("java.lang.String")
I have not tested that, this is a simpler version of my first thought about generics
To know what the return type is, you have to find a container where all these types fit in. Obviously, this is Object. You'd have to convert the primitive types to the corresponding object (like int to Integer).
A better approach would be to create a new container class, which holds a generic type <T>. Like
public class SwitchDemo {
public static SwitchInputType<?> switchInput(String typeName) {
if (typeName.equals("java.lang.String")) {
return new SwitchInputType<String>(new String("A"));
} else if (typeName.equals("int")) {
return new SwitchInputType<Integer>(new Integer(312));
}
return null;
}
public static class SwitchInputType<T> {
private T type;
public SwitchInputType(T type) {
super();
this.type = type;
}
public T getType() {
return type;
}
public void setType(T type) {
this.type = type;
}
}
public static void main(String[] args) {
SwitchInputType<?> sit1 = SwitchDemo.switchInput("java.lang.String");
System.out.println(sit1.getType());
SwitchInputType<?> sit2 = SwitchDemo.switchInput("int");
System.out.println(sit2.getType());
}
}
As an ugly solution to your problem, you could set your method to run the type Object. (as Boolean, Integer, Double are all subtypes)
You would have to ensure though that you then inferred the correct type afterwards when using the returned value (using instanceof) and recast it to the correct type.
Can I ask though why you need such a method? This is abusing the notion of a method definition slightly.
public static Object SwitchInput(String TypeName) {
if (TypeName.equals("java.lang.String") ) {
Return = new String("A");
}
else if (TypeName.equals("int") ) {
Return = new Integer(1);
}
else if (TypeName.equals("double")) {
Return = new Double(1.00) ;
}
etc for bool and all the other types
}
And using this code snippet to infer what type it is further on down in your code
if(returned_value instanceof Double)
etc.

Java - Generics vs Casting Objects

I have a class Data<T>
with a generic attribute
private T value;
is there nicer way to do the following?
ie returning the generic type in different forms?
public List<String> getValues() {
if (value.getClass() != ArrayList.class)
throw new Exception("Wrong Enum value '%s'", value);
return (ArrayList<String>) value;
//ugly
}
public String getStringValue() {
if (value.getClass() != String.class)
throw new Exception("Wrong value type '%s'", value);
return (String) value;
//ugly
}
public Float getFloatValue() {
if (value.getClass() != Double.class)
throw new Exception("Wrong value type '%s'", value);
return (Float) value;
//ugly
}
public Long getLongValue() {
if (value.getClass() != Double.class)
throw new Exception("Wrong value type '%s'", value);
return (Long) value;
//ugly
}
public T getValue() {
return value;
}
Precision, I'm using Gson as deserializer, to get a List, each Data objects can then be heterogeous
Could also register adapters for float and long detection, but it wouldn't be faster or nicer
edit: gson fails to retrieve longs:
either:
((Long) d.getValue())
java.lang.Double cannot be cast to java.lang.Long
or
Long.parseLong( d.getValue().toString())
java.lang.NumberFormatException: For input string: "212231.0"
I tried to register a LongAdpater
gsonBuilder.registerTypeAdapter(Long.class, new LongAdapter());
private static class LongAdapter implements
JsonSerializer<Long>, JsonDeserializer<Long>
{
#Override public Long deserialize(
JsonElement json,
Type type,
JsonDeserializationContext arg2) throws JsonParseException
{
return json.getAsLong();
}
#Override
public JsonElement serialize(Long l, Type arg1,
JsonSerializationContext arg2) {
return new JsonPrimitive(new Double(l));
}
}
java.lang.IllegalArgumentException: Cannot register type adapters for class java.lang.Long
edit2 for tsOverflow:
Data<Float> d1 = new Data<Float>( new Float(6.32));
List<String> l = new ArrayList<String>();
l.add("fr");
l.add("it");
l.add("en");
Data<List<String>> d2 = new Data<List<String>>( l);
Data<Long> d3 = new Data<Long>(new Long(212231));
List<Data> data = new ArrayList<Data>();
data.add(d1);
data.add(d2);
data.add(d3)
new Gson().toJson(data);
The point of generics is NOT to allow a class to use different types at the same time.
Generics allow you to define/restrict the type used by an instance of an object.
The idea behind generics is to eliminate the need to cast.
Using generics with your class should result in something like this:
Data<String> stringData = new Data<String>();
String someString = stringData.getValue();
Data<Long> longData = new Data<Long>();
Long someLong = longData.getValue();
Data<List<String>> listData = new Data<List<String>>();
List<String> someList = listData.getValue();
You should either use Objects and casting --OR-- use generics to avoid casting.
You seem to believe that generics allow for heterogeneous typing within the same instance.
That is not correct.
If you want a list to contain a mixed bag of types, then generics are not appropriate.
Also...
To create a long from a double, use Double.longValue().
To create a float from a double, use Double.floatValue().
I recommend reading the documentation.
The design looks suspicious to me, but to answer your actual question:
The case for Long-values looks wrong. Your snippet contains a c&p error
public Long getLongValue() {
if (value.getClass() != Double.class) // <<- should be Long.class
throw new Exception("Wrong value type '%s'", value);
return (Long) value;
//ugly
}
thus it should read:
public Long getLongValue() {
if (value.getClass() != Long.class)
throw new Exception("Wrong value type '%s'", value);
return (Long) value;
//ugly
}
However, in order to reduce code duplication, you could introduce a generic helper method
private T getValue() {
return value;
}
private <V> V castValue(Class<V> type) {
if (!type.isInstance(value)) {
// exception handling
}
return type.cast(value);
}
public List<String> getValues() {
return castValue(ArrayList.class);
}
public String getStringValue() {
return castValue(String.class);
}
If you decide to go for that approach, I'd recommend to de-generify the data class since it's irritating to have a type parameter if there is actually no constraint on the instance itself. I'd use Object instead for the field type:
private Object getValue() {
return value;
}
private <V> V castValue(Class<V> type) {
if (!type.isInstance(value)) {
// exception handling
}
return type.cast(value);
}
public List<String> getValues() {
return castValue(ArrayList.class);
}
public String getStringValue() {
return castValue(String.class);
}
// .. more cases ..
You could just use the type T directly for a simple getter and Class.cast -method for other types:
public class GenericDataTest
{
private static class DataTest<T>
{
private T value;
public DataTest(T value)
{
this.value = value;
}
public T getValue()
{
return value;
}
public Object getValueAsType(Class<?> type)
{
return type.cast(value);
}
}
#Test
public void testGeneric()
{
DataTest<String> stringTest = new DataTest<String>("Test");
Assert.assertEquals("Test", stringTest.getValue());
Assert.assertEquals("Test", stringTest.getValueAsType(String.class));
DataTest<Double> doubleTest = new DataTest<Double>(1.0);
Assert.assertEquals(1.0, doubleTest.getValue());
Assert.assertEquals(1.0, doubleTest.getValueAsType(Double.class));
}
#Test(expected = ClassCastException.class)
public void testClassCastFailure()
{
DataTest<String> stringTest = new DataTest<String>("Test");
Assert.assertEquals("Test", stringTest.getValueAsType(Float.class));
}
}
You could ask if "value" is assignable to the expected class.
private T value;
.
.
.
public Object getValueAsObjectOfClass(Class<?> expectedClass) {
if(!expectedClass.isAssignableFrom(value.getClass())) {
// abort gracefully
}
return expectedClass.cast(value);
}

Convert integer value to matching Java Enum

I've an enum like this:
public enum PcapLinkType {
DLT_NULL(0)
DLT_EN10MB(1)
DLT_EN3MB(2),
DLT_AX25(3),
/*snip, 200 more enums, not always consecutive.*/
DLT_UNKNOWN(-1);
private final int value;
PcapLinkType(int value) {
this.value= value;
}
}
Now I get an int from external input and want the matching input - throwing an exception if a value does not exist is ok, but preferably I'd have it be DLT_UNKNOWN in that case.
int val = in.readInt();
PcapLinkType type = ???; /*convert val to a PcapLinkType */
You would need to do this manually, by adding a a static map in the class that maps Integers to enums, such as
private static final Map<Integer, PcapLinkType> intToTypeMap = new HashMap<Integer, PcapLinkType>();
static {
for (PcapLinkType type : PcapLinkType.values()) {
intToTypeMap.put(type.value, type);
}
}
public static PcapLinkType fromInt(int i) {
PcapLinkType type = intToTypeMap.get(Integer.valueOf(i));
if (type == null)
return PcapLinkType.DLT_UNKNOWN;
return type;
}
There's a static method values() which is documented, but not where you'd expect it: http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
enum MyEnum {
FIRST, SECOND, THIRD;
private static MyEnum[] allValues = values();
public static MyEnum fromOrdinal(int n) {return allValues[n];}
}
In principle, you can use just values()[i], but there are rumors that values() will create a copy of the array each time it is invoked.
You will have to make a new static method where you iterate PcapLinkType.values() and compare:
public static PcapLinkType forCode(int code) {
for (PcapLinkType typŠµ : PcapLinkType.values()) {
if (type.getValue() == code) {
return type;
}
}
return null;
}
That would be fine if it is called rarely. If it is called frequently, then look at the Map optimization suggested by others.
if you have enum like this
public enum PcapLinkType {
DLT_NULL(0)
DLT_EN10MB(1)
DLT_EN3MB(2),
DLT_AX25(3),
DLT_UNKNOWN(-1);
private final int value;
PcapLinkType(int value) {
this.value= value;
}
}
then you can use it like
PcapLinkType type = PcapLinkType.values()[1]; /*convert val to a PcapLinkType */
You can do something like this to automatically register them all into a collection with which to then easily convert the integers to the corresponding enum. (BTW, adding them to the map in the enum constructor is not allowed. It's nice to learn new things even after many years of using Java. :)
public enum PcapLinkType {
DLT_NULL(0),
DLT_EN10MB(1),
DLT_EN3MB(2),
DLT_AX25(3),
/*snip, 200 more enums, not always consecutive.*/
DLT_UNKNOWN(-1);
private static final Map<Integer, PcapLinkType> typesByValue = new HashMap<Integer, PcapLinkType>();
static {
for (PcapLinkType type : PcapLinkType.values()) {
typesByValue.put(type.value, type);
}
}
private final int value;
private PcapLinkType(int value) {
this.value = value;
}
public static PcapLinkType forValue(int value) {
return typesByValue.get(value);
}
}
I know this question is a few years old, but as Java 8 has, in the meantime, brought us Optional, I thought I'd offer up a solution using it (and Stream and Collectors):
public enum PcapLinkType {
DLT_NULL(0),
DLT_EN3MB(2),
DLT_AX25(3),
/*snip, 200 more enums, not always consecutive.*/
// DLT_UNKNOWN(-1); // <--- NO LONGER NEEDED
private final int value;
private PcapLinkType(int value) { this.value = value; }
private static final Map<Integer, PcapLinkType> map;
static {
map = Arrays.stream(values())
.collect(Collectors.toMap(e -> e.value, e -> e));
}
public static Optional<PcapLinkType> fromInt(int value) {
return Optional.ofNullable(map.get(value));
}
}
Optional is like null: it represents a case when there is no (valid) value. But it is a more type-safe alternative to null or a default value such as DLT_UNKNOWN because you could forget to check for the null or DLT_UNKNOWN cases. They are both valid PcapLinkType values! In contrast, you cannot assign an Optional<PcapLinkType> value to a variable of type PcapLinkType. Optional makes you check for a valid value first.
Of course, if you want to retain DLT_UNKNOWN for backward compatibility or whatever other reason, you can still use Optional even in that case, using orElse() to specify it as the default value:
public enum PcapLinkType {
DLT_NULL(0),
DLT_EN3MB(2),
DLT_AX25(3),
/*snip, 200 more enums, not always consecutive.*/
DLT_UNKNOWN(-1);
private final int value;
private PcapLinkType(int value) { this.value = value; }
private static final Map<Integer, PcapLinkType> map;
static {
map = Arrays.stream(values())
.collect(Collectors.toMap(e -> e.value, e -> e));
}
public static PcapLinkType fromInt(int value) {
return Optional.ofNullable(map.get(value)).orElse(DLT_UNKNOWN);
}
}
As #MeBigFatGuy says, except you can make your static {...} block use a loop over the values() collection:
static {
for (PcapLinkType type : PcapLinkType.values()) {
intToTypeMap.put(type.getValue(), type);
}
}
You could add a static method in your enum that accepts an int as a parameter and returns a PcapLinkType.
public static PcapLinkType of(int linkType) {
switch (linkType) {
case -1: return DLT_UNKNOWN
case 0: return DLT_NULL;
//ETC....
default: return null;
}
}
This is what I use:
public enum Quality {ENOUGH,BETTER,BEST;
private static final int amount = EnumSet.allOf(Quality.class).size();
private static Quality[] val = new Quality[amount];
static{ for(Quality q:EnumSet.allOf(Quality.class)){ val[q.ordinal()]=q; } }
public static Quality fromInt(int i) { return val[i]; }
public Quality next() { return fromInt((ordinal()+1)%amount); }
}
static final PcapLinkType[] values = { DLT_NULL, DLT_EN10MB, DLT_EN3MB, null ...}
...
public static PcapLinkType getPcapLinkTypeForInt(int num){
try{
return values[int];
}catch(ArrayIndexOutOfBoundsException e){
return DLT_UKNOWN;
}
}
This might not be a great solution, but its working for me:
public enum Type {
WATER, FIRE, GRASS;
public static Type getType(int value){
if(value==WATER.ordinal()){
return WATER;
}else if(value==FIRE.ordinal()){
return FIRE;
}else if(value==GRASS.ordinal()){
return GRASS;
}else {
return null;
}
}
}
There is no way to elegantly handle integer-based enumerated types. You might think of using a string-based enumeration instead of your solution. Not a preferred way all the times, but it still exists.
public enum Port {
/**
* The default port for the push server.
*/
DEFAULT("443"),
/**
* The alternative port that can be used to bypass firewall checks
* made to the default <i>HTTPS</i> port.
*/
ALTERNATIVE("2197");
private final String portString;
Port(final String portString) {
this.portString = portString;
}
/**
* Returns the port for given {#link Port} enumeration value.
* #return The port of the push server host.
*/
public Integer toInteger() {
return Integer.parseInt(portString);
}
}

How to convert string result of enum with overridden toString() back to enum?

Given the following java enum:
public enum AgeRange {
A18TO23 {
public String toString() {
return "18 - 23";
}
},
A24TO29 {
public String toString() {
return "24 - 29";
}
},
A30TO35 {
public String toString() {
return "30 - 35";
}
},
}
Is there any way to convert a string value of "18 - 23" to the corresponding enum value i.e. AgeRange.A18TO23 ?
Thanks!
The best and simplest way to do it is like this:
public enum AgeRange {
A18TO23 ("18-23"),
A24TO29 ("24-29"),
A30TO35("30-35");
private String value;
AgeRange(String value){
this.value = value;
}
public String toString(){
return value;
}
public static AgeRange getByValue(String value){
for (final AgeRange element : EnumSet.allOf(AgeRange.class)) {
if (element.toString().equals(value)) {
return element;
}
}
return null;
}
}
Then you just need to invoke the getByValue() method with the String input in it.
You could always create a map from string to value - do so statically so you only need to map it once, assuming that the returned string remains the same over time. There's nothing built-in as far as I'm aware.
According to effective java (2nd ed) item 30, it can be (it is much faster than the loop)
public enum AgeRange {
A18TO23("18-23"),
A24TO29("24-29"),
A30TO35("30-35");
private final String value;
AgeRange(String value){
this.value = value;
}
#Override public String toString(){
return value;
}
private static final Map<String, AgeRange> stringToEnum =
new HashMap<String, AgeRange>();
static {
for (AgeRange r : values()) {
stringToEnum.put(r.toString(), r);
}
}
public static AgeRange getByValue(String value){
return stringToEnum.get(value);
}
}
for (AgeRange ar: EnumSet.allOf(AgeRange)) {
if (ar.toString().equals(inString)) {
myAnswer = ar;
break;
}
}
Or something like that? Just typed in, haven't run through a compiler. Forgive (comment on) typos...
Or use logic like this to build a map once. Avoid iteration at runtime. Good idea, Jon.
The class overrides "toString()" - so, to get the reverse operation, you need to override valueOf() to translate the output of toString() back to the Enum values.
public enum AgeRange {
A18TO23 {
public String toString() {
return "18 - 23";
}
public AgeRange valueOf (Class enumClass, String name) {
return A18T023
}
},
.
.
.
}
Buyer beware - uncompiled and untested...
The mechanism for toString() and valueOf() is a documented part of the API
You could try something like the following?
static AgeRange fromString(String range) {
for (AgeRange ageRange : values()) {
if (range.equals(ageRange.toString())) {
return ageRange;
}
}
return null;
}
Or, as others suggested, using a caching approach:
private static Map<String, AgeRange> map;
private static synchronized void registerAgeRange(AgeRange ageRange) {
if (map == null) {
map = new HashMap<String, AgeRange>();
}
map.put(ageRange.toString(), ageRange);
}
AgeRange() {
registerAgeRange(this);
}
static AgeRange fromString(String range) {
return map.get(range);
}

Categories