Is this written in a proper java8 way? - java-8

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.

Related

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.

Kafka Streams DSL Predicate stream seperation

branch(new predicate{
business logic
if(condition)
return true
else
return false;
When the condition is false how to push to different stream. Currently creating another predicate which collects all other records which doesn't satisfy the above predicate in chain. Is there a way to do in same predicate?
for that you need to pass also second predicate that always returns true
KStream<String, String>[] branches = kStream.branch(
yourPredicate,
(String key, String value) -> true
);
branches[0].to(firstTopic);
branches[1].to(secondTopic);

Java .stream().findAny() throws NullpointerException

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.

Java 8 Streams Filter a list based on a condition

I am trying to extract a filtered list on top of the original list based on some condition. I am using backport version of Java 8 and am not pretty sure how to do this.I get the Set from ccarReport.getCcarReportWorkflowInstances() call. I need to iterate and filter this set based on a condition match( I am comparing the date attribute in each object with the request date being passed. Below is the code
Set<CcarReportWorkflowInstance> ccarReportWorkflowInstanceSet = ccarReport.getCcarReportWorkflowInstances();
List<CcarReportWorkflowInstance> ccarReportWorkflowInstances = StreamSupport.stream(ccarReportWorkflowInstanceSet).filter(ccarReportWorkflowInstance -> DateUtils.isSameDay(cobDate, ccarReportWorkflowInstance.getCobDate()));
The routine which is doing the job
public List<CcarRepWfInstDTO> fetchReportInstances(Long reportId, Date cobDate) {
List<CcarRepWfInstDTO> ccarRepWfInstDTOs = null;
CcarReport ccarReport = validateInstanceSearchParams(reportId, cobDate);
Set<CcarReportWorkflowInstance> ccarReportWorkflowInstanceSet = ccarReport.getCcarReportWorkflowInstances();
List<CcarReportWorkflowInstance> ccarReportWorkflowInstances = StreamSupport.stream(ccarReportWorkflowInstanceSet).filter(ccarReportWorkflowInstance -> DateUtils.isSameDay(cobDate, ccarReportWorkflowInstance.getCobDate()));
ccarRepWfInstDTOs = ccarRepWfInstMapper.ccarRepWfInstsToCcarRepWfInstDTOs(ccarReportWorkflowInstances);
return ccarRepWfInstDTOs;
}
Error I get when I tried to use streams.
Assuming I understood what you are trying to do, you can replace your method body with a single line :
return
validateInstanceSearchParams(reportId, cobDate).getCcarReportWorkflowInstances()
.stream()
.filter(c -> DateUtils.isSameDay(cobDate, c.getCobDate()))
.collect(Collectors.toList());
You can obtain a Stream from the Set by using the stream() method. No need for StreamSupport.stream().
After filtering the Stream, you should collect it into the output List.
I'd use shorter variable and method names. Your code is painful to read.

Unique from list or null in Linq?

I have a list of strings, and want to use a single line of Linq to return the list's unique value (if there is one) or null, otherwise. In other words:
["a","a","a","a","a"] returns "a"
["a"] returns "a"
["a","a","a","a","b"] returns null
["a","b","c"] returns null
[] returns null
I assume I would use IEnumerable.Distinct() to collapse the list to its unique values, but I don't know how to do the "single or null" (SingleOrDefault() throws an exception if there's more than one item; FirstOrDefault() will always return the first item, and won't return null if there's two or more like I want.)
Any ideas? I'm just really curious if there's a simple way to do this in a single line that I'm overlooking. Bonus points if you don't have to write an extension method to make it work. Thanks!
col.Distinct().Count() == 1? col.First() : null;
Would this do?
col.Distinct().Count() > 1 ? null : col.Distinct().First();
Updated to handle empty collection
col.Count() == 0 ? null : col.Distinct().Count() > 1 ? null : col.Distinct().First();

Resources