Multi-stream: weighted average using a second list of weights

A weighted average is two sums over the same joined stream, divided. The weights do not have to add up to one - dividing by the total weight normalises them, which is what makes the code survive a weight being added later.

Code
record Mark(String subject, double score) {}
record Weight(String subject, double weight) {}

var marks = List.of(new Mark("maths", 80.0), new Mark("physics", 60.0), new Mark("art", 90.0));
var weights = List.of(new Weight("maths", 5.0), new Weight("physics", 3.0), new Weight("art", 2.0));

Map<String, Double> w = weights.stream().collect(Collectors.toMap(Weight::subject, Weight::weight));

double weighted = marks.stream().mapToDouble(m -> m.score() * w.getOrDefault(m.subject(), 0.0)).sum();
double totalWeight = marks.stream().mapToDouble(m -> w.getOrDefault(m.subject(), 0.0)).sum();

System.out.println("plain average   : " + marks.stream().mapToDouble(Mark::score).average().orElse(0));
System.out.println("weighted average: " + (weighted / totalWeight));
Output
plain average   : 76.66666666666667
weighted average: 76.0
Advertisement
More in JAVA

Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.

Published 2026-09-20

© Java Coding Hub · About · Contact · Privacy · Terms