Is JsonElement integer or float? - java

Is it possible to determine whether a GSON JsonElement instance is an integer or is it a float?
I'm able to determine whether it's a number:
JsonElement value = ...
boolean isNumber = value.getAsJsonPrimitive().isNumber();
But how to determine if it's an integer or a float, so I can subsequently use the correct conversion method? Either
float f = value.getAsJsonPrimitive().getAsFloat();
or
int i = value.getAsJsonPrimitive().getAsInt();
Edit: The other question may answer why this may be not implemented in GSON, but this question definitely isn't its duplicate.

The only way I've found so far is using regex on a string:
if (value.getAsJsonPrimitive().isNumber()) {
String num = value.getAsString();
boolean isFloat = num.matches("[-+]?[0-9]*\\.[0-9]+");
if (isFloat)
System.out.println("FLOAT");
else
System.out.println("INTEGER");
}
This correctly determines 123 as integer, and both 123.45 and 123.0 as floats.

use something like, and so if return json object is an instance of float or integer you can then apply the required get:
JSONObject jObj = new JSONObject(jString);
Object aObj = jObj.get("a");
if(aObj instanceof Integer){
System.out.println(aObj);
}

Related

Store different datatype in same variable at runtime

I am new to android development. I am facing difficulties to store different types of data in same variable.
Example :
I want to store integer value 1 or String value "one" or double value 1.0 to my variable at run time when user press button. but Here I don't see any datatype for this. If I declare variable as String the I can't store integer value. If I declare variable as integer the I can't store String value.
Thanks in advance.
You can declare your variable of type Object
Object val;
val = Integer.valueOf(12);
val = Double.parseDouble("12")
val = String.valueOf("12");
Later to read the content of val you will have to test is type, or example using instanceof and cast it into the desired type...
Object val = Integer.valueOf(12);
if(val instanceof Integer){
Integer i = (Integer)val;
int iVal = i.intValue();
}else if(val instanceof Double){
//...
}else if (val instanceof String){
//...
}//...

Trying to read Integer from JSON file in java

I am trying to read a JSON file to create a new Object. I can read all the Strings in it but i throws a ClassCastException when trying to read an int. Here is the JSON file.
{"id1" : "string1",
"id2": "string2",
"id3": 100.0
}
And here is the java code.
public static Aparelho novoAparelho(JSONObject obj) {
Aparelho ap = null;
String tipe = (String) obj.get("id1");
String name = (String) obj.get("id2");
if(tipe.equals("anyString")) {
int pot = (int) obj.get("id3");
ap = new SomeObject(name, pot);
}
return ap;
}
It throws.
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
Cast it to double first:
int pot = (int) (double) obj.get("id3");
ap = new SomeObject(name, pot);
Confusingly, there are three kinds of casts:
Those that convert values of primitives
Those that change the type of a reference
Those that box and unbox
In this case, you have an Object (which is actually a boxed Double), and you want a primitive int. You can't unbox and convert with the same cast, so we need two casts: first from Object to double (unboxing), and one from double to int (conversion).
Integers don't have decimal points.
You should be parsing for an int instead of casting as an int.
For example:
if (tipe.equals("anyString")) {
String pot = obj.get("id3");
int x = Integer.parseInt(pot);
ap = new SomeObject(name, x);
}
Since you know that the field is supposed to be an int, you can take advantage of the JSONObject api to handle the parsing for you:
if(tipe.equals("anyString")) {
int pot = obj.getInt("id3");
ap = new SomeObject(name, pot);
}
This is a bit more robust than the casting method -- if somebody changes the json that gets passed to you, the accepted answer might break.

Object Autoconvert to Double with Serialization/GSON

I ran into a problem when developing an application that uses Gson to serialize objects and deserialize them. However, I ran into a problem that I cannot explain the cause of and after a while, I narrowed down the problem to this SSCCE:
import com.google.gson.Gson;
/**
* demonstrates the issue at hand
*/
public class Probs {
public Probs () {
//holds the byte array form of the JSON data
byte[] info = new byte[1];
//get the JSON for a data object and store it in the byte array
Gson gson = new Gson();
Data before = new Data(1);
info = gson.toJson(before).getBytes();
//reassemble the JSON data as a string
String json = new String(info);
System.out.println("JSON string: " + json);
//reconstruct the Data object from the JSON data
Data after = gson.fromJson(json, Data.class);
//attempt to get the "num" value and convert it to an integer
Object val = after.getNum();
System.out.println("Class name: " + val.getClass().getName()); //is java.lang.Double (why isn't it java.lang.Object?)
Integer num = (Integer)val; //produces "java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer"
System.out.println("Number: " + num);
}
public static void main(String[] args) {
new Probs();
}
}
/**
* holds the one piece of data
*/
class Data {
Object num;
public Data(int num) {
this.num = num;
System.out.println("Object value: " + this.num);
}
public Object getNum () {
return this.num;
}
}
I did read this post but it did not appear to have any accepted answers. Because of the way I use it in my application, I need to have the Data object store its data as an Object and be able to cast it later to a different type. When I deserialize the data object and call its getNum(), I thought that should return an Object (since that is its return type). In my application, I need to be able to convert that type into an Integer. However, the JVM appears to convert the Object (val) into a Double because the getClass() reveals that it is a Double and not an Object. Then when I try to convert it to an integer via a cast it fails because it is apparently a Double and not an Object.
My question is: why is val a Double and not an Object (what am I not understanding)?
Thank you for your help
The issue is the JSON spec, and what you're doing.
The JSON spec only specifies a single numeric type, which can a include a decimal point and a fractional portion:
2.4. Numbers
The representation of numbers is similar to that used in most
programming languages. A number contains an integer component that
may be prefixed with an optional minus sign, which may be followed by
a fraction part and/or an exponent part.
JSON parsers are left to decide for themselves what to do with that numeric type when parsing/mapping the JSON.
In your case, your Data class has num defined as Object. This gives Gson no hint as to what specific Java numeric type you'd like the JSON numeric type mapped to. The authors of Gson decided to use a Double when this is the case regardless of whether the number in the JSON includes a decimal + fraction or not.
This actually makes perfect sense when you consider that an integer can be expressed as a double, but not the other way around. Using a single type rather than parsing the number and deciding if it's a int or a double provides consistent behavior.
It's unclear why you aren't using Integer (or int) for num in your Data object if that's what you expect/need. You state you need to cast to Integer "later" which means the only thing that object can be in the first place is an Integer; any other casting attempt would fail.

Regarding casting of the outcome

I have a method which return type is string below is the method
public String getHwIdentifier();
Now I am using this method ..
String s = till.getHwIdentifier();//return type of this method is string
I want to cast it in integer that is something like this
Int i = till.getHwIdentifier();
Please advise how take integer means how to cast it..
try parseInt from Integer class.
Integer.parseInt(till.getHwIdentifier());
but mind you, it'd throw NumberFormatException if the string is not a valid integer representation
Use parseInt(String s) method of Integer class which takes String and converts it to intif it is a number or throws NumberFormatException like this :
int i = Integer.parseInt(till.getHwIdentifier());
Pass the instance of the String to Integer.valueOf(String s).
So in your case:
Integer i = Integer.valueOf(till.getHwIdentifier);
See http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html#valueOf%28java.lang.String%29 for more details.
There is no Java type/class named Int. There's int type and it's encapsulating Integer class.
You can parse an integer in a String to the int value with Integer.parseInt("1234");, or get the Integer value with Integer.valueOf("1234");. But notice if the String doesn't represent an integer you'll get a NumberFormatException.
String s = till.getHwIdentifier();//return type of this method is string;
try
{
Integer a = Integer.valueOf(s);
int b = Integer.parseInt(s);
}
catch (NumberFormatException e)
{
//...
}
Note: You could use Integer a = Integer.decode(s);, but Integer c = Integer.valueOf(s); is preferred as it won't create new objects if possible.
String s = till.getHwIdentifier();
int i = Integer.parseInt(s);
Make sure that your string is in the form of an integer. If your string contains xyz then you will get a java.lang.NumberFormatException.

Java Object Conversion to Integer and String wrapper

I have a java.lang.Object return type from a function. I want to verify whatever Object value returned is of numeric type (double or long or int or byte or Double or Long or Byte or Float or Double ....) and if it's true want to convert into a Integer wrapper reference type. Also if the Object instance holds a String value I want it to be stored in a String reference.
Have a Object return type from a function. I want to verify whatever Object value returned is of numeric type(double or long or int or byte or Double or Long or Byte or Float or Double ....)
if (obj instanceof Number)
...
if it's true want to convert into a Integer wrapper reference type
if ...
val = (Integer) ((Number) obj).intValue();
Also If the Object instance holds a String value i want it to be stored in a String reference.
...
else if (obj instanceof String)
val = obj;
A method that returns Object cannot return primitive types like double, long, or int.
You can check for the actual returned type using instanceof:
if (object instanceof Number){
// want to convert into a Integer wrapper reference type
object = ((Number)object).intValue(); // might lose precision
}
You can assign to a String variable by type-casting
if (object instanceof String){
stringVariable = (String)object;
}
Although you probably have a serious design problem, in order to achieve what you want you can use instanceof operator or getClass() method:
Object o = myFunction();
if(o instanceof Integer) { //or if o.getClass() == Integer.class if you want
only objects of that specific class, not the superclasses
Integer integer = (Integer) o;
int i = integer.intValue();
}
//do your job with the integer
if(o instanceof String)
//String job
You can do something like :
Object obj = getProcessedObject();
if(obj instanceof Number) {
// convert into a Integer wrapper reference type
Integer ref1 = ((Number)obj).intValue();
}
if(obj instanceof String) {
// process object for String
String ref = (String)obj;
}

Categories