The average of N numbers is their sum divided by N, so in Java we add the numbers in a double or long variable and divide the sum by the count, or we call average() on a stream. Learn to calculate the average of N numbers in Java from user input, from an array and from an ArrayList, and to handle the cases that give wrong results.
We calculate averages for product ratings, exam marks, monthly expenses and response times in monitoring dashboards. The three methods in this article differ in how the program receives the numbers.
The following example calculates the average rating of a recipe, once with a loop and once with a stream.
double[] ratings = {4.5, 3.0, 5.0, 4.0};
double sum = 0;
for (double rating : ratings) {
sum += rating;
}
double average = sum / ratings.length; // 4.125
double streamAverage = Arrays.stream(ratings).average().orElse(0.0); // 4.125
The stream version returns an OptionalDouble, because an empty array has no average. After the algorithm, we read numbers from the console, average arrays and lists, avoid integer division and overflow, use BigDecimal for money and build a moving average for a dashboard.
1. Algorithm for Calculating the Average
In simple words, to calculate the average of N numbers, we add all the numbers and divide their sum by N. The formula is average = (x1 + x2 + … + xN) / N, so the average of 10, 20 and 60 is 90 / 3 = 30.

In pseudo-code, the steps work for any N, because the program counts the numbers while it reads them.
Step 1 : Start
Step 2 : sum = 0, count = 0
Step 3 : Read the next number x. If there is no number left, go to step 5
Step 4 : sum = sum + x, count = count + 1, go to step 3
Step 5 : If count = 0, display "no numbers" and go to step 8
Step 6 : average = sum / count
Step 7 : Display average
Step 8 : Stop
Two details decide whether the result is correct in Java. The division must be a floating-point division, and the sum must use a type that is large enough for all the numbers.
1.1. Integer Division Truncates the Average
When both the sum and the count are int values, Java performs integer division and drops the decimal part before the result reaches the double variable. We cast one of the two operands to double to get the exact average.
int total = 7;
int count = 2;
double wrong = total / count; // 3.0
double right = (double) total / count; // 3.5
The assignment to double wrong does not help, because Java computes 7 / 2 = 3 first and only converts the finished result.
2. Program to Calculate the Average of Numbers Entered by the User
We read the user input with the Scanner class, which is covered with the other options in the console input and output guide. The safe version checks every token with hasNextDouble(), so a typo such as abc is skipped instead of stopping the program with an InputMismatchException.
static OptionalDouble readAverage(Scanner scanner) {
scanner.useLocale(Locale.ROOT);
double sum = 0;
int count = 0;
while (scanner.hasNext()) {
if (scanner.hasNextDouble()) {
sum += scanner.nextDouble();
count++;
} else {
scanner.next(); // skip a token that is not a number
}
}
return count == 0 ? OptionalDouble.empty() : OptionalDouble.of(sum / count);
}
The call useLocale(Locale.ROOT) makes the scanner accept a dot as the decimal separator on every machine. With a German default locale, Scanner expects 10,3 and treats 10.3 as an invalid token, so the user’s numbers would be skipped.
OptionalDouble result = readAverage(new Scanner("10.3 20.6 abc 30.9 5 10"));
String shown = String.format(Locale.ROOT, "%.2f", result.orElse(0.0)); // "15.36"
OptionalDouble none = readAverage(new Scanner("abc")); // OptionalDouble.empty
In the console program, we pass new Scanner(System.in) and the user ends the input with Ctrl+D on Linux and macOS, or Ctrl+Z and Enter on Windows. A run with the same input prints the average with two decimals.
Enter numbers separated by spaces, then end the input:
10.3 20.6 abc 30.9 5 10
The average is: 15.36
3. Program to Calculate the Average of Numbers in an Array
Calculating the average of all numbers in an array is very similar to the previous program. Here we have an array that is already populated, so the count is array.length. The primitive streams IntStream, LongStream and DoubleStream have an average() method that does the same work in one line.
int[] marks = {72, 85, 90, 64, 78};
long sum = 0;
for (int mark : marks) {
sum += mark;
}
double average = (double) sum / marks.length; // 77.8
double streamAverage = Arrays.stream(marks).average().orElse(0); // 77.8
For the sum and the average of one array together, the sum and average of an array article shows IntSummaryStatistics and more array variants.
3.1. Empty Arrays and Overflow
An empty array has no average, and each version reports that differently. Division by zero with double values returns NaN, division by zero with int values throws ArithmeticException, and average() returns an empty OptionalDouble.
double[] none = {};
double emptySum = 0;
double nanAverage = emptySum / none.length; // NaN
OptionalDouble emptyAverage = Arrays.stream(none).average(); // OptionalDouble.empty
int intAverage = 0 / none.length; // ArithmeticException: / by zero
Overflow is the second trap. Video view counts of 2 billion each fit in an int, but their sum does not, so an int sum wraps around to a negative number. The IntStream.average() method adds the values in a long, so it returns the correct average, whereas IntStream.sum() returns an int and overflows.
int[] views = {2_000_000_000, 2_000_000_000};
int intSum = views[0] + views[1]; // -294967296
int streamSum = Arrays.stream(views).sum(); // -294967296
long longSum = Arrays.stream(views).asLongStream().sum(); // 4000000000
double viewAverage = Arrays.stream(views).average().orElse(0); // 2.0E9
4. Program to Calculate the Average of Numbers in an ArrayList
Since Java 8, the Stream API lets us calculate the average of a list in one statement. A List<Double> holds boxed values, so we first convert it to a DoubleStream with mapToDouble(), and DoubleStream.average() does the rest. For a List<Integer>, we use mapToInt() in the same way.
List<Double> temperatures = new ArrayList<>(List.of(21.5, 23.0, 19.5, 22.0));
double average = temperatures.stream().mapToDouble(Double::doubleValue).average().orElse(Double.NaN); // 21.5
double viaCollector = temperatures.stream().collect(Collectors.averagingDouble(t -> t)); // 21.5
The collector Collectors.averagingDouble() is useful inside groupingBy(), for example, to get the average temperature per city. It returns 0.0 for an empty list, whereas average() returns an empty OptionalDouble, so only the stream version lets us tell an empty list apart from a real average of zero.
List<Double> noReadings = List.of();
double collectorEmpty = noReadings.stream().collect(Collectors.averagingDouble(t -> t)); // 0.0
boolean hasAverage = noReadings.stream().mapToDouble(t -> t).average().isPresent(); // false
When we need the minimum and maximum next to the average, summaryStatistics() computes all of them in one pass over the list.
List<Double> temperatures = List.of(21.5, 23.0, 19.5, 22.0);
DoubleSummaryStatistics stats = temperatures.stream().mapToDouble(Double::doubleValue).summaryStatistics();
double min = stats.getMin(); // 19.5
double max = stats.getMax(); // 23.0
double mean = stats.getAverage(); // 21.5
5. Average of Money Values With BigDecimal
Prices and invoice amounts should never be averaged as double values, because double cannot store most decimal fractions without a rounding error, as the float and double comparison article shows. An online shop that reports its average order value uses BigDecimal and states the scale and the rounding mode of the division.
List<BigDecimal> orders = List.of(new BigDecimal("19.99"), new BigDecimal("5.49"), new BigDecimal("12.00"));
BigDecimal total = orders.stream().reduce(BigDecimal.ZERO, BigDecimal::add); // 37.48
BigDecimal count = BigDecimal.valueOf(orders.size());
BigDecimal averageOrder = total.divide(count, 2, RoundingMode.HALF_EVEN); // 12.49
BigDecimal unrounded = total.divide(count); // ArithmeticException: Non-terminating decimal expansion
The last line shows why the scale matters. The exact result of 37.48 / 3 has infinitely many digits, so divide() without a scale throws ArithmeticException.
6. Moving Average for a Monitoring Dashboard
A monitoring dashboard shows the average response time of an API, but an average over all requests since startup hides a slow minute. A moving average uses only the last few values, so the number on the screen follows the current load. The following example keeps the last values in an ArrayDeque and updates the sum when a value enters or leaves the window, so each update costs the same small amount of work.
final class MovingAverage {
private final int window;
private final Deque<Long> values = new ArrayDeque<>();
private long sum;
MovingAverage(int window) {
this.window = window;
}
double add(long value) {
values.addLast(value);
sum += value;
if (values.size() > window) {
sum -= values.removeFirst();
}
return (double) sum / values.size();
}
}
MovingAverage latency = new MovingAverage(3);
double first = latency.add(120); // 120.0
double second = latency.add(80); // 100.0
double third = latency.add(100); // 100.0
double fourth = latency.add(300); // 160.0
We can see that the fourth call drops the value 120, so the result is (80 + 100 + 300) / 3 = 160.0, and the spike is visible at once.
7. Average of N Numbers FAQs
Rounding, empty input and picking mean or median are where average programs in assignments and code reviews go wrong most often.
7.1. How do we calculate the average without storing the numbers?
We keep a running sum and a count, as the readAverage() method in section 2 does. Neither the array nor the list is needed when the numbers arrive one by one from the console, a file or a network stream.
7.2. How do we show the average with only two decimals?
For display, we format the value and leave the double unchanged. For a rounded value, we use Math.round(), or BigDecimal.setScale() for money. The decimal formatting article covers DecimalFormat as well.
double avg = 15.3563;
String text = String.format(Locale.ROOT, "%.2f", avg); // "15.36"
double rounded = Math.round(avg * 100) / 100.0; // 15.36
BigDecimal exact = BigDecimal.valueOf(avg).setScale(2, RoundingMode.HALF_UP); // 15.36
7.3. What does average() return for an empty stream?
The method returns OptionalDouble.empty(), because a stream with zero elements has no average. We decide the fallback with orElse(), or throw an exception with orElseThrow().
7.4. What is the difference between the mean, the median and the average?
The average in everyday speech is the arithmetic mean, i.e. the sum divided by the count. The median is the middle value of the sorted numbers, and it is not pulled up by one very large value, which is why salary and house price reports use it.
double[] salaries = {3200, 3500, 3900, 4100, 25000};
double meanSalary = Arrays.stream(salaries).average().orElse(0); // 7940.0
double[] sorted = salaries.clone();
Arrays.sort(sorted);
double medianSalary = sorted[sorted.length / 2]; // 3900.0
7.5. How do we calculate a weighted average?
We multiply each value by its weight, add the products and divide by the sum of the weights. For example, a course grade where the final exam counts twice as much as each of two tests uses the weights 1, 1 and 2.
double[] scores = {70, 80, 90};
double[] weights = {1, 1, 2};
double weightedSum = 0;
double weightTotal = 0;
for (int i = 0; i < scores.length; i++) {
weightedSum += scores[i] * weights[i];
weightTotal += weights[i];
}
double grade = weightedSum / weightTotal; // 82.5
8. Conclusion
The average of N numbers is the sum divided by the count. In Java, we cast before dividing to avoid integer division, add int values in a long to avoid overflow, and decide what an empty input should return.
For arrays and lists, average() on a primitive stream does all of that in one line and returns an OptionalDouble. We use BigDecimal with an explicit scale for money, and a moving average when only the latest values matter. More beginner programs of this kind are in our Java examples collection.
9. References
- IntStream (Java SE 25 API)
- DoubleStream (Java SE 25 API)
- Collectors (Java SE 25 API)
- Scanner (Java SE 25 API)
- BigDecimal (Java SE 25 API)
- JLS 25, Division Operator /
Happy Learning !!