title: Adding up BigDecimals using Streams
body: <p>I have a collection of BigDecimals (in this example, a <code>LinkedList</code>) that I would like to add together. Is it possible to use streams for this?</p>
  
  <p>I noticed the <code>Stream</code> class has several methods</p>
  
  <pre><code>Stream::mapToInt
  Stream::mapToDouble
  Stream::mapToLong
  </code></pre>
  
  <p>Each of which has a convenient <code>sum()</code> method. But, as we know, <code>float</code> and <code>double</code> arithmetic is almost always a bad idea.</p>
  
  <p>So, is there a convenient way to sum up BigDecimals?</p>
  
  <p>This is the code I have so far.</p>
  
  <pre><code>public static void main(String[] args) {
      LinkedList&lt;BigDecimal&gt; values = new LinkedList&lt;&gt;();
      values.add(BigDecimal.valueOf(.1));
      values.add(BigDecimal.valueOf(1.1));
      values.add(BigDecimal.valueOf(2.1));
      values.add(BigDecimal.valueOf(.1));
  
      // Classical Java approach
      BigDecimal sum = BigDecimal.ZERO;
      for(BigDecimal value : values) {
          System.out.println(value);
          sum = sum.add(value);
      }
      System.out.println("Sum = " + sum);
  
      // Java 8 approach
      values.forEach((value) -&gt; System.out.println(value));
      System.out.println("Sum = " + values.stream().mapToDouble(BigDecimal::doubleValue).sum());
      System.out.println(values.stream().mapToDouble(BigDecimal::doubleValue).summaryStatistics().toString());
  }
  </code></pre>
  
  <p>As you can see, I am summing up the BigDecimals using <code>BigDecimal::doubleValue()</code>, but this is (as expected) not precise.</p>
  
  <p><strong>Post-answer edit for posterity:</strong></p>
  
  <p>Both answers were extremely helpful. I wanted to add a little: my real-life scenario does not involve a collection of raw <code>BigDecimal</code>s, they are wrapped in an invoice. But, I was able to modify Aman Agnihotri's answer to account for this by using the <code>map()</code> function for stream:</p>
  
  <pre><code>public static void main(String[] args) {
  
      LinkedList&lt;Invoice&gt; invoices = new LinkedList&lt;&gt;();
      invoices.add(new Invoice("C1", "I-001", BigDecimal.valueOf(.1), BigDecimal.valueOf(10)));
      invoices.add(new Invoice("C2", "I-002", BigDecimal.valueOf(.7), BigDecimal.valueOf(13)));
      invoices.add(new Invoice("C3", "I-003", BigDecimal.valueOf(2.3), BigDecimal.valueOf(8)));
      invoices.add(new Invoice("C4", "I-004", BigDecimal.valueOf(1.2), BigDecimal.valueOf(7)));
  
      // Classical Java approach
      BigDecimal sum = BigDecimal.ZERO;
      for(Invoice invoice : invoices) {
          BigDecimal total = invoice.unit_price.multiply(invoice.quantity);
          System.out.println(total);
          sum = sum.add(total);
      }
      System.out.println("Sum = " + sum);
  
      // Java 8 approach
      invoices.forEach((invoice) -&gt; System.out.println(invoice.total()));
      System.out.println("Sum = " + invoices.stream().map((x) -&gt; x.total()).reduce((x, y) -&gt; x.add(y)).get());
  }
  
  static class Invoice {
      String company;
      String invoice_number;
      BigDecimal unit_price;
      BigDecimal quantity;
  
      public Invoice() {
          unit_price = BigDecimal.ZERO;
          quantity = BigDecimal.ZERO;
      }
  
      public Invoice(String company, String invoice_number, BigDecimal unit_price, BigDecimal quantity) {
          this.company = company;
          this.invoice_number = invoice_number;
          this.unit_price = unit_price;
          this.quantity = quantity;
      }
  
      public BigDecimal total() {
          return unit_price.multiply(quantity);
      }
  
      public void setUnit_price(BigDecimal unit_price) {
          this.unit_price = unit_price;
      }
  
      public void setQuantity(BigDecimal quantity) {
          this.quantity = quantity;
      }
  
      public void setInvoice_number(String invoice_number) {
          this.invoice_number = invoice_number;
      }
  
      public void setCompany(String company) {
          this.company = company;
      }
  
      public BigDecimal getUnit_price() {
          return unit_price;
      }
  
      public BigDecimal getQuantity() {
          return quantity;
      }
  
      public String getInvoice_number() {
          return invoice_number;
      }
  
      public String getCompany() {
          return company;
      }
  }
  </code></pre>