Tôi có một bộ sưu tập BigDecimals (trong ví dụ này, a LinkedList
) mà tôi muốn thêm vào với nhau. Có thể sử dụng các luồng cho việc này?
Tôi nhận thấy Stream
lớp học có một số phương pháp
Stream::mapToInt
Stream::mapToDouble
Stream::mapToLong
Mỗi trong số đó có một sum()
phương pháp thuận tiện . Nhưng, như chúng ta đã biết, float
và double
số học hầu như luôn là một ý tưởng tồi.
Vì vậy, có cách nào thuận tiện để tổng hợp BigDecimals không?
Đây là mã tôi có cho đến nay.
public static void main(String[] args) {
LinkedList<BigDecimal> values = new LinkedList<>();
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) -> System.out.println(value));
System.out.println("Sum = " + values.stream().mapToDouble(BigDecimal::doubleValue).sum());
System.out.println(values.stream().mapToDouble(BigDecimal::doubleValue).summaryStatistics().toString());
}
Như bạn có thể thấy, tôi đang tóm tắt BigDecimals bằng cách sử dụng BigDecimal::doubleValue()
, nhưng điều này (như mong đợi) không chính xác.
Chỉnh sửa sau câu trả lời cho hậu thế:
Cả hai câu trả lời đều rất hữu ích. Tôi muốn thêm một chút: kịch bản đời thực của tôi không liên quan đến một bộ sưu tập BigDecimal
s thô , chúng được gói trong một hóa đơn. Nhưng, tôi đã có thể sửa đổi câu trả lời của Aman Agnihotri để giải thích điều này bằng cách sử dụng map()
chức năng cho luồng:
public static void main(String[] args) {
LinkedList<Invoice> invoices = new LinkedList<>();
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) -> System.out.println(invoice.total()));
System.out.println("Sum = " + invoices.stream().map((x) -> x.total()).reduce((x, y) -> 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;
}
}
Invoice::total
so vớiinvoice -> invoice.total()
.