I have a list of Request objects (id, amount, price), as shown
List<Request> requests = Arrays.asList(
new Request(id++, 20, 59.28),
new Request(id++, 10, 61.23),
new Request(id++, 30, 60.67),
new Request(id++, 25, 60.16),
new Request(id++, 60, 59.67));
and I want to calculate two metrics - sum (sum) and sum (sum * price) - in one iteration. I need them to calculate the average price: amount (amount * price) / amount (amount).
Whereas I want to use Java 8 threads, the only option I found is to map the value to the Pair object and implement the user user:
static class Aggregate implements Consumer<Pair<Double, Double>> {
private double count = 0L;
private double sum = 0L;
public double average() {
return count > 0 ? sum/(double) count : 0;
}
public void combine(Aggregate other) {
count += other.count;
sum += other.sum;
}
@Override
public void accept(Pair<Double, Double> data) {
this.count += data.getLeft();
this.sum += data.getLeft() * data.getRight();
}
}
Double avgPrice = requests.stream()
.map(e -> Pair.<Double, Double>of(e.getAmount(), e.getPrice()))
.collect(Aggregate::new, Aggregate::accept, Aggregate::combine)
.average();
This approach seems rather confusing - we need to create an additional Pair object for each record :(
Does anyone know a better solution?