Deserialize JSON to Java enum - java

I have the following enumeration in Java on Android and I would like to be able to deserialize an integer in an incoming JSON string/object into this Enum type. I have been getting hits on Jackson and GSON but nothing on the JSON.org package, which I am using.
Is there an easy way to do this or do I need to alter the JSON decoder? Thanks.
public enum ValueEnum {
ONE(1),
TWO(2),
THREE(3);
private int value;
private ValueEnum(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

ValueEnum.values() will return you array of ValueEnum[] then you can iterate over array and check for Value
public static ValueEnum valueOf(int value) {
ValueEnum[] valueEnums = ValueEnum.values();
for (ValueEnum valueEnum : valueEnums) {
if (valueEnum.getValue() == value)
{
return valueEnum;
}
}
return DEFAULT;
}

Related

NumberFormatException with custom type on primefaces's InputNumber

I've created a kind of custom type on a JSF project using PrimeFaces.
I'd use this type with PrimeFaces's inputNumber but I get the error:
NumberFormatException class java.lang.NumberFormatException
java.lang.NumberFormatException at
java.math.BigDecimal.(BigDecimal.java:550) at
java.math.BigDecimal.(BigDecimal.java:383) at
java.math.BigDecimal.(BigDecimal.java:806) at
org.primefaces.component.inputnumber.InputNumberRenderer.formatForPlugin(InputNumberRenderer.java:292)
at
org.primefaces.component.inputnumber.InputNumberRenderer.encodeScript(InputNumberRenderer.java:231)
at
org.primefaces.component.inputnumber.InputNumberRenderer.encodeEnd(InputNumberRenderer.java:124)
In short, I've created a class MyCurrency that stores a double and extends ValueExpression, like the following:
public final class MyCurrency extends ValueExpression implements Comparable<MyCurrency>, Serializable {
private Double value;
private MyCurrency(final Double value) {
this.value = value;
}
public Double getValue() {
return this.value;
}
public Long longValue() {
return value.longValue();
}
#Override
public int compareTo(final MyCurrency o) {
return this.getValue().compareTo(o.getValue());
}
#Override
public Object getValue(final ELContext context) {
return new BigDecimal(this.value);
}
#Override
public void setValue(final ELContext context, final Object value) {
this.value = new Builder().withValue(value).build().value;
}
public static class Builder {
private Double value;
public Builder withValue(final Double value) {
this.value = value;
return this;
}
public Builder withValue(final Long value) {
this.value = new Double(value);
return this;
}
public Builder withValue(final Object value) {
this.value = Double.parseDouble(value.toString());
return this;
}
public MyCurrency build() {
return new MyCurrency(this.value);
}
}
}
And in my bean I've a property with type MyCurrency.
When I use it with an inputNumber:
<p:inputNumber id="importoDa" value="#{myBean.myAmount}" />
I get the error [NumberFormatException].
Any help, please?
Not sure if it's a solution for what you are asking, but it seems that you are trying to format the input of your inputNumber as currency an compare it's value to another object. It might be easier to store only the double or BigDecimal value in your bean and format it in the view as currency. You can achieve this using the symbol and decimalPlaces properties of the <p:inputNumber> tag this way:
<p:inputNumber id="importoDa" value="#{myBean.myAmount}" symbol="$" decimalPlaces="2" />
Hope it helps :)

How can i convert convert json to object with different field names GSON

how can i convert this json:
[{"id":"0","value":1010},{"id":"1","value":"1000"},{"id":"2","value":"1111"}]
to single object having object having fields.
value0;(corresponds to id of value 0) it should be 1010
value1;(corresponds to id of value 1) it should be 1000
value2;(corresponds to id of value 2)
using GSON how can i implement it.
Create a Java Class according to your json object field like:-
public class Example {
private String id;
private String value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
And one more class to represent arrays of json value to JAVA objects:-
public class JSONExample {
List<Example> examples;
public List<Example> getExamples() {
return examples;
}
public void setExamples(List<Example> examples) {
this.examples = examples;
}
}
Then you can loop your JSON object/array to create "Example" java
Object and using the same create JSONExample object.
Thats It.
It is going to be something like below :
String yourJson = "[{"id":"0","value":1010},{"id":"1","value":"1000"},{"id":"2","value":"1111"}]";
Gson gson = new Gson();
YourObject[] yourObjectArr= gson.fromJson(yourJson, YourObject[].class);
class YourObject
{
String id;
String value;
}

How to nest enum

I have some UI client filters (combobox and checkbox group) that I need to use on server side: I thought to use an enum to identify filter types and others enums to identify each filter's options.
// All UI filters
public enum FilterType {
AGGREGATION("aggregation"),
AREA("area"),
PRODUCTION("production"),
DATA_TYPE("datatype"),
PRODUCER("producer"),
NETWORK("network"),
SOURCE("source");
private String value;
private FilterType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
// FilterType.AGGREGATION filter options
public enum AggregationOptionType {
STANDARD("standard"),
DTR("dtr"),
CO("co");
private String value;
private AggregationOptionType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
I would like to craete a hard link between FilterType.AGGREGATION and AggregationOptionType forcing the access to an option via FilterType.AGGREGATION.DTR.
How can I "nest" an enum inside a value of another enum?
Are there other patterns (maybe smarter than mine) to achieve the same result?
EDIT
A clarification: I do NOT need to assign to each value of the outer enum a value of a common inner enum. I need to assign a whole different inner enum to each value of the outer enum.
You can put one enum into another, like:
enum OuterEnum {
A, B;
enum InnerEnum {
C, D;
}
}
To use like:
class Enumuser {
OuterEnum.InnerEnum ie = OuterEnum.InnerEnum.C;
}
But of course, that is not exactly what you are looking for.
You need to go one step further:
enum OuterEnum {
A(InnerEnum.C), B(InnerEnum.D);
private final InnerEnum inner;
private OuterEnum(InnerEnum inner) { this.inner = inner; }
public InnerEnum getInner() { return inner; }
enum InnerEnum {
C, D;
}
}
class Enumuser {
OuterEnum.InnerEnum inner = OuterEnum.A.getInner();
}
But a final word of warning: don't get too hang up on using enums for such purposes. You see, as soon as you start writing switch statements all over the place that switch over such enums, in order to do this or that ... you are probably doing something wrong. Consider not "falling into that enum trap" please.
Instead you should be looking into using polymorphism, like shown here!
You can add it to the Enum, as a variable.
But only if you can have all the sub Enums under the same enum type ie
public enum FilterType {
AGGREGATION("aggregation",Subfilter.DTR);
}
You can do something like as follows:
//All UI filters
public interface FilterType {
// FilterType.AGGREGATION
public interface AGGREGATION {
// FilterType.AGGREGATION filter options
enum AggregationOptionType {
STANDARD("standard"),
DTR("dtr"),
CO("co");
private String value;
private AggregationOptionType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
}
}
e.g. for AGGREGATION
Just use it in the same way like a String value and if you want to have a single file, so hold your enums in a interface class:
public interface Enums {
public enum FilterType {
AGGREGATION("aggregation", AggregationOptionType.DTR),
AREA("area"),
PRODUCTION("production"),
DATA_TYPE("datatype"),
PRODUCER("producer"),
NETWORK("network", AggregationOptionType.CO),
SOURCE("source");
public final String value;
public final AggregationOptionType type;
private FilterType(String value, AggregationOptionType typy) {
this.value = value;
this.type = typy;
}
private FilterType(String value) {
this.value = value;
this.type = AggregationOptionType.STANDARD;
}
}
public enum AggregationOptionType {
STANDARD("standard"),
DTR("dtr"),
CO("co");
public final String value;
private AggregationOptionType(String value) {
this.value = value;
}
}
}

Java - return type for enum values

Good day SO people. I have a problem regarding returning the inner enum values of my enum. I do not know which return type to use. I have tried googling and bumped into some solutions the uses generics however, I still have no luck. I do not know if my question has a solution or probably I did a bad design. So here goes, below
is my enum.
public enum KEYS
{
A("value"),
B("value"),
C("value");
public enum KEYS_GROUP_A
{
ITEM_A ("value"),
ITEM_B ("value"),
ITEM_C ("value");
private String value;
private KEYS_GROUP_A( String _value )
{
value = _value;
}
public String getVal()
{
return value;
}
}
public enum KEYS_GROUP_B
{
ITEM_A ("value"),
ITEM_B ("value"),
ITEM_C ("value");
private String value;
private KEYS_GROUP_B( String _value )
{
value = _value;
}
public String getVal()
{
return value;
}
}
public enum KEYS_GROUP_C
{
ITEM_A ("value"),
ITEM_B ("value"),
ITEM_C ("value");
private String value;
private KEYS_GROUP_C( String _value )
{
value = _value;
}
public String getVal()
{
return value;
}
}
private String value;
private PROPERTY_KEYS(String _value)
{
value = _value;
}
public String getVal()
{
return value;
}
public <?> getEnumValues(int x)
{
if ( 0 == x )
{
return KEYS.KEYS_GROUP_A.values();
}
else if ( 1 == x )
{
return KEYS.KEYS_GROUP_B.values();
}
else
{
return KEYS.KEYS_GROUP_C.values();
}
}
}
What I am trying to do is the getEnumValues() method. I have tried the return type <T extends Enum<T>> T but still an error occurs. Please tell if my design is bad or should not really be done. Please state some references. I'm willing to read and learn. Please shed some light! Thanks in advance!
The most specific type you can return is
public Enum<?>[] getEnumValues(int x)
You can return a more "useful" type if you define an interface like this:
interface HasVal { String getVal(); }
then make your enums all implement that interface, e.g.:
public enum KEYS_GROUP_A implements HasVal {
// ...
#Override public String getVal() { return value; }
}
Then you can return
public HasVal[] getEnumValues(int x)
and be able to invoke the getVal method on the instances:
for (HasVal val : getEnumValues(x)) {
System.out.println(val.getVal());
}
You can't use:
public <T extends Enum<T>> T[] getEnumValues(int x)
because this isn't satisfiable for a general T. For instance, I could define:
enum Blah {}
and then try to invoke:
Blah[] blah = getEnumValues(1);
That wouldn't be type safe, because at least one (well, all, actually) of the code paths return a value which is not covariant with Blah[].

Are there any advantages between List<CustomObject> and HashMap <String, Object>

I am trying to implement a solution (in Java 1.6) where i need to store some values (for a set of properties) and thinking in three options considering the following three (Any other idea is of course wellcome!)
Option 1
Create a class (call it Property) that can store different type of objects (String, int, boolean...) and and work with the set of properties as a List<Property>
Something like:
private String type; //Store the type of Object
private String name; //Store the name of the property
private String valueStr; //Store the String value
private int valueInt; //Store the int value
private boolean valueBool; //Store the boolean value
I dont really like the idea of having many properties and using only one of them. (only one of the values will be set per property)
Option 2
Use HashMap<String, Object> and parse the type on each case.
Have the good thing that you can get the Property by name
Option 3
Use HashMap<String, Property> Where the String is the name of the property and you can get the value with the name and no need to parse.
Questions are:
Which of one you think is the best one?
or if none of them are good i would like to hear other ideas
Also is there any performance difference between the List and the HashMap?
Thanks in advance for the help.
I think better is to have a custom Value class like this:
public class MyValue {
enum Type {
INT, STRING, BOOL;
}
private Type type; //Store the type of Object in Type Enum
private Object value; //Store the value in Object
public void setValue(int val) {
type = Type.INT;
value = new Integer(val);
}
public void setValue(String val) {
type = Type.STRING;
value = val;
}
public void setValue(boolean val) {
type = Type.BOOL;
value = new Boolean(val);
}
public String stringVal() {
// check type to be STRING first
return (String) value;
}
public int intVal() {
// check type to be INT first
return ((Integer) value.intValue());
}
public boolean booleanVal() {
// check type to be BOOL first
return ((Boolean) value.booleanValue());
}
}
You will need to convert from Object to specific type based on enum Type in your getters.
Another option would be something like this, using inheritance rather than keeping a large number of unused fields around.
public interface Property {
String getType();
String getName();
Object getValue();
}
public abstract class AbstractProperty implements Property {
private final String name;
protected AbstractProperty(String name) {
this.name = name;
}
}
public class StringProperty extends AbstractProperty {
private final String value;
public StringProperty(String name, String value) {
super(name);
this.value = value;
}
#Override
public String getType() {
return String.class.getName();
}
#Override
public String getValue() {
return value;
}
}
public class IntegerProperty extends AbstractProperty {
private final Integer value;
public IntegerProperty(String name, Integer value) {
super(name);
this.value = value;
}
#Override
public String getType() {
return Integer.TYPE.getName();
}
#Override
public Integer getValue() {
return value;
}
}
I think option 2 would be the best for you. Considering that you are storing properties I am expecting that you would be querying this list quite often which again points in the direction of a HashMap as that would make your lookup very efficient.
I suggest using an enum instead. Enums are good for holding lists of values, and are effective at retrieval.
public enum Property {
TYPE,
NAME,
VALUEINT; //...
private String sProp = "";
private int iProp = 0;
private boolean bProp = false;
public String getStringProp() {return sProp;}
public int getIntProp() {return iProp;}
public boolean getBoolProp() {return bProp;}
public void setStringProp(String str) {this.sProp = str;}
public void setIntProp(int i) {this.iProp = i;}
public void setBoolProp(boolean b) {this.bProp = b;}
}
This can then be accessed with Property.TYPE, Property.VALUEINT, etc. You can set properties with Property.TYPE.setStringProp(), and get them with Property.TYPE.getStringProp().
You can read more about enums from Oracle's site.
I am unsure if there's one 'best' way. It really depends on how the data would be used after storing in a data structure.
In cases when I just need to accumulate properties and do something on each of them, I'd use a list, or even an array, sometimes.
If you might have to get a particular property, say by name, then a HashMap could help.
Again if you want to use the native object type or an instance of Property depends on what kind of data you have.
Which performs better depends on the number of objects you have, how you'd access them for use, how often you'd insert and several other factors.

Categories