If there is a structure, an array for example, which might be null, is it valid to use a for/in loop for this structure? For example,
String[] a = someFunction(); //some function which might return null
for (String s : a) {
//do something
}
I wonder if this code will crash or not.
No. You'll get a NullPointerException
In such circumstances I always try to return empty collections, rather than null collections. That way I don't have to worry about iterating without a prior null check (you could argue this is a NullObject pattern)
Make someFunction() return an empty array if possible.
Otherwise, yeah. You'll get a NullPointerException
I wonder if this code will crash or not.
Yes. It might crash.
Note that if you return an empty collection, this might ruin your logic. You have to be sure that you don't do unexpected things when you didn't return a non-null value.
I would simply put an if that checks if the value returned from someFunction() is null:
if(a != null) {
for (String s : a) {
//...
}
}
Related
This question already has answers here:
Using Java 8 Optional for List of String as output
(3 answers)
Closed 1 year ago.
I keep seeing some users saying that using a collection with an optional is not recommended / is bad practice. I couldn't find much information on why it would be bad practice, so here I am.
In case it matters, in my particular case I have a JpaRepository with 2 methods. One Optional<List> getValues() and a second List getDefaultValues(), as such:
public interface someRepository extends JpaRepository<x, y> {
Optional<List> getValues();
List getDefaultValues();
}
The idea is that the values might not be present so I want to force the method caller to do .orElse(getDefaultValues()) so there is no chance getting returned an empty List. I also figured it would be tidier than just doing something like this:
List list = getValues();
if (list.isEmpty()) {
list = getDefaultValues();
}
Any feedback is appreciated.
Edit: I realise my example is not the most well suited to the question, as pointed out in the answers below. However, I would still like to understand why Optional<List> is considered bad practice by some.
This question does not really answer my question.
I think the point is moot. There are two possible cases:
1. The caller needs to be aware that default values have been returned
In this case, the caller will not be able to use the orElse()/orElseGet() construct, and will have to check with isPresent(). This is no better than checking whether the list is empty.
2. The caller does not need to be aware that default values have been returned
In which case you might as well hide the implementation details behind a single List getValues() method that returns the default values in case no values were found.
As to the general applicability of using Optional<List>, I think the Brian Goetz quote from this answer says it best:
Our intention was to provide a limited mechanism for library method
return types where there needed to be a clear way to represent "no
result", and using null for such was overwhelmingly likely to cause
errors.
When it comes to lists (and collections in general), there is already a clear way to represent "no result", and that is an empty collection.
Lets first consider this example:
public class <X> Example {
public List<X> getValues() {
if (...) {
return null;
} else {
return /* a non-empty list */
}
}
public List<X> getValuesAgain() {
if (...) {
return Collections.emptyList();
} else {
return /* a non-empty list */
}
}
}
Which of those ways of returning no values is better?
I would argue that the better way is (nearly always) the way that getValuesAgain does it; i.e. by returning an empty list. Consider the following.
With the first version, I need to test for a null before using the result:
List<String> l = example.getValues();
if (l != null) {
for (s String: l) {
/* do something */
}
}
With the second version, I can use the result directly:
List<String> l = example.getValuesAgain();
for (s String: l) {
/* do something */
}
In short, returning null makes life more complicated for the caller compared with returning an empty list. In theory, you may have saved the creation of an empty list object ... except that the javadoc for emptyList() states that it doesn't need to return a distinct list object each time. (And it typically won't!)
Now consider what Optional<List<String>> means: either a List<String> or no value. But as we have already seen, returning an empty list is simpler for the caller that returning a null. And the same logic applies here too.
So if getValues returns an Optional<List<X>>, we would need to use it like this:
Optional<List<String>> l = example.getValues();
if (l.isPresent()) {
for (s String: l.get()) {
/* do something */
}
}
Compare with the original getValuesAgain:
List<String> l = example.getValuesAgain();
for (s String: l) {
/* do something */
}
In short, using Optional to return a list or null is not an improvement.
The only scenario where I think you should contemplate using Optional<List<?>> as a return type is if the API needs to make a semantic distinction between an empty list versus no list.
The same applies for other collection types, and also for arrays, strings and other examples.
Another way of thinking about this is that the designers' intention for Optional is to provide a way to indicate there is "no result"; see Brian Goetz's answer to this question. But we don't need to indicate there is "no result" here since we can return an empty collection.
I have a condition in java as follows:
if(a == null || a.getRecords() == null || a.getRecords().isEmpty()) {
}
Is there a better way to write this condition using some google guava library or apache library?
Not sure if this solution is better, but you can use an Optional for that:
boolean result = !Optional.ofNullable(a)
.map(MyClass::getRecords)
.filter(List::isEmpty)
.isPresent();
if (result) {
// ...
}
A way of doing it is like so, using the null object pattern:
if (firstNonNull(firstNonNull(a, someNonNullInstance).getRecords(), emptyList()).isEmpty()) {
Where MoreObjects.firstNonNull and Collections.emptyList() are used.
This assumes that someNonNullInstance is an instance of the same type as a, with an empty records list (or whatever the type of getRecords() is).
I wouldn't recommend this, however. The original code is far more readable (I would go so far as to say that this is quite unreadable).
You could make it more readable by breaking up the expression:
TypeOfA anA = firstNonNull(a, someNonNullInstance);
List<Record> aList = firstNonNull(anA.getRecords(), emptyList());
if (aList.isEmpty()) {
// ...
}
but it still feels far worse that the original.
Seems you are working with collection here , If you use the Apache Commons Collections library in your project, you may use the CollectionUtils.isEmpty and MapUtils.isEmpty() methods which respectively check if a collection or a map is empty or null (i.e. they are "null-safe").
Also You can use org.apache.commons.lang.Validate's "notEmpty" method:
Validate.notEmpty(myCollection) -> Validate that the specified argument collection is neither null nor a size of zero (no elements); otherwise throwing an exception.
When you use spring then you can use
boolean isNullOrEmpty = org.springframework.util.ObjectUtils.isEmpty(obj);
where obj is any [map,collection,array,anything...]
But it seems To check an object is null is easy but to verify if it's empty is tricky as object can have many private or inherited variables and nested objects which should all be empty. For that All need to be verified or some isEmpty() method be in all objects which would verify the objects emptiness.
You can't do it directly, you should provide your own way to check this. Eg.
class MyClass {
Object attr1, attr2, attr3;
public boolean isValid() {
return attr1 != null && attr2 != null && attr3 != null;
}
}
Or make all fields final and initialize them in constructors so that you can be sure that everything is initialized.
I have some function with lambda which is returning some object or null
public Function<SomeObject1, SomeObject2> lambdaFunc = obj1 -> {
// here I do some logic, convert obj1 to obj2 and on the end return obj2 or null
};
I am using that function in my stream like that:
someObj0.setObjects2(entity.getObjects1().stream().map(lambdaFunc).collect(Collectors.toSet()));
Here when lambdaFunc return null I got exception, I think it is due collect function. Is some pretty solution to do that? I will be ok if that stream return also null when lambdaFunc return null, and don't continue.
EDIT 1:
Ok I tried filter(Objects::nonNull) function but I find out problem is with entity.getObjects1() so I need prevent call stream function if it return null, any ideas?
You can sinply add filtering for nonNull values:
someObj0.setObjects2(
Optional.ofNullable(entity.getObjects1())
.orElse(Coollections.emptyList()) // return original Object or singleton empty from Collections
.stream()
.map(lambdaFunc)
.filter(Objects::nonNull) // add checking here
.collect(Collectors.toSet()));
Here you have two choices:
First would be to wrap getObjects1() in a Optional
Second would be more clean - never return null, initialize your object with empty collection at start. Methods that return collections should never return null, but an emptyCollection from Collections util class. So that you would not have to worry about the nulls.
so
class SomeObj0 {
private List<SomeObject1> col =Collections.emptyList();
// getters/setters
}
I assume your collections is a list, but you can prevent it with a Optional:)
I think this is the case where you should use Optional instead of null.
You don't have much details about what entity.getObjects1() is doing, but one thing is for sure, if you avoid returning null all along it will save you a NullPointerException further on.
You can try something like this which is clearer as to the intent you are doing:
Optional.ofNullable(entity.getObjects1())
.map(objects -> objects.stream()
.filter(Objects::nonNull)
.map(lambdaFunc)
.collect(Collectors.toSet()))
.ifPresent(someObj0::setObjects2)
If you change entity.getObjects1() to return Optional you avoid the first call to ofNullable().
I would also encapsulate the objects.stream() part to another method that takes the collection and lambda function and returns another collection, to make the code a bit clearer.
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 have a big problem with this code and I have no idea how to cause it:
while(tree.find(indexreg)!=null){
//do stuff
}
For some reason, comparing tree.find(indexreg) with null causes a NullPointerException. Since this is a college project I have to use my own binary tree implementation instead of the one provided by Java. tree is a BinarySearchTree and indexreg is a Comparable object, that was already initialized. This is the code for find in the BinarySearchTree class:
public Comparable find(Comparable x) {
return elementAt(find(x, root));
}
It looks for the object in the tree and it returns null if it doesn't find it (I don't think you can return an empty Comparable object). I tried Googling but I didn't find an useful answer. Does anyone know how to make this code work?
I don't think the problem has anything to do with your Comparable.
If the line while(tree.find(indexreg) != null) { throws a NullPointerException, it must be because tree is null. No other possibilities are credible.
Comparison of an object reference with null using == or != will NOT throw an NPE. So even if tree.find(...) returned a null, that can't be the cause of this exception.
Passing a null value as a method argument will NOT throw an NPE. So if indexreg was null, that wouldn't cause this exception. (An NPE could be thrown by the find method or something it calls, but the stacktrace will not show a different line in a different method as the origin of the exception.)
(I could be misinterpreting the question. I'm assuming that the OP means "throws" when he says that the line "causes" the exception.
Unfortunately, the OP is only posting snippets of code and hasn't shown us the stacktrace ... which is the critical piece of evidence.)
public Comparable find(Comparable x) {
return x == null ? null : elementAt(find(x, root));
}
fyi this is equivalent to:
public Comparable find(Comparable x) {
if (x == null) return null;
return elementAt(find(x, root));
}
You nay also consider improving the clarity of your code: You have a method call and a test combined. While this is not "bad" per se, IMHO it would be cleaner to separate the two, AND get a hold of the value returned in case you want to do something with it, like this:
for (Comparable<?> result = tree.find(indexreg); result != null; result = tree.find(indexreg)) {
//do stuff with variable "result"
}
It just makes it more obvious what is controlling the loop.
There is another way to get the result, but it's considered "bad coding style" by some; that is to assign and test in one:
Comparable<?> result;
while ((result = tree.find(indexreg)) != null) {
//do stuff with variable "result"
}
Some believe that you should avoid this style of coding. I tend to agree with them.
Possibly indexreg is null, not initialized at all. You should certainly code find() more defensively as suggested by #Bohemian but this may be the underlying problem. Or see next comment below.