Java 8 Optional: combine two possibly null object - java

I have to ensure if two values are non null. When the first and second have non null values, pass first as argument to second. If one of them are null value, then return false.
This can be done in the following piece of code:
String value1 = function_to_get_value1()
if (value1 == null) return false;
String value2 = function_to_get_value2(value1)
if (value2 == null) return false;
return true;
It can also be done in short form:
try {
return function_to_get_value2(function_to_get_value1()) != null;
} catch (NullPointerException e) {
return false;
}
I was wondering how to do this in fluent form with Optional.

You could try something like this:
return Optional.ofNullable(function_to_get_value1())
.map(v1 -> function_to_get_value2(v1))
.isPresent();
map() applies the lambda if value is present and returns a new Optional.ofNullable() or otherwise returns an empty Optional. So in the end you have an empty Optional if either value was null or a non-empty one.
If you have a look at the source code for those methods, it basically is equivalent to this:
//Optional.ofNullable(...)
Optional<UiObject> v1Opt = value1 == null ? Optional.empty() : Optional.of(value1);
//Optional.map(...)
Optional<UiObject> v2Opt;
if(v1Opt.isPresent()) {
//this is the lambda
UiObject value2 = function_to_get_value2(value1);
//Optional.ofNullable(...) called in map(...)
v2Opt = value2 == null ? Optional.empty() : Optional.of(value2);
} else {
v2Opt = Optional.empty();
}
//Optional.isPresent()
return v2Opt.value != null;

Related

Choosing non null attributes

I have an object with 3 attributes, where only one can be not null. I would like to call a methode with the argument that is not null but if possible without a large if else statement.
I thought of something like this, but it doesn't work.
myMethode(myObj.getAttr1() || myObj.getAttr2() || myObj.getAttr3());
What would be a good solution?
One option is to stream the attributes and filter the first (presumably, only) non-null one:
myMethod(Stream.of(myObj.getAttr1(), myObj.getAttr2(), myObj.getAttr3())
.filter(Objects::notNull)
.findFirst()
.orElse(null) // Or perhaps throw an exception?
);
|| is a logical or operator and can be used only between two boolean types, which is why your code doesn't work.
myMethode(myObj.getAttr1() != null ? myObj.getAttr1() :
myObj.getAttr2() != null ? myObj.getAttr2() :
myObj.getAttr3() != null ? myObj.getAttr3() : null);
if your object only 3 attributes , you can use reflection like below
final long notNullAttributeCount = Arrays.stream(myObj.getClass().getFields())
.map(f -> {
try {
f.setAccessible(true);
return f.get(myObj);
} catch (IllegalAccessException e) {
return null;
}
}).filter(Objects::nonNull).count();
if (notNullAttributeCount == 1) {
//do your staff
}

How to turn null into false in Java?

In my code I have a org.apache.tapestry5.json.JSONObject named j.
I want to read the property use-name from that Object:
Boolean isUseName = (Boolean) j.opt("use-name");
The value can either be true, false or null (if the entry is not present in the JSONObject). Now I'd like to use isUseName for a conditional statement:
if(!isUseName) {System.out.println("No Name to be used.")}
This gives me a NullPointerException if "use-name" was not in the JSONObject. One way is to simply check first if isUseName is null, e.g.
if(isUseName != null && !isUseName) {System.out.println("No Name to be used.")}
I was wondering, if there is a more elegant way. Is it e.g. possible to (automatically) set isUseName to false, if j.opt() returns null? One thing that came to my mind is using a ternary expression, but this has a redundant j.opt("use-name"):
Boolean isUseName = (j.opt("use-name") != null)
? (Boolean) j.opt("use-name")
: false;
You could compare with Boolean.TRUE:
boolean useName = Boolean.TRUE.equals (j.opt ("use-name"));
Logical expressions short-circuit, so if you check null first, then you can use it after the check:
if(isUseName != null && !isUseName) {
// It's not null, and false
System.out.println("No Name to be used.");
}
or
if(isUseName == null || !isUseName) {
// It's null or false
System.out.println("No Name to be used.");
}
and similarly
if(isUseName != null && isUseName) {
// It's not null, and true
}
and
if(isUseName == null || isUseName) {
// It's either null or true
}
How about check if the key exists
boolean useName = j.has("use-name") ? j.getBoolean("use-name") : false;

May I get Null pointer exception from this routine?

I have written a below routine in Java, I need to know that the code is Null Pointer Safe or not:
public class TRM_Fields {
public static String returnActualValue(String Staffing_Event,
String CurrentValue, String PriorValue) {
String returnValue;
returnValue = null;
if ("TRM".equalsIgnoreCase(Staffing_Event) && CurrentValue == null
&& PriorValue != null && !"".equalsIgnoreCase(PriorValue)) {
returnValue = PriorValue;
} else {
returnValue = CurrentValue;
}
return returnValue;
}
}
Any of the parameter Staffing_Event, CurrentValue and PriorValue may be null.
If it is not Null Pointer Safe what should I do to achieve that?
Your method is safe. You are correctly using "constantString".equals(someObject) to ensure a null-safe comparison.
Some other comments:
Your method is hard to read because you are using TitleCase for Java variables, when they should be camelCase.
You only have two possible return values. So you can simplify your method as follows:
public static String returnActualValue(String staffingEvent,
String currentValue, String priorValue) {
if ("TRM".equalsIgnoreCase(staffingEvent) && currentValue == null
&& priorValue != null && !"".equalsIgnoreCase(priorValue)) {
return priorValue;
} else {
return currentValue;
}
}
Note that the else construct isn't necessary, so it's a matter of style whether you include that structure or simply have return currentValue;.

How to handle a method where the parameter is tightly connected to the return value. What if the parameter is null? Java

I'm writing a method that should return the first item in an array belonging to a certain user. The class looks like this:
public MailItem getNextMailItem(String who)
{
return mailbox.get(who).pollFirst();
}
I need some sort of error handling in case the "who"-parameter is empty or null e.g
if (who != null && who.length() != 0)
But what if that turns out to be false?
your if block is something like that
public MailItem getNextMailItem(String who) {
MailItem item = null;
if (who != null && who.length() != 0) {
item = mailbox.get(who).pollFirst();
} else {
//show some error message or error log here
}
return item;
}
on filure your method will return null.
also read this Q&A
Returning null in the absence of a value would be an obvious solution:
public MailItem getNextMailItem(String who){
MailItem mailItem = null;
if (who != null && who.length() != 0){
mailItem = mailbox.get(who).pollFirst();
}
return mailItem;
}
But consider this:
If you communicate with null, your return value really is ambiguous. It can mean a lot of things. Instead, you could use Guava's Optional or the Null object pattern.
Using the Null pattern, you would define an instance that has a neutral behavior, possibly in your MailItem interface, and return it in case of the absence of a value:
public MailItem getNextMailItem(String who) {
MailItem mailItem = null;
if (who != null && who.length() != 0){
mailbox.get(who).pollFirst();
} else {
mailItem = MailItem.NULL_ITEM;
}
return mailItem;
}
This way - unless an unexpected exception happens - you can always be sure that getNextMailItem returns a valid instance of MailItem.
Simple solution is to return null. On the other side, check for null and handle accordingly.

Refactor code with return statements

The "if" blocks with checkcustomers are exactly used in other methods in this class, so there is a lot of code dublication for same checks. But I cant also directly extract this checksomethings to one single method because they have return values.
Some good ideas to refactor this code? I just modified this code to simplify here, so dont get caught on minor issues in this code(if any), Basically question is how to a extract a piece of code to a method(because it is dublicated on other methods) when there are many returns in that current method.
public Details getCustomerDetails(){
if(checkifcustomerhasnoboobs){
..worry about it..
return new Details("no");
}
if(checkifcustomerplaytenniswell){
..do find a tennis teacher
return new Details("no cantplay");
}
//...ok now if customer passed the test, now do the some real stuff
//
//
CustomerDetails details= getCustomerDetailsFromSomewhere();
return details;
}
How about this?
public Result checkSomethings() {
if ( checksomething1 ) {
return ResultCheckSomething1;
}
if ( checksomething2 ) {
return ResultCheckSomething2;
}
return ResultCheckNone;
}
public Details getCustomerDetails(){
Result result = checkSomethings();
switch ( result ) {
case ResultCheckSomething1:
return new Details("message1");
case ResultCheckSomething2:
return new Details("message2");
default:
return getCustomerDetailsFromSomewhere();
}
}
The Result... codes would be in an enum.
Maybe something like this?
public Details getCustomerDetails(){
boolean isError = checksomething1() || checksomething2();
String message = checksomething1() ? "message1" : "message2";
return isError ? new Details(message) : getCustomerDetailsFromSomewhere();
}
If you try to avoid call check functions twice just keep it results
public Details getCustomerDetails(){
boolean check1 = checksomething1();
boolean check2 = checksomething2();
String message = check1 ? "message1" : "message2";
return (check1 || check2) ? new Details(message) : getCustomerDetailsFromSomewhere();
}
Replace the returns with assignments to a result variable that remains null until the first assignment to it. Each block could be replaced by a function that returns null if its condition for changing the result is false.
As pointed out in a comment by herman, this only works if null is not a possible result of one of calls.
public Details getCustomerDetails(){
Details result = null;
if(checksomething1){
..error
result = new Details("message1");
}
if(result == null) {
if(checksomething2){
..error
result = new Details("message2");
}
if(result == null){
result = getCustomerDetailsFromSomewhere();
}
return result;
}
I would do this:
public Details getCustomerDetails(){
Details invalidDetails = checkForInvalidCustomer();
if (invalidDetails !=null) {
return (invalidDetails);
}
//...ok now if customer passed the test, now do the some real stuff
//
//
CustomerDetails details= getCustomerDetailsFromSomewhere();
return details;
}
public Details checkForInvalidCustomer() {
if(checkifcustomerhasnoboobs){
..worry about it..
return new Details("no");
}
if(checkifcustomerplaytenniswell){
..do find a tennis teacher
return new Details("no cantplay");
}
// nulls means valid customer
return (null);
}
Basically, for your specific example, I'm using null so that I can differentiate the case where none of the conditions matched, vs either condition matched. That way I can use a single if statement. Now, if you wanted to return null, you would need to modify this solution slightly, perhaps use some constant for flagging the case instead of using null.
Using Java 8, you can refactor into a method that returns an Optional<...> value.
Statements like return x; would be replaced by return Optional.of(x) (assuming x cannot be null). The default return statement at the end would be return Optional.empty().
Then you can use return optional.orElseGet(() -> ...)) to compute the value for the case where none of the original return statements would be reached.

Categories

Resources