Java .stream().findAny() throws NullpointerException - java-8

My goal is to check if there is a object with specific ID in collection:
Optional<PolicyCoHolder> policyHolder = policyCoHolderCollection.getPolicyCoHolder()
.stream()
.filter(coHolder -> coHolder.getPolicyCoHolderId().longValue() == representativeId)
.findAny();
My collection:
policyCoHolder = {ArrayList#17539} size = 3
0 = {PolicyCoHolder#17541}
1 = {PolicyCoHolder#17542}
2 = {PolicyCoHolder#17543}
And representativeId:
representativeId = null
As stated in docs:
Returns: an Optional describing some element of this stream, or an
empty Optional if the stream is empty
Throws: NullPointerException - if the element selected is null
However in my collection there's no null elements, and .filter() should have filtered out all elements, so why is NPE thrown?
java.lang.NullPointerException: null
at gold.core.domain.mtpl.mapper.MTPLMapper.lambda$addPolicyCoHolder$1(MTPLMapper.java:303)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1359)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:469)

It looks like coHolder is null or coHolder.getPolicyCoHolderId() returns null. Try to add additional filters before your original filter:
Optional<PolicyCoHolder> policyHolder = policyCoHolderCollection.getPolicyCoHolder()
.stream()
// will filter out all nulls in the stream
.filter(Objects::nonNull)
// compare values finally, Object::equals can handle null checks properly
.filter(coHolder -> Objects.equals(coHolder.getPolicyCoHolderId(),representativeId))
.findAny();
Of course we can combine all 3 filter into 1, but in my opinion it looks less readable.

Related

Is this written in a proper java8 way?

I have a POJO where I have a Map<String, String> field.
I need to do the below checks.
Check POJO object null
Check map is null
Get a value from a map
Parse to boolean - It is not happening in the below snippet
Return true or false.
For negative cases in first 4 statement should lead to false value.
I have something as below.
Optional<Object> optional = Optional.ofNullable(event)
.map(Event::getAttributes)
.map(attrMap -> attrMap.get("restructured"));
return optional.isPresent();
How can I do this in Java8 way? I see that if value is null, NPE is thrown. Is there any way to do as I mentioned in the steps i.e if null return false?
Optional#orElse is exactly what you need:
return Optional.ofNullable(e)
.map(Event::getAttribute)
.map(m -> m.get("restructured"))
.map(Boolean::parseBoolean)
.orElse(false);
If any of the steps produces null then result resolves to false.

Java Stream filter - how can i filter data without wrapping the filter code in 'if' condition for checking null on the filtering keys?

I am doing the following:
List<Objects> filtered = objects.stream()
.filter(o -> source.equals(o.getSource()) && date.equals(o.getDate()) && id.equals(o.getId()))
.collect(Collectors.toList());
where both date and id could possibiliy be null, as the are coming from method parameters.
How can I ignore them if null, without wrapping the above code in an if statement tp check 'id' and 'date' for null values ? I want to do it inside the filter.
Edit : To make it more clear, i want the filter to act only on the non-null values, i.e if date is non-null and id is null, then filter only on date and ignore id, and so on..
Thanks
An additional option is to do the null checks in the predicate:
.filter(o -> source.equals(o.getSource())
&& (null == date || date.equals(o.getDate()))
&& (null == id || id.equals(o.getId())))
You could use the static method Objects::equals. Chances are that this method is designed for just this:
List<Objects> filtered = objects.stream()
.filter(o -> Objects.equals(source, o.getSource()) && Objects.equals(date, o.getDate()) && Objects.equals(id, o.getId()))
.collect(Collectors.toList());
Note: as Scratte mentioned in the comments, this may not filter out objects for which getDate() returns null, if date is also null. Same goes for id. If that's the case, then the abovementioned code snippet does not comply. In that case, then we have to explicitly filter for non-null dates and ids:
.filter(o -> Objects.nonNull(o.getId()) && Objects.nonNull(o.getDate()))
Update
If you want to skip the comparison for getDate() if date is null (and same for id), then you could check first for null, just like in ernest_k's answer.
You could easily build a small method for it:
public static boolean nullOrEquals(Object baseObject, Object compareObject) {
return baseObject == null || Objects.equals(baseObject, compareObject);
}
.filter(o -> Objects.equals(source, o.getSource())
&& nullOrEquals(date, o.getDate())
&& nullOrEquals(id, o.getId()))
Here's an Ideone example.

Unable to create a constant value of type 'System.DBNull'. Only primitive types or enumeration types are supported in this context

I try to apply left outer join on the basis of two ids one in the primary key of one table while the foreign key of another table also nullable
var yarnPOFilter_Grid = (from yrq in _context.Yarn_Requisition_Details
//join ypo in
_context.Yarn_PurchaseOrder_Details on yrq.YarnRequsitionDetailID
equals
ypo.YarnRequsitionDetailID into t
join ypo in
_context.Yarn_PurchaseOrder_Details on yrq.YarnRequsitionDetailID
equals
DBNull.Value.Equals(ypo.YarnRequsitionDetailID) ? 0 :
ypo.YarnRequsitionDetailID into t
from rt in t.DefaultIfEmpty() //
DefaultIfEmpty preserves left-hand elements that have no matches on the
right side
select new
{
YarnRequsitionDetailID =
(rt.YarnRequsitionDetailID == null ? long.MinValue :
rt.YarnRequsitionDetailID),
yrq.YarnID,
yrq.Yarn.YarnName,
yrq.YarnFellowID,
yrq.Yarn_FellowCodes.YarnFellowCode,
yrq.QuantityRequired,
rt.QuantityOrdered,
QuantityBalance_Custom =
yrq.QuantityRequired - rt.QuantityOrdered
}).ToList();
return yarnPOFilter_Grid;
I get this error message when I deal with null in joining condition
Unable to create a constant value of type 'System.DBNull'. Only primitive types or enumeration types are supported in this context.
Execute ToList() First before Select as there is no sql equivalent to the conditions you added in the YarnRequsitionDetailID = (rt.YarnRequsitionDetailID == null ? long.MinValue : rt.YarnRequsitionDetailID)
so it will be
from rt in t.DefaultIfEmpty()).ToList().Select(c => new
{
YarnRequsitionDetailID =
(c.rt.YarnRequsitionDetailID == null ? long.MinValue :
c.rt.YarnRequsitionDetailID),
c.yrq.YarnID,
c.yrq.Yarn.YarnName,
c.yrq.YarnFellowID,
c.yrq.Yarn_FellowCodes.YarnFellowCode,
c.yrq.QuantityRequired,
c.rt.QuantityOrdered,
QuantityBalance_Custom =
c.yrq.QuantityRequired - c.rt.QuantityOrdered
}).ToList();
i hope this solved your previous problem

Spring mvc ignore null objects in list

How can I handle null objects in array which binds from an inputs?
I have
input name=example value=3,4
input name=example value=""
List example = new ArrayList()
the bind result is a list with 3 elements = null ,3, 4 is there an attribute that I can put on the list to ignore this null?
#JsonInclude(Include.NON_NULL) isn't working.
You can try to send your list to Apache ListUtils:
List result = ListUtils.predicatedList(example, PredicateUtils.notNullPredicate());
You can use classic Java 8 Stream API, it will look like this:
list = list.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());

LINQ: Nullable object must have a value.

Let me preface this by saying I'm a novice with LINQ, and that this is code that I didn't originally write but am trying to fix. I've done a lot of research on this error, but I haven't found anything helpful yet. In fact, this error sort of makes my head spin. Anyway...
I have a LINQ query that is selecting some data from three SharePoint lists. Here it is:
private void loadPEGrid(int id)
{
dc = new SpEntityDataContext(SPContext.GetContext(this.Context).Web.Url);
EntityList<ProductDocumentMapItem> dMaps = dc.GetList<ProductDocumentMapItem>("Product Document Map");
object mappedItems = null;
mappedItems = from m in dMaps
join p in dc.PEProducts on m.ProductID.Value equals p.Id.Value
join d in dc.ProductDocuments on m.DocID.Value equals d.Id.Value
where m.ProductID.Value == id && m.ProductType == "PE"
select new {
p.Grade,
d.Path,
d.DocumentType,
d.Title,
d.Name,
Language = d.Language.Title,
m.Id,
DocId = m.DocID };
GridViewProducts.KeyFieldName = "Id";
GridViewProducts.DataSource = mappedItems;
GridViewProducts.DataBind();
}
The following fields are nullable:
m.ProductID
m.DocID
d.DocumentType
m.Id
When I debug, none of this throws an error, but when the page loads it does:
System.InvalidOperationException: Nullable object must have a value
Does this mean that one of the fields I'm selecting is null, or one of the join fields? Having checked the data, I don't think this is the case. Let me know if you need any more info from me.
System.InvalidOperationException: Nullable object must have a value
This exception is thrown when you are trying to get Value property of nullable type. So, that means one or more of following is true:
At least one of objects in dMaps has property ProductID equal to null
At least one of objects in dMaps has property DocID equal to null
At least one of objects in dc.PEProducts has property Id equal to null
At least one of objects in dc.ProductDocuments has property Id equal to null
Exception raised not by query

Resources