2

Anyone heard for a json library supporting java8 Optionals when returning values?
Lets say I have the following json documents:

{
  "person" : {
    "address" : {
       "streetName" : "Moonshtrasse",
       "streetNo" : 12
     }
  }
}

and an empty document

{}

Assuming the get methods in the JSONObject return Optionals, I want to do something like this:

Optional<String> streetName = obj.getJSONObject("person")
    .flatMap(person -> person.getJSONObject("address"))
    .flatMap(adr -> adr.getString("streetName"));

Instead of checking for null values after every get method.

In the first case this construct would give me an Optional containing the street name and in the second case would give me an empty Optional.

George
  • 7,206
  • 8
  • 33
  • 42
  • No it is not actually – George Nov 25 '15 at 10:38
  • the other thread relates to serialization of JSON and the accepted answer is that there is a version of Jackson that will do the needful.... so this question appears to be answered by that thread. There is a further thread on this topic here: http://stackoverflow.com/questions/24547673/why-java-util-optional-is-not-serializable-how-to-serialize-the-object-with-suc – robjwilkins Nov 25 '15 at 10:42
  • 2
    Use `Optional.ofNullable`. – a better oliver Nov 25 '15 at 10:49

2 Answers2

2

Regarding the comment from @zeroflagL, his approach would be applicable if we had methods which return null values when the desired element does not exist.
One such library is org.json
There are opt methods which return null when there are no values. So we can employ the Optional as:

    JSONObject obj = new JSONObject(someJsonString);

    Optional<String> streetName = Optional.ofNullable(obj.optJSONObject("person"))
        .flatMap(person -> Optional.ofNullable(person.optJSONObject("address")))
        .flatMap(address -> Optional.ofNullable(address.optString("streetName")));

That would give us the required result.

George
  • 7,206
  • 8
  • 33
  • 42
2

According to the documentation for Optional::map,

If the mapping function returns a null result then this method returns an empty Optional.

Thus, we could just call the null-returning methods as-is within the lambdas passed through Optional::map, in lieu of flatMapping the Optional-ized results of said null-returning methods,

JSONObject obj = new JSONObject(someJsonString);

Optional<String> streetName = Optional.ofNullable(obj.optJSONObject("person"))
    .map(person -> person.optJSONObject("address"))
    .map(address -> address.optString("streetName"))
;
srborlongan
  • 4,460
  • 4
  • 26
  • 33