Definition
This uses an inclusive range plus a numeric terminal operation on a primitive int stream.
- IntStream.rangeClosed(1, 100) – an inclusive range that emits
1, 2, ..., 100, including the end value. - sum() – a terminal operation on
IntStreamthat adds all elements and returns anint. - Result 5050 – equals the arithmetic series formula
n(n + 1) / 2withn = 100. - Inclusive end –
rangeClosedis right because 100 is a value you want counted, not merely a boundary. - No boxing –
IntStreamkeeps values as primitive ints, so the aggregation avoidsIntegerwrappers.
At the National Bank of India, Rajesh must tally the deposits made on each of the first 100 days of a scheme, where day one deposited one rupee, day two deposited two, and so on up to day 100. rangeClosed(1, 100) lays out all 100 days including the last one, because day 100 is a real day with a real deposit. sum() is the adding machine that runs down the whole column and prints the grand total, 5050. He does not stop at day 99; the closed range makes sure day 100 is included.
Understanding the Concepts
How do you compute the sum of 1 to 100?
Build the inclusive range with rangeClosed(1, 100) and call the sum() terminal operation. sum() adds every element and returns an int.
package com.bank.demo;
import java.util.stream.IntStream;
public class SumFirstHundred {
public static void main(String[] args) {
int total = IntStream.rangeClosed(1, 100).sum();
System.out.println("sum 1..100 = " + total);
}
}
sum 1..100 = 5050
Why rangeClosed and not range?
rangeClosed(1, 100) includes 100, while range(1, 100) stops at 99 and would give 4950. To include 100 with range you must write range(1, 101).
| Expression | Produces | Sum |
|------------|----------|-----|
| range(1, 100) | 1 to 99 | 4950 |
| range(1, 101) | 1 to 100 | 5050 |
| rangeClosed(1, 100) | 1 to 100 | 5050 |
package com.bank.demo;
import java.util.stream.IntStream;
public class RangeChoice {
public static void main(String[] args) {
System.out.println("range(1,100) = " + IntStream.range(1, 100).sum());
System.out.println("range(1,101) = " + IntStream.range(1, 101).sum());
System.out.println("rangeClosed(1,100) = " + IntStream.rangeClosed(1, 100).sum());
}
}
range(1,100) = 4950
range(1,101) = 5050
rangeClosed(1,100) = 5050
How does the result match the arithmetic formula?
The sum of the first n natural numbers is n(n + 1) / 2. For n = 100 that is 100 * 101 / 2 = 5050, which matches the stream result and is a good sanity check.
package com.bank.demo;
import java.util.stream.IntStream;
public class FormulaCheck {
public static void main(String[] args) {
int n = 100;
int streamSum = IntStream.rangeClosed(1, n).sum();
int formulaSum = n * (n + 1) / 2;
System.out.println("stream = " + streamSum);
System.out.println("formula = " + formulaSum);
System.out.println("equal? = " + (streamSum == formulaSum));
}
}
stream = 5050
formula = 5050
equal? = true
What is the difference between sum() and reduce()?
sum() is a specialized terminal operation that exists on primitive streams. reduce(identity, op) is the general-purpose fold that can express the same computation and more.
package com.bank.demo;
import java.util.stream.IntStream;
public class SumVsReduce {
public static void main(String[] args) {
int withSum = IntStream.rangeClosed(1, 100).sum();
int withReduce = IntStream.rangeClosed(1, 100).reduce(0, Integer::sum);
int withLambda = IntStream.rangeClosed(1, 100).reduce(0, (a, b) -> a + b);
System.out.println(withSum + " " + withReduce + " " + withLambda);
}
}
5050 5050 5050
Use sum() when you just need a total; use reduce when the combining logic is custom.
What are common mistakes?
The two frequent errors are an off-by-one on the bound and using count() when you meant sum().
// WRONG: range is exclusive, so this sums 1..99 and gives 4950, not 5050
int wrong = IntStream.range(1, 100).sum();
// WRONG: count() returns how many elements (100), not their sum
long alsoWrong = IntStream.rangeClosed(1, 100).count();
// CORRECT: rangeClosed includes 100, and sum() totals the values
int correct = IntStream.rangeClosed(1, 100).sum(); // 5050
The first wrong version silently undercounts by missing 100. The second returns the element count, 100, which is a different question.
When can the sum overflow, and how do you prevent it?
IntStream.sum() returns an int, which caps near 2.1 billion. Summing a large range overflows and wraps to a negative or wrong value. Convert to a long stream with asLongStream() before summing.
package com.bank.demo;
import java.util.stream.IntStream;
public class OverflowSafety {
public static void main(String[] args) {
// Large range: int sum overflows
int overflow = IntStream.rangeClosed(1, 100_000).sum();
// Safe: promote to long before summing
long safe = IntStream.rangeClosed(1, 100_000).asLongStream().sum();
System.out.println("int sum = " + overflow);
System.out.println("long sum = " + safe);
}
}
int sum = 705082704
long sum = 5000050000
The int result is wrong because the true total exceeds Integer.MAX_VALUE; the long result is correct.
How does sum() compare with Stream?
IntStream.sum() works on primitive ints with no boxing. A Stream must unbox each Integer or map to an IntStream first, which is slower and more verbose.
| Aspect | IntStream.sum() | Stream<Integer> | |--------|-----------------|------------------| | Element type | primitive `int` | boxed `Integer` | | Boxing overhead | none | one object per element | | Summing | `sum()` directly | `mapToInt(i -> i).sum()` | | Readability | high | lower |
package com.bank.demo;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class IntVsBoxedSum {
public static void main(String[] args) {
int primitive = IntStream.rangeClosed(1, 100).sum();
int boxed = Stream.iterate(1, n -> n + 1).limit(100)
.mapToInt(Integer::intValue).sum();
System.out.println(primitive + " " + boxed);
}
}
5050 5050
How is this applied in a banking context?
Suppose a recurring-deposit scheme adds one rupee on day one, two on day two, and so on for 100 days. The total deposited is the sum of 1 to 100. Money uses BigDecimal, so map each int to a BigDecimal and reduce.
package com.bank.deposit;
import java.math.BigDecimal;
import java.util.stream.IntStream;
public class SchemeTotal {
public static void main(String[] args) {
BigDecimal total = IntStream.rangeClosed(1, 100)
.mapToObj(BigDecimal::valueOf)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("total deposited = " + total);
}
}
total deposited = 5050
For money you reduce with BigDecimal rather than sum(), because sum() exists only on primitive numeric streams.
What are the edge cases?
A range where start == end in rangeClosed still yields one element, and an empty range sums to zero.
package com.bank.demo;
import java.util.stream.IntStream;
public class EdgeCases {
public static void main(String[] args) {
System.out.println("rangeClosed(5,5).sum() = " + IntStream.rangeClosed(5, 5).sum());
System.out.println("range(5,5).sum() = " + IntStream.range(5, 5).sum());
}
}
rangeClosed(5,5).sum() = 5
range(5,5).sum() = 0
rangeClosed(5, 5) includes the single value 5, while range(5, 5) is empty and sums to 0.
How do average, max, and min relate to sum?
IntStream offers a family of numeric terminals. summaryStatistics() computes several at once in a single pass.
package com.bank.demo;
import java.util.IntSummaryStatistics;
import java.util.stream.IntStream;
public class Stats {
public static void main(String[] args) {
IntSummaryStatistics stats = IntStream.rangeClosed(1, 100).summaryStatistics();
System.out.println("count = " + stats.getCount());
System.out.println("sum = " + stats.getSum());
System.out.println("min = " + stats.getMin());
System.out.println("max = " + stats.getMax());
System.out.println("avg = " + stats.getAverage());
}
}
count = 100
sum = 5050
min = 1
max = 100
avg = 50.5
Can you sum in parallel?
Because addition is associative, summing parallelizes safely. For a range of this size parallelism is not worth the overhead, but the result is identical.
package com.bank.demo;
import java.util.stream.IntStream;
public class ParallelSum {
public static void main(String[] args) {
long sum = IntStream.rangeClosed(1, 100).asLongStream().parallel().sum();
System.out.println("parallel sum = " + sum);
}
}
parallel sum = 5050
What are common interview follow-up questions?
Interviewers ask why rangeClosed is used instead of range, how the result relates to n(n+1)/2, when sum() overflows and how asLongStream() fixes it, the difference between sum() and reduce(), and why IntStream beats Stream for numeric totals. A tight answer: rangeClosed includes 100, the sum is 5050 by the arithmetic series formula, int sums can overflow so promote to long, sum() is the specialized form of reduce(0, Integer::sum), and IntStream avoids boxing.
Visual Overview
IntStream.rangeClosed(1, 100) // inclusive: 100 is counted
1 2 3 ... 99 100
└───────┬──────────┘
│ sum()
▼
┌─────────────────────┐
│ 1 + 2 + ... + 100 │
│ = 5050 │
└─────────────────────┘
range vs rangeClosed for summing to 100
range(1, 100) -> 1 .. 99 -> sum 4950 (misses 100)
range(1, 101) -> 1 .. 100 -> sum 5050
rangeClosed(1, 100) -> 1 .. 100 -> sum 5050 (clearest)
Overflow guard for large ranges
IntStream.rangeClosed(1, 100000).sum()
│ int result overflows Integer.MAX_VALUE
▼
705082704 (WRONG, wrapped)
IntStream.rangeClosed(1, 100000).asLongStream().sum()
│ long holds the full total
▼
5000050000 (CORRECT)
Key Takeaway
At the National Bank of India, Rajesh needs the total of a 100-day recurring-deposit scheme where day one adds one rupee, day two adds two, and so on to day 100. He lays out all 100 days with IntStream.rangeClosed(1, 100), choosing the closed form because day 100 is a real day that must be included. Had he used the exclusive range(1, 100), he would have stopped at day 99 and quietly lost the final deposit.
With the range in place, sum() is the adding machine. It runs down the whole column and returns 5050. He can confirm the figure with the arithmetic series formula n(n + 1) / 2, which for n = 100 gives 100 * 101 / 2 = 5050, a handy sanity check that the stream and the math agree.
sum() is the specialized, readable form of the more general reduce(0, Integer::sum), and it exists because IntStream carries primitive ints with no boxing, which keeps the aggregation fast. The same family gives average, min, max, and summaryStatistics for several results in one pass.
The one trap to respect is overflow. IntStream.sum() returns an int, so a large range can exceed Integer.MAX_VALUE and wrap to a wrong value. Promoting with asLongStream().sum() holds the full total. For money, Rajesh reduces with BigDecimal instead of sum(), since sum() lives only on primitive numeric streams.
Remember one sentence: rangeClosed(1, 100) includes 100 and sum() totals it to 5050, but switch to asLongStream().sum() when the total could overflow an int.
---