import org.json.JSONObject;
String someStringJsonData = "{\"someKey\": " + "null" + "}";
JSONObject someJsonObjectData = new JSONObject(someStringJsonData);
Object someKey = someJsonObjectData.get("someKey");
if (null == someKey) {
System.out.println("someKey is null");
}
I have the above simple snippet of code. I would expect to see "someKey is null" printed, however, my code never goes in the if loop. I tried printing value of someKey and it shows to be null. Not sure what I am missing.
I tried different values of the jsonString from this post but to no avail.
Per its docs, the internal form of the value of a JSONObject can contain values of these types: Boolean, JSONArray, JSONObject, Number, String, or the JSONObject.NULL object. Therefore, I would not expect its get() method to return null for any key. In your particular case, I would expect someJsonObjectData.get("someKey") to return JSONObject.NULL, which will compare unequal to null.
JSONObject.NULL is a specific object, so it should be safe to perform == comparisons with it:
import org.json.JSONObject;
// ...
void doSomething() {
String someStringJsonData = "{\"someKey\": null}";
JSONObject someJsonObjectData = new JSONObject(someStringJsonData);
Object someValue = someJsonObjectData.get("someKey");
if (someValue == JSONObject.NULL) {
System.out.println("someKey's value is null");
}
}
I needed to do the check for
JSONObject.NULL and not null
https://developer.android.com/reference/org/json/JSONObject.html#NULL.
Printing the class of someKey helped. Thank you everyone for your time!!
Related
I am getting JSON from a server and then parsing the JSON using GSON. I want to determine if a string element from the JSON equals another string variable. However, String.equals() returns false when it should return true.
Java Code:
JsonElement element = parser.parse(response.toString());
if (element.isJsonObject()) {
JsonObject data = element.getAsJsonObject();
JsonArray stud = data.get("students").getAsJsonArray();
for(int i = 0; i < stud.size(); i ++){
String t = stud.get(i).getAsJsonObject().get("StudNum").toString();
System.out.println("t = " + t);
if (t.equals("F02660934")){
System.out.println("equal"); //never prints
}
}
}
Console output:
t = "F02660934"
t = "002660934"
t = "002643472"
t = "002664906"
Is it comparing "F02660934" to F02660934, therefore returning false?
Thanks in advance!
Your string contains quotes, so you need to include that in your if statement.
if (t.equals("\"F02660934\""))
System.out.println("equals");
Though you shouldn't be using toString() on a JsonElement. Use getAsString() instead.
For more info see GSON JsonElement.getAsString vs. JsonElement.toString?
#killjoy recommended this in the comments, but Java was comparing "F02660934" to F02660934, reading the quotation marks as part of the string. This can be solved one of two ways if using toString():
1). t.equals("\"F02660934\"") which causes t to ignore the quotation marks in equals()
2). t = t.replaceAll("\"", "") which strips the quotation marks from the string and replaces them with nothing so when equals() is called t is equivalent to F02660934
I have a hashmap of key and value both of String type.
Map<String, String> map = new HashMap<>();
//put the key-values now
I want to check for null or emptiness of the value of a particular key. Referencing the discussion here, I do it as:
if("".equals(map.get("keyName")) {
//do stuff
}
Is it valid?
As the return type of Map.get is Object, so do I need to check it like this:
if("".equals(map.get("keyName").toString()) {
//do stuff
}
But toString() gives null pointer exception if it is null. So, what is the right way to do it?
Yes, I'm a beginner.
You can do something like this-
String val = map.get("keyName");
if(val != null && !"".equals(val)){
// val is not null and is not empty
}
I would suggest you use StringUtils from Apache Commons:
if (!StringUtils.isEmpty(map.get("keyName")){
// Do something
}
See the JavaDoc: https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html#isEmpty%28java.lang.String%29
You can use like this -
if(map.get("keyName").equals(null) || map.get("keyName").equals("")){
//Failed to insert code
}
I am parsing input JSON. For a field, there are 3 possibilities:
the field is absent;
the value is set to null;
the value is set to something valid.
Different behavior is implemented: for an absent value in the JSON, the default value is inserted into the database; for a null value in the JSON, a null value is inserted into the database.
I thought about Optional to model this:
public class Data {
private Optional<String> field;
}
Which of the following two options make most sense?
If field is null, the field was absent in the JSON. If field is Optional.empty, the field is null in the JSON.
If field is null, the field was null in the JSON. If field is Optional.empty, the field is absent in the JSON.
FWIW, I am using Jackson with module jackson-datatype-jdk8 to parse the input JSON.
I think you shouldn't use Optional for this scenario. As #dkatzel has mentioned in his answer, it's meant to be used as an API return value more than as a field.
Despite this academic discussion, you can accomplish what you want simply by initializing fields in your Data class to their default values:
public class Data {
private String field = DEFAULT_VALUE;
}
And then let Jackson do the rest.
EDIT as per OP's comment:
When your JSON comes with a null value for the field, Jackson will set it to null, and that's what will be stored in the database.
When your JSON does not contain the field, the DEFAULT_VALUE will be automatically loaded in your Data instance.
And when your JSON does actually contain a value for the field, Jackson will set it, and that value will reach the database.
EDIT 2, considering OP's requirement to find out if the field was either filled in, set to null or was absent in the input JSON, after parsing the JSON input:
If, after parsing the input JSON, you need to know whether the field was either filled in, set to null or was absent, then consider this example, which shows the approach I'd take:
public class Data {
private String field1 = "hello";
private Integer field2 = 10;
private Double field3 = 3.75;
private static final Data DEFAULTS = new Data(); // defaults will be kept here
public String getField1() {
return this.field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public Integer getField2() {
return this.field2;
}
public void setField2(Integer field2) {
this.field2 = field2;
}
public Double getField3() {
return this.field3;
}
public void setField3(Double field3) {
this.field3 = field3;
}
#Override
public String toString() {
return "Data [field1=" + this.field1 +
", field2=" + this.field2 +
", field3=" + this.field3 + "]";
}
public boolean isDefault(Function<Data, Object> getter) {
Object defaultProperty = getter.apply(DEFAULTS);
Object actualProperty = getter.apply(this);
return defaultProperty != null // needed to support fields with no default value
&& defaultProperty.equals(actualProperty);
}
public boolean isNull(Function<Data, Object> getter) {
return getter.apply(this) == null;
}
public boolean isSet(Function<Data, Object> getter) {
return !this.isNull(getter) && !this.isDefault(getter);
}
}
Here I've used a private static attribute to hold your Data's default values and 3 methods to query any field state (default, null or set). In order to determine which field to query, these methods receive a Function<Data, Object>, which are given a Data instance and return an Object that is supposed to be the desired field. (If you stop to think it, getters can be seen as functions that take the instance as input and return a specific field of the instance).
So later, when you need to know how a certain field arrived in your JSON input, just use those 3 query methods to find out:
ObjectMapper m = new ObjectMapper();
String json = "{\"field1\":null,\"field2\":20}";
Data data = m.readValue(json, Data.class);
System.out.println(data); // Data [field1=null, field2=20, field3=3.75]
System.out.println("field1 default ? " + data.isDefault(Data::getField1)); // false
System.out.println("field1 null ? " + data.isNull(Data::getField1)); // true
System.out.println("field1 set ? " + data.isSet(Data::getField1)); // false
System.out.println("field2 default ? " + data.isDefault(Data::getField2)); // false
System.out.println("field2 null ? " + data.isNull(Data::getField2)); // false
System.out.println("field2 set ? " + data.isSet(Data::getField2)); // true
System.out.println("field3 default ? " + data.isDefault(Data::getField3)); // true
System.out.println("field3 null ? " + data.isNull(Data::getField3)); // false
System.out.println("field3 set ? " + data.isSet(Data::getField3)); // false
I would say that the first option makes the most semantic sense. It also potentially allows for easier computation.
Where a field in java is null, it is implied that a value is missing, which matches the first option.
I suggest that you store these fields in a hash-map where the key is the JSON field name and the value is the JSON field's value. I also suggest you don't use an optional here (as it can add an unnecessary layer of complexity), and instead use either a null or non-null object in the hashmap.
HashMap<String, Value> jsonFields = new HashMap<String, Value>();
boolean hasField1 = false;
Value field1Value = null;
if(jsonFields.contains("field1"){ // It is present in the JSON file
field1Value = jsonFields.get("field1"); // "null" here would mean that the JSON field was set to "null"
hasField1 = true;
}
The second choice makes more sense to me. null means null and empty means not present.
However, Optional shouldn't really be used as a field. It's supposed to be used as an API return value.
Could you instead store the data in a Map that allows null values? And if the key (your field) isn't present in the map, then return Optional.empty ?
Neither? I would annotate my POJO fields with #DefaultValue(). Then your possibilities are a null value or a non-null value specified in JSON, or the default if the field was omitted from JSON. And you can then just persist the POJO without any special per-field analysis.
If you are dealing with Object instead of String, here's a solution I find elegant:
use Optional.empty(); if there is no value
use Optional.of(value) if there is a value
use Optional.of(specialValue) if the value is null
where specialValue is a static singleton you can easily test, for instance: ObjectUtils.NULL (from commons.lang).
Then you can easily test your optional:
if (optional.isPresent()) {
if (ObjectUtils.NULL.equals(optional.get())) {
// value is there and null
} else {
// value is there and not null
}
} else {
// value is not there
}
In a ListResourceBundle implementation I define an array with some keys containing null values.
It compiles fine the loading process of the bundle containing a null value. However when I call getObject on a key with a non-null value (like in the following example "Pollution" which has value "high"), it gives me a NullPointerException.
Do you have an idea why it happens in that way?
ResourceBundle labels = ResourceBundle.getBundle("bundlething", new Locale("it"));
labels.getObject("Pollution");// here NullPointerException, However Pollution has a \n
value, other keys of the same array do not.
UPDATE:
This is the stacktrace I receive:
Exception in thread "main" java.lang.NullPointerException at
java.util.ListResourceBundle.loadLookup(ListResourceBundle.java:196)
at
java.util.ListResourceBundle.handleGetObject(ListResourceBundle.java:124)
at java.util.ResourceBundle.getObject(ResourceBundle.java:387) at
ResourceBundleThing.main(ResourceBundleThing.java:38)
and this is the bundle I load by passing new Locale("it") as target Locale:
import java.util.ListResourceBundle;
public class bundlething_it extends ListResourceBundle {
private Object [][] contents ={{"Inhabitants",null},{"Pollution",new Double(3.4034)},{"Lollerball",new Integer(132)}};
public Object[][] getContents()
{
return contents;
}
}
There is null corresponding to "Inhabitans" however I am referring only to "Pollution" which has a non-null value. Still I get a NullPointerException; If I remove that null from "Inhabitants" it works.. so it's there the problem, I know. However I would like to know why since I am not using that particular key-value pair.
Does it load all the values as soon as getObject it's called?
Thanks in advance.
The stack trace precisely indicates where the error comes from:
Object[][] contents = getContents();
HashMap<String,Object> temp = new HashMap<>(contents.length);
for (int i = 0; i < contents.length; ++i) {
// key must be non-null String, value must be non-null
String key = (String) contents[i][0];
Object value = contents[i][1];
if (key == null || value == null) {
throw new NullPointerException(); // <-- HERE
}
temp.put(key, value);
}
So, you have your answer: although I haven't seen it mentioned in the documentation, ListResourceBundle doesn't allow null values.
for (int lstSize = 0; lstSize < obj.size(); lstSize++) {
if (obj.get(lstSize).getCuffSize() == null) {
obj.get(lstSize).setCuffSize("");
}
}
I have an ArrayList, where there are many items which has a value of null, can i set values as empty string, if my items in my List Object holds null value.
For instance:
While looping i am getting cuffSize as null, so i am setting it to empty String. But there are such many items in my Object which needs to be set like this. Is there any better way where can i set all the items in my object holding null value to empty string?
An enhanced for would get rid of all the get() calls:
for (MyObj elem : obj) {
if (elem.getCuffSize() == null) {
elem.setCuffSize("");
}
}
In Java 8 you will be able to do this in a cleaner way using Lambdas, but in Java 7 I don't know of a better way than looping.
Rather than setting many properties from null to empty string later I think its better to initialize those properties inside your class itself to empty String like this:
public class MyClass {
private String cuffSize = ""; // init to empty String here
private String somethingElse = ""; // init to empty String here
...
}
Then even if you don't call setters of cuffSize it will contain an empty String instead of null.
I would suggest you add a method in the class of your object. which do the null->"" logic.
The method could return the object reference, so that you could do it during adding it into your list. something like:
public Obj null2empty(){
field1=field1==null?"":field1;
field2=field2==null?"":field2;
field3=field3==null?"":field3;
....
return this;
}
list.add(obj.null2empty());
also possible to do it in iteration:
for(Obj obj : list) obj.null2empty();
Or you can use iterator:
Iterator<MyObject> it = obj.iterator();
while(it.hasNext())
{
MyObject obj = it.next();
if(obj == null) { .. }
}
The implementation of getCuffSize() method can be below, so that your end objective is met
public String getCuffSize()
{
return (cuffSize == null) ? "" : cuffSize;
}