Due to rich profiling, our Java code is cluttered with outputs of method results of nullable objects.
It looks like this
namedObject == null ? "?" : namedObject.getName()
is it possible to write a static method for this? (e.g. looking like this):
Util.nvl( namedObject, NamedObject::getName, "?" )
What would = Util.nvl look like? I've experimented a bit an searched google but yielded no result.
This does not work:
public static <T> T nvl(T value, Function<T, ?> method, T nullSubstition) {
return value == null ? nullSubstition : (T) method.apply(value);
}
The compiler tells me: non-static method getName() cannot be referenced from a static context
Java 8 introduced an Optional class which is a nicer way to avoid NullPointerExceptions. You can use Optional to encapsulate the potential null values and pass or return it safely without worrying about the exception. Without Optional, when a method signature has return type of certain object.
Let's learn how to use Java 8's Optionals to make your null checks simple and less error-prone! The method orElse() is invoked with the condition "If X is null, populate X. Return X.", so that the default value can be set if the optional value is not present.
We can use lambda expression str -> str!= null inside stream filter() to filter out null values from a stream.
The isEmpty() method of List interface in java is used to check if a list is empty or not. It returns true if the list contains no elements otherwise it returns false if the list contains any element.
Your signature can't be correct. You want your method to take the NamedObject as first argument (so T is a NamedObject), and to return a String (so now T is String).
You need two generic type parameters:
public class Utils {
public static <O, T> T nvl(O value, Function<O, T> method, T nullSubstition) {
return value == null ? nullSubstition : method.apply(value);
}
static class NamedObject {
String getName() {
return "foo";
}
}
public static void main(String[] args) {
NamedObject foo = null;
String name = Utils.nvl(foo, NamedObject::getName, "bar");
System.out.println("name = " + name); // name = bar
foo = new NamedObject();
name = Utils.nvl(foo, NamedObject::getName, "bar");
System.out.println("name = " + name); // name = foo
}
}
An even better signature, allowing more flexibility, would be
public static <O, T> T nvl(O value, Function<? super O, ? extends T> method, T nullSubstition) {
return value == null ? nullSubstition : method.apply(value);
}
Your method's generics aren't defined correctly. You're attempting to create a method that receives an object of a certain type (T
, for argument's sake, or a NamedObject
in the given example), and applies a method that returns an object of a different type (S
, for argument's sake, or String
in the given example), or a default S
value if the passed object is null
:
public static <T, S> S nvl(T value, Function<T, S> method, S nullSubstition) {
return value == null ? nullSubstition : (S) method.apply(value);
}
Note that Java 8's Optional
may allow you to write this in a more elegant way (although elegance is somewhat in the eye of the beholder):
public static <T, S> S nvl(T value, Function<T, S> method, S nullSubstition) {
return Optional.ofNullable(value).map(method).orElse(nullSubstition);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With