The straight-forward way is to create a custom collector class.
public class StockStatistics {
private DoubleSummaryStatistics profitStat = new DoubleSummaryStatistics();
private DoubleSummaryStatistics profitPercentageStat = new DoubleSummaryStatistics();
public void accept(Stock stock) {
profitStat.accept(stock.getProfit());
profitPercentageStat.accept(stock.getProfitPercentage());
}
public StockStatistics combine(StockStatistics other) {
profitStat.combine(other.profitStat);
profitPercentageStat.combine(other.profitPercentageStat);
return this;
}
public static Collector<Stock, ?, StockStatistics> collector() {
return Collector.of(StockStatistics::new, StockStatistics::accept, StockStatistics::combine);
}
public DoubleSummaryStatistics getProfitStat() {
return profitStat;
}
public DoubleSummaryStatistics getProfitPercentageStat() {
return profitPercentageStat;
}
}
This class serves as a wrapper around two DoubleSummaryStatistics
. It delegates to them each time an element is accepted. In your case, since you're only interested in the sum, you could even use a Collectors.summingDouble
instead of DoubleSummaryStatistics
. Also, it returns the two statistics with getProfitStat
and getProfitPercentageStat
; alternatively, you could add a finisher operation that would return a double[]
containing only both sums.
Then, you can use
StockStatistics stats = stocks.stream().collect(StockStatistics.collector());
System.out.println(stats.getProfitStat().getSum());
System.out.println(stats.getProfitPercentageStat().getSum());
A more generic way is to create a collector capable of pairing other collectors. You can use the pairing
collector written in this answer and, also available in the StreamEx library.
double[] sums = stocks.stream().collect(MoreCollectors.pairing(
Collectors.summingDouble(Stock::getProfit),
Collectors.summingDouble(Stock::getProfitPercentage),
(sum1, sum2) -> new double[] { sum1, sum2 }
));
The sum of the profit will be in sums[0]
and the sum of the profit percentage will be in sums[1]
. In this snippet, only the sums are kept and not the whole stats.