Using Java 8 Optional with JSONObject? - java-8

GIVEN:
JSONObject o = <populated from json source>;
if (o.has("stuff") && response.getJSONObject("stuff").has("stuffList")
&& o.getJSONObject("stuff").getJSONArray("stuffList").size() > 0) {
doStuff()
}
ASK:
How can I rewrite the above using java.util.Optional so that I don't have to make all those JSONObject checks?
Something like:
java.util.Optional<JSONObject> _O = java.util.Optional.ofNullable(o);
java.util.Optional<Integer> size = _response.map(JSONObject::getJSONObject("stuffList")...<etc>???;
if (size.IsPresent && size > 0) { doStuff(); }

It is not refactorable in a nicely way to Optionals in this case.
Why?
getJSONObject() method will never return null. If there is no value associated with provided key, it will throw JSONException. Optional monad was designed for handling nulls and not exceptions. Those checks are necessary in this case.
However, for educational purposes, let's assume that if there is no value stored under a specified key, method would return null.
You could refactor it like this:
Optional.ofNullable(response.getJSONObject("stuff"))
.map(stuff -> stuff.getJSONArray("stuffList"))
.filter(array -> array.length() > 0)
.ifPresent((array) -> doStuff(array)); // replaceable with a method reference

Related

Using Optionals and forEach in Java 8, check for empty object

I would like to use Optionals with forEach in my example below, and am not sure about the correct approach.
Basically the functionality is as follows:
List<Long> myList;
List<Long> myResultList;
myList = getValues_A();
if (null != myList && !myList.isEmpty())
return;
for (Long singleVal : myList) {
List<Long> tempList = getValues_B(singleVal);
if (null != tempList && !tempList.isEmpty())
myResultList.addAll(tempList);
}
So I simple retrieve some data into myList, check if there is some value returned, and if so, I use the result to again retrieve data and put it in a final result list.
My idea with Optionals:
List<Long> myList;
List<Long> myResultList;
myList = getValues_A();
if (null != myList && !myList.isEmpty())
return;
myResult.forEach(itemToCheck -> Optional
.ofNullable(getValues_B(itemToCheck))
.ifPresent(myResultList::addAll));
Questions:
The first part:
myList = getValues_A();
if (null != myList && !myList.isEmpty())
return;
Is there any way to use Java 8 Optionals instead?
I.e.
myList = getValues_A();
if (!Optional.ofNullable(myList).isPresent())
return;
But this would only check for null and not if the object was empty (for which I also want to return). Can this be extended with a size check of the object within the Stream?
Also, misusing Optional's isPresent as a nullcheck only is bad coding practise I guess. Any other ideas?
The second part:
I assume that even empty objects will be attempted to be added to myResultList? Can this be somehow prevented in a similar approach, i.e. check if size = 0 within the stream?
myResult.forEach(itemToCheck -> Optional
.ofNullable(getValues_B(itemToCheck))
.ifPresent(myResultList::addAll));
Small sidenote: I can't use isEmpty(Object object) of org.apache.commons.lang3.ObjectUtils as I'm with version < 3.9.
I also think it is worth mentioning that besides whole reusing Optional is not good thing in any possible case(with which I agree). We also see in this approach that we create empty list and then altering its state by adding new elements. I thing if we can we should always avoid such solutions. Much cleaner approach is to instantiate list with its elements while declaring.
For getting rid of first part, you can make the getValues_A() function to return an Optional or an empty list instead of null.It make no sense to make any processing with Optional in this method.
Second part written with stream :
List<Long> myResultList = myList.stream().map(singleVal -> getValues_B(singleVal)).filter(Objects::nonNull).flatMap(List::stream).collect(Collectors.toList());
Each steps explained:
1. map(singleVal -> getValues_B(singleVal)) - each element of the list will be processed and you'll get a List as result for each.
2. filter(Objects::nonNull) - remove empty lists
3. flatMap(List::stream) - from stream of List<Long>,you'll obtain a stream of Long
4. collect(Collectors.toList()) - collect all resultList.
You may take advantage of the orELseGet() API of the Optional and the map/flatmap APIs of the stream to simplify your code.
List<Long> resultList = Optional.ofNullable(getValues_A())
.orElseGet(Collections::emptyList)
.stream()
.filter(Objects::nonNull)
.flatMap(l -> Optional.ofNullable(getValues_B(l))
.orElseGet(Collections::emptyList)
.stream()
.filter(Objects::nonNull))
.collect(Collectors.toList());

How do I avoid returning a null value while avoiding mutation?

I am trying to create a method that will take a list of items with set weights and choose 1 at random. My solution was to use a Hashmap that will use Integer as a weight to randomly select 1 of the Keys from the Hashmap. The keys of the HashMap can be a mix of Object types and I want to return 1 of the selected keys.
However, I would like to avoid returning a null value on top of avoiding mutation. Yes, I know this is Java, but there are more elegant ways to write Java and hoping to solve this problem as it stands.
public <T> T getRandomValue(HashMap<?, Integer> VALUES) {
final int SIZE = VALUES.values().stream().reduce(0, (a, b) -> a + b);
final int RAND_SELECTION = ThreadLocalRandom.current().nextInt(SIZE) + 1;
int currentWeightSum = 0;
for (Map.Entry<?, Integer> entry : VALUES.entrySet()) {
if (RAND_SELECTION > currentWeightSum && RAND_SELECTION <= (currentWeightSum + entry.getValue())) {
return (T) entry.getKey();
} else {
currentWeightSum += entry.getValue();
}
}
return null;
}
Since the code after the loop should never be reached under normal circumstances, you should indeed not write something like return null at this point, but rather throw an exception, so that irregular conditions can be spotted right at this point, instead of forcing the caller to eventually debug a NullPointerException, perhaps occurring at an entirely different place.
public static <T> T getRandomValue(Map<T, Integer> values) {
if(values.isEmpty())
throw new NoSuchElementException();
final int totalSize = values.values().stream().mapToInt(Integer::intValue).sum();
if(totalSize<=0)
throw new IllegalArgumentException("sum of weights is "+totalSize);
final int threshold = ThreadLocalRandom.current().nextInt(totalSize) + 1;
int currentWeightSum = 0;
for (Map.Entry<T, Integer> entry : values.entrySet()) {
currentWeightSum += entry.getValue();
if(threshold <= currentWeightSum) {
return entry.getKey();
}
}
// if we reach this point, the map's content must have been changed in-between
throw new ConcurrentModificationException();
}
Note that the code fixes some other issues of your code. You should not promise to return an arbitrary T without knowing the actual type of the map. If the map contains objects of different type as key, i.e. is a Map<Object,Integer>, the caller can’t expect to get anything more specific than Object. Besides that, you should not insist of the parameter to be a HashMap when any Map is sufficient. Further, I changed the variable names to adhere to Java’s naming convention and simplified the loop’s body.
If you want to support empty maps as legal input, changing the return type to Optional<T> would be the best solution, returning an empty optional for empty maps and an optional containing the value otherwise (this would disallow null keys). Still, the supposed-to-be-unreachable code point after the loop should be flagged with an exception.

Convert for loop into Java 8 Stream

I need to convert these code into Java 8 Stream I tried it using the given below code written by me but still I haven't got what I wanted.
//contractList is list of Contract class
//contract.getProgramId() returns String
//contract.getEnrollmentID() returns String
//'usage = CommonUtils.getUsageType()' is other service to call wich returns String
//enroll and usage are String type
//enrollNoWithUsageTypeJson is json object '{"enroll": value, "usage": value}'
//usages is List<JSONObject> where enrollNoWithUsageTypeJson need to add
for (Contract contract : contractList) {
if (!StringUtils.isEmpty(contract.getProgramId())) {
enroll = contract.getEnrollmentID();
usage = CommonUtils.getUsageType(envProperty, contract.getProgramId());
if (!(StringUtils.isEmpty(enroll) || StringUtils.isEmpty(usage))) {
enrollNoWithUsageTypeJson.put("enroll", enroll);
enrollNoWithUsageTypeJson.put("usage", usage);
usages.add(enrollNoWithUsageTypeJson);
}
}
}
This is till now what I have got:
contractList.stream()
.filter(contract -> !StringUtils.isEmpty(contract) &&
!StringUtils.isEmpty(contract.getProgramId()))
.collect(Collectors.to);
Thakyou in advance :)
Here is how a stream based version of your code might look like (add static imports as needed):
List<JSONObject> usages = contractList.stream()
.filter(c -> isNotEmpty(c.getProgramId()))
.map(c -> new SimpleEntry<>(c.getEnrollmentID(), getUsageType(envProperty, c.getProgramId())))
.filter(e -> isNotEmpty(e.getKey()) && isNotEmpty(e.getValue())))
.map(e -> {
enrollNoWithUsageTypeJson.put("enroll", e.getKey());
enrollNoWithUsageTypeJson.put("usage", e.getValue());
return enrollNoWithUsageTypeJson; })
.collect(toList());
I took the liberty of using isNotEmpty from Apache Commons as given this option !isEmpty looks terrible. I am (ab)using AbstractMap.SimpleEntry to hold a pair of values. If you feel getKey, getValue make the code less readable, you can introduce a class to hold these 2 variables. E.g.:
class EnrollUsage {
String enroll, usage;
}
You may also prefer to define a method:
JSONObject withEnrollAndUsage(JSONObject json, String enroll, String usage) {
json.put("enroll", enroll);
json.put("usage", usage);
return json;
}
and in the above use instead:
.map(e -> withEnrollAndUsage(enrollNoWithUsageTypeJson, e.getKey(), e.getValue()))
Keep in mind that you never really "need" to convert code to use streams. There are cases where using streams, albeit intellectually satisfying, actually complicates your code. Exercise your best judgement in this case.

How to replace lambda written in Where clause of Linq with equivalent delegate

I have an Query expression that uses a predicate type and lambda expression.
I am getting desired result with this. But I am not clear with how this expression is getting evaluated.
I tried to break this lambda expression by creating delegate and replacing condition under Where with delegate type.
If I have to rewrite the same thing with writing a delegate instead of anonymous type. What will be the syntax. How the delegate will be return for the same.
if (((DataTable)dgvAssignedRpm.DataSource).AsEnumerable()
.Where(row => row.Field<long>("FK_RPM_BTN_SETTING_ID") == objRpmButtonHolder.RpmSettingId).Count() > 1)
{
List<DataRow> listPkgBtnSettings = SearchForExistingSettingId();
}
void MethodSignature(...)
{
...
if (((DataTable)dgvAssignedRpm.DataSource).AsEnumerable()
.Where(RowCondition)
{
List<DataRow> listPkgBtnSettings = SearchForExistingSettingId();
}
...
}
// Where want a Func<T,bool> parameter
// T is the first parameter type (DataRow here)
// bool represents the return value
bool RowCondition(DataRow row)
{
return row.Field<long>("FK_RPM_BTN_SETTING_ID") == objRpmButtonHolder.RpmSettingId).Count() > 1
}
I assume the correct delegate replacement would be:
if (((DataTable)dgvAssignedRpm.DataSource).AsEnumerable().Where(
delegate(DataRow row) {
return (row.Field<long>("FK_RPM_BTN_SETTING_ID") == objRpmButtonHolder.RpmSettingId.Count() > 1);
}))
{
List<DataRow> listPkgBtnSettings = SearchForExistingSettingId();
}
But it's morning for me, so forgive me if I'm a bit off.
What the where desires is to give a DataRow as a parameter and a bool to return. You could just about fill in anything in the lambda or delegate, as long as it matches these requests.
To your question why it requests Func<> and how it works. The statement you're using is LINQ, so I found you a reference regarding this which can probably explain it better than me:
http://blogs.msdn.com/b/mirceat/archive/2008/03/13/linq-framework-design-guidelines.aspx
But yeah, the last type here in the Func<> is what it returns. (However, I can still recommend using the Lambda expression, as it's pretty clean, neat and serves the Func<> best.
(Also, look at what intellisence gives you when you write "new Func<....", it should give you a good idea of what Func wants and can do!)
Hope I was of help.

What are nested functions? What are they for?

I've never used nested functions, but have seen references to them in several languages (as well as nested classes, which I assume are related).
What is a nested function?
Why?!?
What can you do with a nested function that you cannot do any other way?
What can you do with a nested function this is difficult or inelegant without nested functions?
I assume nested functions are simply an artifact of treating everything as an object, and if objects can contain other objects then it follows.
Do nested functions have scope (in general, I suppose languages differ on this) just as variables inside a function have scope?
Please add the language you are referencing if you're not certain that your answer is language agnostic.
-Adam
One popular use of nested functions is closures. In a lexically scoped language with first-class functions it's possible to use functions to store data. A simple example in Scheme is a counter:
(define (make-counter)
(let ((count 0)) ; used to store the count
(define (counter) ; this is the counter we're creating
(set! count (+ count 1)) ; increment the count
count) ; return the new count
counter)) ; return the new counter function
(define mycounter (make-counter)) ; create a counter called mycounter
(mycounter) ; returns 1
(mycounter) ; returns 2
In this example, we nest the function counter inside the function make-counter, and by returning this internal function we are able to access the data available to counter when it was defined. This information is private to this instance of mycounter - if we were to create another counter, it would use a different spot to store the internal count. Continuing from the previous example:
(define mycounter2 (make-counter))
(mycounter2) ; returns 1
(mycounter) ; returns 3
It's useful for recursion when there is only 1 method that will ever call it
string[] GetFiles(string path)
{
void NestedGetFiles(string path, List<string> result)
{
result.AddRange( files in the current path);
foreach(string subPath in FoldersInTheCurrentPath)
NestedGetFiles(subPath, result);
}
List<string> result = new List<string>();
NestedGetFiles(path, result);
return result.ToArray();
}
The above code is completely made up but is based on C# to give the idea of what I mean. The only method that can call NestedGetFiles is the GetFiles method.
Nested functions allow you to encapsulate code that is only relevant to the inner workings of one function within that function, while still allowing you to separate that code out for readability or generalization. In some implementations, they also allow access to outer scope. In D:
int doStuff() {
int result;
void cleanUpReturn() {
myResource1.release();
myResource2.release();
return result * 2 + 1;
}
auto myResource1 = getSomeResource();
auto myResource2 = getSomeOtherResource();
if(someCondition) {
return cleanUpReturn();
} else {
doSomeOtherStuff();
return cleanUpReturn();
}
}
Of course, in this case this could also be handled with RAII, but it's just a simple example.
A nested function is simply a function defined within the body of another function. Why? About the only reason I could think of off the top of my head is a helper or utility function.
This is a contrived example but bear with me. Let's say you had a function that had to act on the results two queries and fill an object with values from one of the queries. You could do something like the following.
function process(qryResult q1, qryResult q2) {
object o;
if (q1.someprop == "useme") {
o.prop1 = q1.prop1;
o.prop2 = q1.prop2;
o.prop3 = q1.prop3;
} else if (q2.someprop == "useme") {
o.prop1 = q2.prop1;
o.prop2 = q2.prop2;
o.prop3 = q2.prop3;
}
return o;
}
If you had 20 properties, you're duplicating the code to set the object over and over leading to a huge function. You could add a simple nested function to do the copy of the properties from the query to the object. Like this:
function process(qryResult q1, qryResult q2) {
object o;
if (q1.someprop == "useme") {
fillObject(o,q1);
} else if (q2.someprop == "useme") {
fillObject(o,q2);
}
return o;
function fillObject(object o, qryResult q) {
o.prop1 = q.prop1;
o.prop2 = q.prop2;
o.prop3 = q.prop3;
}
}
It keeps things a little cleaner. Does it have to be a nested function? No, but you may want to do it this way if the process function is the only one that would have to do this copy.
(C#) :
I use that to simplify the Object Browser view, and to structure my classes better.
As class Wheel nested in Truck class.
Don't forget this detail :
"Nested types can access private and protected members of the containing type, including any inherited private or protected members."
They can also be useful if you need to pass a function to another function as an argument. They can also be useful for making factory functions for factory functions (in Python):
>>> def GetIntMaker(x):
... def GetInt():
... return x
... return GetInt
...
>>> GetInt = GetIntMaker(1)
>>> GetInt()
1
A nested function is just a function inside another function.
Yes, it is a result of everything being an object. Since you can have variables only visible in the function's scope and variables can point to functions you can have a function that is referenced by a local variable.
I don't think there is anything that you can do with a nested function that you absolutely couldn't do without. A lot of the times it makes sense, though. Namely, whenever a function is a "sub-function" of some other function.
A common use-case for me is when a function performs a lot of complicated logic but what the function computes/returns is easy to abstract for all the cases dictated by the logic.

Resources