This is a code segment from another StackOverflow question:
#Override
public String convertToDatabaseColumn(final UUID entityValue) {
return ofNullable(entityValue).map(entityUuid -> entityUuid.toString()).orElse(null);
}
I am really struggling to understand the use of the Optional class. Is the return code saying "return the value of the map (a String) or NULL if that fails?
How can return be acting on a method rather than a Class - that is Optional.ofNullable()?
This is a really bad use of Optional. In fact the java developers themself say that optional should not be used in such cases, but only as a return argument from a method. More can be read in this great answer: Is it good practice to use optional as an attribute in a class
The code can be rewritten to this:
#Override
public String convertToDatabaseColumn(final UUID entityValue) {
return entityValue == null ? null : entityValue.toString();
}
Is the return code saying "return the value of the map (a String) or NULL if that fails?
Yes. You can check the documentation of Optional here. It tells you exactly what map and orElse do.
How can return be acting on a method rather than a Class - that is Optional.ofNullable()?
You are not returning the method. You are returning the return value of a method. Look at this simple example:
int myMethod() {
return foo();
}
int foo() { return 10; }
See? I am not returning foo the method, I am returning 10, the return value of foo.
Note that it is possible to return methods, with functional interfaces.
In this case, you are returning the return value of the last method in the method chain, orElse. ofNullable creates an Optional<T>, then map is called on this object and returns a new Optional<T>, then orElse is called and its return value is returned.
Lets go step by step:
ofNullable(entityValue)
creates an Optional of the incoming parameter (which is allowed to be null, using of() a NPE gets thrown for null input)
.map(entityUuid -> entityUuid.toString())
Then you pick the actual value, and invoke toString() on that value ... which only happens if entityValue isn't null. If it is null, the result comes from orElse(null).
In the end, the result of that operation on the Optional is returned as result of the method.
The above code is nothing but a glorified version of
if (entityValue == null) return null;
return entityValue.toString();
Optionals have their place in Java, but your example isn't a good one.
It doesn't help readability a bit, and you are not alone with wondering "what is going on here".
The code can be turn like this :
public String convertToDatabaseColumn(final UUID entityValue) {
if(entityValue==null){
return null;
}else{
return entityValue.toString();
}
}
Your initial code have two statements:
Optional.ofNullable(entityValue): create an Optional Object to say the value can be present or not.
.map(entityUuid -> entityUuid.toString()).orElse(null); you apply some operation to your Optional object, return a string of it or null.
This will avoid a null pointer exception in a more elegant way.
Optional.ofNullable(T value):
Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.
Optional.orElse(null)
Return the value if present, otherwise return null.
Follow this link
Related
Imagine an Optional.ofNullable check assigning to a String:
String result = Optional.ofNullable(class1)
.map(Class1::getClass2)
.map(Class2::getResult);
Where getResult returns a String.
While I know this doesn't compile, I can fix it by either adding toString() or .orElse(""); to sort that.
As it stands, the error is:
Bad return type in method reference, cannot convert java.lang.String
to U
I understand adding orElse("") as that will assign result to an empty String.
But what's the benefit of adding toString() if something is null along the way? Or is that just to purely get it to compile?
The return type of map is Optional <U>, so to get a real value you should call for orElse with the return type of T.
This is the toString implementation if the Optional:
#Override
public String toString() {
return value != null
? String.format("Optional[%s]", value)
: "Optional.empty";
}
So, calling toString you'll never get the real value, but a value wrapped to Optional, while orElse will return you the default provided value.
Let's see the difference:
Integer i = 4;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.toString();
System.out.println(s);
Output:
Optional[4]
With null:
Integer i = null;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.toString();
System.out.println(s);
Output:
Optional.empty
While using orElse:
Integer i = null;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.orElse("None");
System.out.println(s);
Output:
None
So you can see that there are different purposes of these methods.
And the answer to your comment:
"Is there a way to call get() and also call orElse() in the same chain?"
Integer i = 10;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.orElse("None");
System.out.println(s);
Output:
10
You don't need to call get explicitly, the value will be fetched if not null;
/**
* If a value is present, returns the value, otherwise returns
* {#code other}.
*
* #param other the value to be returned, if no value is present.
* May be {#code null}.
* #return the value, if present, otherwise {#code other}
*/
public T orElse(T other) {
return value != null ? value : other;
}
I understand adding orElse("") as that will assign result to an empty
String.
It doesn't sound like you do understand it to me because that's not a good description of what's happening. Optional.orElse does the following: if the optional contains a value, return that value. If it doesn't contain a value, return whatever argument you've given it.
It's semantically equivalent to the following:
if (optional.ifPresent())
{
return optional.get();
}
else
{
return theArgument;
}
Calling toString, while it will satisfy the compiler, is not what you want to do. You are converting the Optional object itself to a String, not getting the String from inside! While your string will be included, this is only because of how the JDK developers have decided to implement toString. They could equally have not provided an implementation, leaving you with just the default behaviour.
Calling toString on an Optional should basically never be relied upon outside of logging. It's essentially just debugging information. If you do this, then information about the Optional wrapper will be printed as well, which is almost certainly not what you want.
System.out.println(Optional.empty()); // Optional.empty
System.out.println(Optional.of("foo")); // Optional[foo]
If you want result to be null if something along the way returns null then do orElse(null)
String result = Optional.ofNullable(class1)
.map(Class1::getClass2)
.map(Class2::getResult).orElse(null);
I would like to know how I can use findAny() in a data stream when it does not find any coincidence, it does not return null.
String CountryFinal= "Spain";
List<ParContriesTO> listContries = new ArrayList<SelectItem>();
listContries.add(new SelectItem(215, "Germany"));
Integer idCountry = (int) listContries.stream()
.filter(country -> country.getNoCountry().equals(CountryFinal))
.findAny().orElse(null).getCoCountry();
The Stream::findAny returns Optional and its method Optional::findAny, according to the documentation, there are 4 ways to return T:
Optional::get returns the T or throws NoSuchElementException
Optional::orElse returns T or a default value
Optional::orElseGet returns T or a value provided with Supplier
Optional::orElseThrow returns T or throws a custom exception
As far as I understand, you are looking for the second or third method which returns a defined value in case the origin is null. You can return a null-object using the Null-Object pattern which represents an object which is valid but does "nothing". Or else you can use null.
I suggest you receive a country before you let return null or anything alse and use getCoCountry() method on it (I suppose Country::getCoCountry returns either int or Integer) - otherwise, what have you done would return NullPointerException.
Try the following snippet:
Integer idCountry = listContries.stream() // Stream
.filter(c -> countryFinal.equals(c.getNoCountry())) // Get one equals to "Spain"
.findFirst() // Get Optional<Country>
.map(Country::getCoCountry) // If exists, get its code
.orElse(0); // Or else return an invalid code
Note there is no need to both filter by the country name and then check the equality since you expect there is only one "Spain".
The approach to invoke getCoCountry as last is generally bad.
What you could do is:
listContries.stream()
.filter(country -> country.getNoCountry()
.equals(CountryFinal))
.findAny().map(Country::getCoCountry).orElse(WHATEVER_YOU_WANT);
To clarify: findAny returns Optional that may contain an instance of country. You can safely invoke getCoCountry in map. This is the importance of Optional type. At this step, you're still safe since you still have an Optional that MAY contain an Integer result. In the end, you can use orElse to decide what you want to have if instance is null.
Can someone explain how Optional helps us avoid NullPointerException?
Optional<String> op = someFunc()
if(op.isPresent()) {
op.get();
}
String possibleNull = op.get();
Isn't this code prone to NullPointerException too? If so, then why is this code preferred over
String op = someFunc()
if(op != null) {
op.get();
}
String possibleNull = op;
What possible benefit does Optional provide other than the fact that it helps us in knowing whether a function actually had a return value or not
Let's say you want to get a string returned by a function, convert it to upper case, and then print it out. If you have:
String someFunc() { ... }
You might be tempted to write:
System.out.println(someFunc().toUpperCase());
Of course, this throws NullPointerException if someFunc returns null. Instead, suppose we have this:
Optional<String> someFunc() { ... }
Then
System.out.println(someFunc().toUpperCase());
won't work, since Optional doesn't have a toUpperCase method. At this point -- hopefully -- you'll be confronted with an Optional, which should make you think about the case of the Optional being empty. This helps avoid NPEs, but probably only somewhat.
Now you might be focusing on how to get the value out of the Optional, and you might forget about the empty case. Ah, there's a get method:
System.out.println(someFunc().get().toUpperCase());
This brings back the same problem as NPE, except that the exception is NoSuchElementException instead. So if you blindly call get on an Optional, it really is pretty much the same thing as calling a method on a reference without checking whether it's null.
(For this reason, Brian Goetz considers Optional.get to be the biggest mistake in Java 8. See his interview with Angelika Langer JAX 2015 Fragen und Antworten zu Java 8 at about 16 minutes in. I'm not sure it's the biggest, but it is a mistake. People just don't expect get to throw an exception.)
If you're diligent about checking for null references or empty optionals, then
Optional<String> os = someFunc();
if (os.isPresent()) {
System.out.println(os.get().toUpperCase());
}
is hardly any better than the old
String s = someFunc();
if (s != null) {
System.out.println(s.toUpperCase());
}
The real advantage of Optional is that it's a library class that has a fairly rich API for dealing with the empty case in a safe way. It's often possible to process the value that might be contained within an Optional by chaining a couple method calls to the method that returned the Optional in the first place. For example, we could rewrite the sample above as follows:
someFunc().map(String::toUpperCase)
.ifPresent(System.out::println);
String op = someFunc()
if(op != null) {
op.trim();
}
When the interface someFunc() is invoked above, it doesn't explicitly say that a null value could be returned, so the caller is left to his/her own assumption.
By explicitly returning an Optional, the caller of someFunc() is made aware that the interface could potentially return null. From an interface creator's perspective, it lets him/her be specific about the return value rather than having to document it separately.
Optional<String> op = someFunc()
if(op.isPresent()) {
op.get().trim();
}
One scenario where Optional is helpful in avoiding NullPointerException is method chaining.
class A {
private B b;
}
class B {
private C c;
}
class C {
private D d;
}
Let's say I have the above classes, and I want to make sure that an instance of class A has a non-null instance of D, but without causing a null pointer exception.
If I were to directly call a.getB().getC().getD() != null, then it might throw NullPointerException - say if a.getB() was null.
Of course, I can do
try {
a.getB().getC().getD();
// do something
}
catch(NullPointerException e) {
// handle exception
};
But that doesn't look nice. An elegant solution would be to wrap our objects in optional.
Optional.ofNullable(a).map(A::getB).map(B::getC).map(C::getD).isPresent()
Check this for more.
I started to learn Lambda expressions of Java 8, and wrote below program to get sum of all numbers in the list:
import java.util.Arrays;
import java.util.List;
public class MainClass {
public static void main(String[] args) {
List<Integer> number = Arrays.asList(1, 2, 3, 4, 5);
System.out.println(number.stream().reduce((c,e) -> {
return c + e;
}));
}
}
I was expecting the output to be:
15
but I got:
Optional[15]
Java version: 1.8.0_45
Please explain what does Optional[] means in the output?
Does it has any significance in Java 8?
From the Java Docs for Stream#reduce(), we see that the reduce operation returns an Optional<T>. An Optional simply wraps a value if there is a value present, otherwise is "empty".
Important operations on Optional include Optional#isPresent, which lets you know if there is something in the Optional or not, Optional#get, which returns the T wrapped in the Optional and throws an exception if called on Empty, and Optional#orElse which returns the T wrapped in the Optional if present, or the returns the default value provided if called on Empty.
For your case, the rationale behind reduce() returning an Optional<Integer> is that the list you're trying to reduce may be empty. In that case, the Integer that should be returned is not well defined. For your specific intention 0 would be acceptable (As the sum of the elements in an empty list is 0), thus you can get the sum as follows:
int sum = number.stream().reduce((c,e) -> c + e).orElse(0);
That way, even if the list is empty, you will still get a result that defines the sum of the list.
reduce(BinaryOperator<T> accumulator):
Returns an Optional describing the result of the reduction
Optional:
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
The reason reduce() returns an Optional, is because the stream might be empty, in which case there would be nothing to reduce, aka no value, and an Optional.empty() would be returned.
In order to avoid Optional in the return you can call to this other method https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-T-java.util.function.BinaryOperator- Just add the identity: "0" before adding the lambda expression. Note that now there is only a 0 as a fist parameter to the reduce call.
System.out.println(number.stream().reduce(0,(c,e) -> {
return c + e;
}));
returns just
15
Got it, thanks #Mshnik and #TimoSta. According to source code of Optional<> which overrides toString method
#Override
public String toString() {
return value != null
? String.format("Optional[%s]", value)
: "Optional.empty";
}
Above code adds that Optional[] in my output stream.
From java.lang.Object.Optional:
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
Optional offers two different primary methods for retrieving its value.
public T get() simply returns the value enclosed in the Optional, but throws a NoSuchElementException if the Optional does not wrap a value.
orElse(T other) returns the value enclosed in the Optional or other if the Optional does not enclose a value.
EDIT (thanks #Brian Goetz):
Generally, orElse() is a better choice since get() returns a NoSuchElementException if the Optional contains a null value. True, in this case you will always recieve a value in Optional but it's still good practice to primarily use orElse().
So, in your case, you would change
System.out.println(number.stream().reduce((c,e) -> {
return c + e;
}));
to:
System.out.println(number.stream().reduce((c,e) -> {
return c + e;
}).orElse(0));
which will return the desired value of 15.
And as #Brian Goetz said in the comments, if you really wanted to make it succinct you could use Integer::sum and a method reference:
System.out.println(number.stream.reduce(Integer::sum).orElse(0))
which is equivalent to using the longer lambda.
String x = (String) null;
Why there is no exception in this statement?
String x = null;
System.out.println(x);
It prints null. But .toString() method should throw a null pointer exception.
You can cast null to any reference type without getting any exception.
The println method does not throw null pointer because it first checks whether the object is null or not. If null then it simply prints the string "null". Otherwise it will call the toString method of that object.
Adding more details: Internally print methods call String.valueOf(object) method on the input object. And in valueOf method, this check helps to avoid null pointer exception:
return (obj == null) ? "null" : obj.toString();
For rest of your confusion, calling any method on a null object should throw a null pointer exception, if not a special case.
You can cast null to any reference type. You can also call methods which handle a null as an argument, e.g. System.out.println(Object) does, but you cannot reference a null value and call a method on it.
BTW There is a tricky situation where it appears you can call static methods on null values.
Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.
This is by design. You can cast null to any reference type. Otherwise you wouldn't be able to assign it to reference variables.
Casting null values is required for following construct where a method is overloaded and if null is passed to these overloaded methods then the compiler does not know how to clear up the ambiguity hence we need to typecast null in these cases:
class A {
public void foo(Long l) {
// do something with l
}
public void foo(String s) {
// do something with s
}
}
new A().foo((String)null);
new A().foo((Long)null);
Otherwise you couldn't call the method you need.
Println(Object) uses String.valueOf()
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Print(String) does null check.
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
Many answers here already mention
You can cast null to any reference type
and
If the argument is null, then a string equal to "null"
I wondered where that is specified and looked it up the Java Specification:
The null reference can always be assigned or cast to any reference type (§5.2, §5.3, §5.5).
If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l).
As others have written, you can cast null to everything.
Normally, you wouldn't need that, you can write:
String nullString = null;
without putting the cast there.
But there are occasions where such casts make sense:
a) if you want to make sure that a specific method is called, like:
void foo(String bar) { ... }
void foo(Object bar) { ... }
then it would make a difference if you type
foo((String) null) vs. foo(null)
b) if you intend to use your IDE to generate code; for example I am typically writing unit tests like:
#Test(expected=NullPointerException.class)
public testCtorWithNullWhatever() {
new MyClassUnderTest((Whatever) null);
}
I am doing TDD; this means that the class "MyClassUnderTest" probably doesn't exist yet. By writing down that code, I can then use my IDE to first generate the new class; and to then generate a constructor accepting a "Whatever" argument "out of the box" - the IDE can figure from my test that the constructor should take exactly one argument of type Whatever.
This language feature is convenient in this situation.
public String getName() {
return (String) memberHashMap.get("Name");
}
If memberHashMap.get("Name") returns null, you'd still want the method above to return null without throwing an exception. No matter what the class is, null is null.
Print:
Print an object. The string produced by the String.valueOf(Object) method is translated into bytes
ValueOf:
if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.
It wil simply return a string with value "null" when the object is null.
This is very handy when using a method that would otherwise be ambiguous. For example: JDialog has constructors with the following signatures:
JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)
I need to use this constructor, because I want to set the GraphicsConfiguration, but I have no parent for this dialog, so the first argument should be null. Using
JDialog(null, String, boolean, Graphicsconfiguration)
is ambiguous, so in this case I can narrow the call by casting null to one of the supported types:
JDialog((Frame) null, String, boolean, GraphicsConfiguration)