Jay
Jay

Reputation: 9479

Java8 stream - combine the finding of sum, positive result and average result into single step

Is it possible to combine the below 3 steps into a single step?

private double calculateTotalBCMMatrixCost(SpecificationEntryRequest specificationEntryRequest) {

        // Finds the total BCM matrix cost
        double totalBcmMatrixCost = specificationEntryRequest.getComponentList().stream()
                .map(ComponentDetail::getStartingMaterialId)
                .map(this::calculateBCMMatrixCostForAnalyte)
                .collect(Collectors.summingDouble(Double::doubleValue));

        // Finds the non zero cost count
        long nonZeroPriceCount = specificationEntryRequest.getComponentList().stream()
                .map(ComponentDetail::getStartingMaterialId)
                .map(this::calculateBCMMatrixCostForAnalyte)
                .filter(price -> price > 0).count();

        // returns the average cost
        return totalBcmMatrixCost / nonZeroPriceCount;
    }

Upvotes: 1

Views: 267

Answers (1)

Eran
Eran

Reputation: 393811

Use DoubleSummaryStatistics:

DoubleSummaryStatistics stats = specificationEntryRequest.getComponentList().stream()
    .map(ComponentDetail::getStartingMaterialId)
    .mapToDouble(this::calculateBCMMatrixCostForAnalyte)
    .filter(price -> price > 0)
    .summaryStatistics();
double totalBcmMatrixCost = stats.gtSum ();
long nonZeroPriceCount = stats.getCount ();
double average = stats.getAverage ();

Or course, if you only need the average (that's what your method is returning), you can use:

return specificationEntryRequest.getComponentList().stream()
    .map(ComponentDetail::getStartingMaterialId)
    .mapToDouble(this::calculateBCMMatrixCostForAnalyte)
    .filter(price -> price > 0)
    .average()
    .orElse(0.0);

Upvotes: 4

Related Questions