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.
Related
This code will give NullPointerException. Isn't the mapToInt (map) method supposed to handle NPE?
List<Integer> list = Arrays.asList(null, null);
OptionalDouble op = list.stream()
.mapToInt(val->val)
.average();
Why do you expect it to handle NullPointerException?
The lambda expression val->val is equivalent to:
new ToIntFunction<Integer> () {
int applyAsInt(Integer value) {
return value;
}
}
And when a method that has an int return type returns an Integer, auto-unboxing takes place. This means value.intValue() is called, and if value is null, NullPointerException is thrown.
mapToInt() simply calls the applyAsInt() method of the ToIntFunction instance passed to it for each element of the Stream.
It has no reason to check that an element is null and somehow handle it, since it has no way of knowing how you wish to deal with nulls. It's the job of the ToIntFunction instance to decide that, and your ToIntFunction doesn't handle nulls.
As Eran has already noted in his answer, the mapToInt is not supposed to handle NPE.
You have to deal with it instead, by providing your custom null-check logic. E.g.:
OptionalDouble op = list.stream()
.mapToInt(val -> val == null ? 0 : val)
.average();
I am fairly new to Java but had a similar problem. Reading over this and the documentation I came up with this -keep in mind, I'm using it for a slightly different reason but you will see how I was able to filter out the possibility of nulls to avoid the NPE.
positions.stream().filter(i -> i != null).mapToInt(i -> i).toArray();
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 List object and I need to take the first element on the list if it is not null or empty.
I write below code using java and now I want to convert it to Java 8.
List<DD> container
A<DD,DI> a;
if(container!=null || !container.isEmpty()){
for(DD dd:container)
{
a = dd.getPrescription();
break;
}
}
I convert it like this.
DD detail = container.stream().findFirst().get();
I need to know this is correct?
There is a critical flaw in your current code, i.e.
if(container!=null || !container.isEmpty())
this can still throw a NullPointerException (when container == null), unless the conditional operator is changed to &&. Post which the implementation below would be what I would suggest following.
It's almost correct, in the sense that you need to handle some default value if the conditions are not met :
DD detail = container.stream().findFirst().orElse(null); // or some default value instead of 'null'
If the container itself could be null, use
DD detail = container != null ?
container.stream().findFirst().orElse(null) : null;
In the case when you need the prescription from this object, use map as :
container.stream().findFirst().map(DD::getPrescription).orElse(null)
// ^^
// return type of prescription then
With Java-9, this could have been much simpler as :
A<DD, DI> basePrescription = Stream.ofNullable(container) // Java-9 API
.flatMap(List::stream)
.findFirst()
.map(DD::getPrescription)
.orElse(null);
This is way easier:
A<DD,DI> a = container.get(0).getPrescription();
While this is a direct translation of your original code, you probably intended something like that:
A<DD,DI> a = container != null && !container.isEmpty()
? container.get(0).getPrescription()
: null;
As of JDK9, there is a new method T requireNonNullElse(T obj,
T defaultObj) which essentially returns the first argument if it is non-null and otherwise returns the non-null second argument.
We can, therefore, simplify your code to:
Objects.requireNonNullElse(container, Collections.emptyList())
.stream()
.findFirst()
.map(DD::getPrescription);
This returns an Optional<T> where T is whatever type getPrescription is. depending on the context and whether it's appropriate you might want to use .orElse(null); to get the value the optional contains or else a null value but there are also several other methods in the Optional<T> API which you might find more useful when extracting the value from the optional.
The findFirst() method finds the first element in a Stream. This method is used when you specifically want the first element from a sequence.
a) container.stream().findFirst().orElse(null);
b) container.stream().filter(Objects::nonNull).findFirst().orElse(null);
c)container.stream().filter(StringUtils::isNotBlank).findFirst();
or as lambdas:
d)container.stream().filter(s -> StringUtils.isNotBlank(s)).findFirst();
e)container.stream().filter(StringUtils::isNotBlank).findFirst()
For reference:- http://www.geekabyte.io/2015/01/using-optional-effectively-in-java-8.html
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.
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