I am new to lambda expressions and am trying to use them to reduce the following code to the lambda equivalent. I have looked into reduce and flatMap and forEach, as well as several other things, but I am obviously missing something because everything that I try is either syntactically incorrect or I don't have a reference for what I need.
I need to perform an analysis of each element against all other elements in a collection. I coded that as nested loops with a conditional. Once non-matching elements have been identified, a computation is done using both elements. Finally, I want a collection of results for each comparative computation.
So, here's the original code:
final List<Element> updated = new ArrayList<>(elements.size());
for (final Element first : elements) {
Attribute newAttribute = first.getAttribute();
for (final Element second : elements) {
if (!first.equals(second)) {
newAttribute = newAttribute.add(computeChange(first, second));
}
}
final Element newElement = new Element(first.getEntry(), newAttribute, first.getValue());
updated.add(newElement);
}
Then, I tried many variations of lambda expressions, the simplest of which is:
elements.parallelStream()
.map(first -> new Element(first.getEntry(), first.getAttribute().add(
computeChange(first, second)), first
.getValue())).collect(Collectors.toList()));
Obviously, this is wrong as there is no reference to second available to me and no condition/filter for second being not equal to first.
How do I reduce this nested loop with conditional returning a collection to a lambda expression?
Any help here is greatly appreciated.
Try:
elements.stream()
.map(first -> {
Attribute newAttribute = elements.stream().filter(second -> !first.equals(second))
.map(second -> computeChange(first, second))
.reduce(first.getAttribute(), (a, b) -> a.add(b))
return new Element(first.getEntry(), newAttribute, first.getValue());
}).collect(Collectors.toList()));