Adding multiple fields in Java streams (and conditional stream operations)
<p>Let's say I have this class:</p>

<pre><code>public class Thing {
    private BigDecimal field1;
    private BigDecimal field2;

    private BigDecimal otherField1;
    private BigDecimal otherField2;
    private BigDecimal otherField3;
}
</code></pre>

<p>and in another class I for-each over a <code>List&lt;Thing&gt; things</code>, adding field1 and field2 to a sum that I return when the iteration is done.</p>

<p>But what I want is to accomplish that with Java streams. The following is what I have--it works, but I feel like there has to be a way to condense it down to one stream:</p>

<pre><code>public BigDecimal addFields(List&lt;Thing&gt; things) {
    BigDecimal field1sum = things.parallelStream()
                                     .filter(thing -&gt; thing.getField1() != null)
                                     .map(Thing::getField1)
                                     .reduce(BigDecimal.ZERO, BigDecimal::add);

     BigDecimal field2sum = things.parallelStream()
                                     .filter(thing -&gt; thing.getField2() != null)
                                     .map(Thing::getField2)
                                     .reduce(BigDecimal.ZERO, BigDecimal::add);
     return field1sum.add(field2sum);
}
</code></pre>

<p>I suspect the answer is the <code>reduce()</code> method that takes three arguments, one of which is a BiFunction, but I haven't been able to figure out how to make that work. Edit: I think I could pass in <code>(x,y) -&gt; x.add(y)</code> to <code>reduce()</code>, but then the question becomes how do I <code>map()</code> both of those fields?</p>

<p>Additionally, is it possible/how would I go about turning this imperative code into a functional stream?</p>

<pre><code>public BigDecimal addOtherFields(List&lt;Thing&gt; things) {
    BigDecimal result = BigDecimal.ZERO;
    for (Thing thing : things) {
        if (thing.getOtherField2() != null) {
            BigDecimal otherField2 = thing.getOtherField2();
            otherField2 = thing.getOtherField1().subtract(otherField2);
            result = result.add(otherField2);
         } else if (thing.getOtherField3() != null) {
            BigDecimal otherField3 = thing.getOtherField3();
            otherField3 = thing.getOtherField1.subtract(otherField3);
            result = result.add(otherField3);
         }
     }
     return result;
 }
</code></pre>

<p>Or, to be a bit more precise, how would I handle that conditional check in a stream based approach? I was trying to <code>filter()</code> things out without success.</p>