Ben LinkedList
birlikte eklemek istiyorum BigDecimals (bu örnekte, a ) bir koleksiyon var . Bunun için akış kullanmak mümkün mü?
Stream
Sınıfın birkaç yöntemi olduğunu fark ettim
Stream::mapToInt
Stream::mapToDouble
Stream::mapToLong
Her birinin uygun bir sum()
yöntemi vardır. Ancak, bildiğimiz gibi float
ve double
aritmetik neredeyse her zaman kötü bir fikirdir.
Yani, BigDecimal'leri özetlemenin uygun bir yolu var mı?
Bu şimdiye kadar sahip olduğum kod.
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());
}
Gördüğünüz gibi, BigDecimal'leri kullanarak özetliyorum BigDecimal::doubleValue()
, ancak bu (beklendiği gibi) kesin değil.
Postity için cevap sonrası düzenleme:
Her iki cevap da son derece yardımcı oldu. Biraz eklemek istedim: Gerçek hayat senaryom ham koleksiyon içermiyor BigDecimal
, bir faturaya sarılıyor. Ancak, map()
akış için işlevi kullanarak Aman Agnihotri'nin cevabını bunun hesabını değiştirebildim :
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
Vs için +1invoice -> invoice.total()
.