Printing the bill table
The canteen wants a price chart on the wall: the bill for 1 chai, 2 chais, 3 chais… up to 10. Riya starts typing System.out.println ten times. Arjun Sir stops her at the fourth line.
Sir, it's only ten lines. Copy-paste is fine, right?
Today it's ten. Tomorrow the canteen wants 50, and the price changes to ₹22. Will you edit 50 lines? Write the work once and tell Java how many times to repeat it. That's a loop.
So one line of logic, and a counter that goes from 1 to 10?
Exactly. The for loop packs the counter's start, its stopping rule and its step into one line. Let's see the exact order Java runs them in.
What is a for loop?
The for loop is an entry-controlled loop with the syntax for (initialisation; condition; update) { body }. The initialisation runs once; then, as long as the boolean condition is true, the body executes followed by the update. When the condition becomes false, control passes to the statement after the loop. The enhanced for loop (for (Type x : collection)) iterates over every element of an array or Iterable.
Start a counter, check a condition, do the work, move the counter, check again… and stop when the condition fails. Use it when you know (or can calculate) how many times to repeat.
Words you'll meet in this lesson
i or cups, usually declared in the init part.< vs <=.The order of execution
| 1. Initialisation | Runs once, before anything else: int i = 1 |
|---|---|
| 2. Condition | Checked before every iteration. False → the loop ends immediately. |
| 3. Body | The statements in { } |
| 4. Update | Runs after the body: i++. Then back to step 2. |
| Times the body runs | for (i = 0; i < n; i++) → exactly n times; for (i = 1; i <= n; i++) → also n times |
| Scope | A variable declared in the init part exists only inside the loop |
Exam tip: for for (int i = 0; i < 5; i++), the condition is checked 6 times (5 true, 1 false), the body runs 5 times, and the update runs 5 times. All three parts are optional: for (;;) is an infinite loop.
Forms of the for loop
Counting up
for (int i = 1; i <= 10; i++)
The most common form.
Counting down
for (int i = 10; i >= 1; i--)
Countdowns, processing from the end.
Stepping
for (int i = 0; i <= 100; i += 5)
Every 5th value, every other row…
for-each
for (int m : marks)
Visits every element. No index, no off-by-one.
Classic for or for-each?
| Need | Use |
|---|---|
| Read every element in order | for-each |
| Need the index (position), e.g. “Day 3” | classic for |
| Change array elements, go backwards, or skip elements | classic for |
| Repeat a fixed number of times, no collection involved | classic for |
Several variables: the init and update parts can hold several comma-separated parts: for (int i = 0, j = 9; i < j; i++, j--) walks from both ends towards the middle, useful for reversing.
Writing a loop that's correct the first time
Decide the start value
Should the counter start at 0 or 1? Array positions start at 0; human counts usually start at 1.
The init part runs exactly once. Its variable gets a slot in the method's stack frame.Write the stopping condition carefully
“1 to 10 inclusive” is
javac places the condition check before the body and compiles it as a conditional jump that leaves the loop when it fails.i <= 10. “10 items starting at 0” isi < 10.Write the body
Put the work that repeats inside
A variable declared inside the body is recreated on every iteration. A total declared inside would reset to 0 each time.{ }. Use an accumulator declared before the loop for totals.Write the update
Usually
Fori++. Make sure it moves the counter towards making the condition false, or the loop never ends.i++, javac uses the compactiincinstruction, then agotothat jumps backwards to the condition. A loop is just a backward jump.Check the first and last iteration
Ask: what happens when i is at its start value? At its last value? Does it run 0 times when it should?
Hot loops are where the JIT compiler shines: after enough iterations, HotSpot compiles the loop to machine code, sometimes even while it's running (on-stack replacement).
Three iterations, every step: both views
The program prints the bill for 1, 2 and 3 cups and keeps a total. Left: the code and output. Right: the stack frame and the bytecode jumps.
- Initialisation runs once:
cups = 1. The total starts at 0. - Iteration 1: condition true, body prints Rs 20, total = 20, then the update makes cups 2.
- Iteration 2: body prints Rs 40, total = 60, cups becomes 3.
- Iteration 3: 3 ≤ 3 is still true (that's why we used ≤), total = 120, cups becomes 4.
- The condition is checked a 4th time: 4 ≤ 3 is false, so the loop ends.
- The statement after the loop prints Total: Rs 120.
- Two local slots:
totaland the loop variablecups, created by the init part. - The condition passes, the body runs,
iincadds 1 andgotojumps backwards to the check. - Same instructions again with cups = 2. total is now 60.
- Third pass: total reaches 120 and cups becomes 4.
- Now
if_icmpgt(if greater than) is true, so the JVM jumps forward to END. The loop is over. cupsbelonged to the loop; after it, onlytotalis in scope.
Loops behind everyday software
Any time software does something “for every…”, there's a loop underneath.
Watch it with an example: a 3-month EMI schedule
Riya buys a Rs 30,000 laptop on a 3-month no-cost EMI. One for loop prints the whole schedule. Watch the counter, the check and the update in every round.
- Initialise:
int m = 1runs once, before the first round. - Round 1: check
1 <= 3: true, so the body runs, prints month 1 and reducesdueto 20,000. Then the updatem++makes m = 2. - Round 2:
2 <= 3true → month 2, due 10,000, m = 3. - Round 3:
3 <= 3true → month 3, due 0, m = 4. - Exit:
4 <= 3is false, so the loop stops. The check runs one more time than the body. - Done: three rows printed by three lines of loop code. With 24 months you'd change only the 3. (No-cost EMI shown without interest, to keep it simple.)
1. Totals in carts and bills
A cart's total is a loop over its items: price × quantity, added up. Tax, discounts and delivery are applied after.
2. EMI and repayment schedules
Loan apps show a month-by-month schedule: interest, principal and remaining balance for each month. That's a loop from month 1 to n (see practice problem P10).
3. Reports and dashboards
Daily sales, attendance or website visits: a loop goes through the records once and computes totals, averages, the best day and how many days missed a target.
4. Retrying failed network calls
When a payment gateway or API call fails temporarily, services retry a limited number of times with a growing wait: for (int attempt = 1; attempt <= 3; attempt++).
5. Batch processing and pagination
Jobs that process lakhs of records do it in batches: for (int page = 0; page < totalPages; page++), fetching and handling 500 records at a time instead of loading everything at once.
Examples are simplified to show where loops fit. Real systems add error handling and logging.
The bill table
public class Main {
public static void main(String[] args) {
int total = 0;
for (int cups = 1; cups <= 3; cups++) {
int bill = cups * 20;
total += bill;
System.out.println(cups + " cup(s): Rs " + bill);
}
System.out.println("Total of all bills: Rs " + total);
}
}int total = 0;The accumulator, declared before the loop so it survives every iteration.int cups = 1Init: runs once.cups <= 3Condition: checked before every iteration (4 times here).cups++Update: runs after each body.int bill = cups * 20;Declared inside the body, so it's a fresh variable each iteration.
Every check, every iteration
Watch the tracer jump back to the for line after each iteration, and the condition fail on the fourth check.
Worked examples: real problems, solved and traced in memory
A for loop repeats work a known number of times. Each program below is a real job done with one loop. In the trace, watch the loop variable change, the condition being checked, and the running total grow on each pass.
Total and best day of the week
Problem statement
A shop records sales for 5 days. Find the total, the average and the best day using one for loop over the array.
sales {4200, 3800, 5100, 2900, 6100}Total: Rs 22100, average: Rs 4420 Best day: 5 (Rs 6100)
Approach
- Start
total = 0andbest = 0. - Loop over indexes 0 to length − 1, adding and comparing.
- Day numbers are index + 1.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
A recurring deposit year by year
Problem statement
A customer deposits Rs 10,000 at the start of each year for 4 years. The balance earns 7% interest at the end of each year. Print the balance after each year.
Rs 10,000 per year, 7%, 4 years
Year 1: Rs 10700 Year 2: Rs 22149 Year 3: Rs 34399 Year 4: Rs 47507
Approach
- Loop
yearfrom 1 to 4. - Add the deposit, then multiply by 1.07.
- Round when printing.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
Count digits and letters in a vehicle number
Problem statement
A parking app checks the number plate "MH12AB4521". Count how many characters are letters and how many are digits with a for loop over the String.
"MH12AB4521"
4 letters, 6 digits
Approach
- Loop over indexes of the String.
charAt(i)gets each character.Character.isDigit/isLetterclassify it.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
Check yourself
Quick revision
Lesson 3.3 in one screen
for (init; condition; update) { body }— init once; then check → body → update, repeat.- Entry-controlled: can run 0 times.
i = 0; i < nandi = 1; i <= nboth run n times. - Accumulators go before the loop; loop variables die with the loop.
- Count up, down (
i--) or in steps (i += 5); several variables with commas. - for-each:
for (Type x : array)— read every element, no index. - Off-by-one: check the first and last iteration. Update must move towards ending the loop.
- Bytecode: condition jump +
iinc+gotoback.
Interview and viva questions
What is the difference between for and while?
Both are entry-controlled. for keeps the init, condition and update together and suits a known number of iterations. while has only a condition and suits “repeat until something happens”, where the count isn't known in advance. Any for can be written as a while.
Is for (;;) valid?
Yes. All three parts are optional; an empty condition means true, so it's an infinite loop. It must be ended with break, return or an exception.
Can we modify the loop variable inside the body?
Yes, but it makes the loop hard to understand and is a common source of bugs. Keep changes to the loop variable in the update part.
What are the limitations of for-each?
No index, can't go backwards, can't skip elements, and assigning to the loop variable doesn't change the array. For collections, removing elements during for-each throws ConcurrentModificationException (Module 11).
How do you print on the same line in a loop?
Use System.out.print inside the loop and System.out.println() once after it. For many pieces, building a String with StringBuilder is faster (Lesson 4.6).
Practice problems
Loops are where problem-solving really starts. Try each one in the live editor before opening the solution. Problems get harder as you go; the last two are real business tasks.
Multiplication table
Print the multiplication table of n from 1 to 10.
n = 7
7 x 1 = 7 7 x 2 = 14 … 7 x 10 = 70
Show solution and explanation
public class Main {
public static void main(String[] args) {
int n = 7;
for (int i = 1; i <= 10; i++) {
System.out.println(n + " x " + i + " = " + (n * i));
}
}
}How it works: i runs from 1 to 10 inclusive (<=). The brackets around n * i keep the multiplication from being joined as text.
Sum of the first n numbers
Add up all whole numbers from 1 to n.
n = 100
Sum of 1 to 100 = 5050
Show solution and explanation
public class Main {
public static void main(String[] args) {
int n = 100;
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
System.out.println("Sum of 1 to " + n + " = " + sum);
}
}How it works: the classic accumulator pattern: start at 0, add each value. You can check the answer with the formula n × (n + 1) / 2 = 100 × 101 / 2 = 5050.
Even numbers on one line
Print all even numbers from 2 to limit on one line, separated by spaces.
limit = 20
2 4 6 8 10 12 14 16 18 20
Show solution and explanation
public class Main {
public static void main(String[] args) {
int limit = 20;
for (int i = 2; i <= limit; i += 2) {
System.out.print(i);
if (i + 2 <= limit) {
System.out.print(" ");
}
}
System.out.println();
}
}How it works: stepping by 2 from 2 visits only even numbers, half the work of checking i % 2 for every number. The small if avoids a trailing space after the last number, which matters when online judges compare output exactly.
Factorial
Calculate n! = 1 × 2 × 3 × … × n.
n = 10
10! = 3628800
Show solution and explanation
public class Main {
public static void main(String[] args) {
int n = 10;
long factorial = 1;
for (int i = 2; i <= n; i++) {
factorial *= i;
}
System.out.println(n + "! = " + factorial);
}
}How it works: a product accumulator starts at 1, not 0 (anything times 0 is 0). We use long because factorials grow very fast: 13! already overflows an int (Lesson 2.2). Even long overflows after 20!.
First n Fibonacci numbers
Print the first n terms of the Fibonacci series, where each term is the sum of the previous two: 0, 1, 1, 2, 3, 5…
n = 10
0 1 1 2 3 5 8 13 21 34
Show solution and explanation
public class Main {
public static void main(String[] args) {
int n = 10;
int a = 0, b = 1;
for (int i = 1; i <= n; i++) {
System.out.print(a + (i < n ? " " : "\n"));
int next = a + b;
a = b;
b = next;
}
}
}How it works: we keep only the last two terms, a and b. Each iteration prints a, then shifts the window forward: the new pair is (b, a + b). The ternary prints a space between terms and a newline after the last.
Is it a prime number?
A prime number has exactly two divisors: 1 and itself. Check whether n is prime, efficiently.
n = 97
97 is prime
Show solution and explanation
public class Main {
public static void main(String[] args) {
int n = 97;
boolean prime = n >= 2;
for (int d = 2; d * d <= n; d++) {
if (n % d == 0) {
prime = false;
break;
}
}
System.out.println(n + (prime ? " is prime" : " is not prime"));
}
}How it works:
- Numbers below 2 aren't prime, so
primestarts asn >= 2. - We only test divisors up to √n (
d * d <= n): if n = a × b, one of a or b is at most √n. For 97 that's 9 checks instead of 95. break(Lesson 3.5) stops as soon as a divisor is found.
Reverse a word
Print a word backwards using a loop.
word = "MyPhatshala"
alahstahPyM
Show solution and explanation
public class Main {
public static void main(String[] args) {
String word = "MyPhatshala";
String reversed = "";
for (int i = word.length() - 1; i >= 0; i--) {
reversed += word.charAt(i);
}
System.out.println(reversed);
}
}How it works: positions in a String go from 0 to length() - 1, so we count down from the last position to 0. charAt(i) gets one character. (For long strings, use StringBuilder instead of +=; Lesson 4.6 explains why.)
Count vowels in a sentence
Count how many vowels (a, e, i, o, u, upper or lower case) are in a sentence.
text = "Java runs on Every Device"
Vowels: 9
Show solution and explanation
public class Main {
public static void main(String[] args) {
String text = "Java runs on Every Device";
int count = 0;
for (char ch : text.toLowerCase().toCharArray()) {
if ("aeiou".indexOf(ch) >= 0) {
count++;
}
}
System.out.println("Vowels: " + count);
}
}How it works: toCharArray() turns the text into an array of chars, so a for-each loop can visit each one. Lowercasing first handles capitals. "aeiou".indexOf(ch) returns the position of ch in "aeiou", or −1 if it isn't there: a neat way to test membership.
Weekly sales report
A store records sales for 7 days. Print the total, the average per day, the best day (1–7) and how many days missed the daily target of ₹5,000.
sales = {4200, 6100, 5800, 3900, 7200, 8800, 4700}Total: Rs 40700 Average: Rs 5814.29 Best day: Day 6 (Rs 8800) Days below target: 3
Show solution and explanation
public class Main {
public static void main(String[] args) {
int[] sales = {4200, 6100, 5800, 3900, 7200, 8800, 4700};
final int TARGET = 5000;
int total = 0;
int bestDay = 0; // index of the best day so far
int missed = 0;
for (int i = 0; i < sales.length; i++) {
total += sales[i];
if (sales[i] > sales[bestDay]) {
bestDay = i;
}
if (sales[i] < TARGET) {
missed++;
}
}
double average = (double) total / sales.length;
System.out.println("Total: Rs " + total);
System.out.printf("Average: Rs %.2f%n", average);
System.out.println("Best day: Day " + (bestDay + 1) + " (Rs " + sales[bestDay] + ")");
System.out.println("Days below target: " + missed);
}
}How it works:
- One loop, three results: a sum, a “best so far” and a counter are all updated in the same pass. Real reports avoid looping over big data several times.
- We store the index of the best day, not just its value, because the report needs the day number. A classic for loop is used because we need the index.
- Arrays start at 0, humans at 1, so we print
bestDay + 1. - The average needs a cast to avoid integer division (Lesson 2.4);
printf("%.2f")rounds it to two decimals.
Loan EMI repayment schedule
A customer borrows ₹1,00,000 at 12% per year, repaid in 6 equal monthly instalments (EMIs). Calculate the EMI with the standard formula and print a schedule showing, for each month, the interest, the principal repaid and the remaining balance.
EMI = P × r × (1 + r)n ÷ ((1 + r)n − 1), where P is the loan, r the monthly rate and n the number of months.
principal = 100000, yearly rate = 12%, months = 6
EMI: Rs 17254.84
Month Interest Principal Balance
1 1000.00 16254.84 83745.16
…
6 170.84 17084.00 0.00Show solution and explanation
public class Main {
public static void main(String[] args) {
double principal = 100_000;
double monthlyRate = 12.0 / 12 / 100; // 12% a year = 1% a month
int months = 6;
double factor = Math.pow(1 + monthlyRate, months);
double emi = principal * monthlyRate * factor / (factor - 1);
System.out.printf("EMI: Rs %.2f%n", emi);
System.out.println("Month Interest Principal Balance");
double balance = principal;
for (int m = 1; m <= months; m++) {
double interest = balance * monthlyRate;
double principalPart = emi - interest;
balance -= principalPart;
System.out.printf("%5d %9.2f %10.2f %9.2f%n", m, interest, principalPart, Math.abs(balance));
}
}
}How it works:
- Monthly rate: 12% per year ÷ 12 months = 1% = 0.01 per month.
Math.powcalculates (1.01)6 once, before the loop, because it doesn't change.- Each month: interest is charged on the remaining balance; the rest of the EMI repays principal. That's why the interest part shrinks and the principal part grows every month.
printfwith widths like%9.2flines the columns up and rounds to paise.- Floating-point rounding can leave the final balance as a tiny negative like −0.0000001, which would print as “-0.00”, so we print
Math.abs(balance). A real bank would use BigDecimal and adjust the last instalment to clear the balance exactly.
Real-world scenario questions (asked in company interviews)
Loop bugs cause missing data, slow systems and hung servers. Decide your answer first, then open the model answer.
The last record is always missing
A monthly export writes customer records to a CSV. Finance notices the last customer is always missing. The loop is for (int i = 0; i < customers.length - 1; i++). A teammate wrote it “to avoid going out of bounds”. Explain and fix.
The interviewer is checking: do you spot off-by-one errors and understand array bounds?
Show a strong answer
Valid indices are 0 to length - 1. The condition i < length already stops at length - 1. Writing i < length - 1 stops one early and skips the last element.
- Fix:
i < customers.length, or better, a for-each loop, which can't get the bounds wrong. - Add a test that checks the number of exported rows equals the number of customers.
- Re-run the export for affected months.
Avoid: adjusting bounds by guesswork until the exception disappears.
The order page takes 8 seconds
The “My orders” page loads 200 orders, then runs for (Order o : orders) { o.setProduct(productRepository.findById(o.getProductId())); }. Each database call takes about 40 ms. Why is the page slow, and how would you fix it?
The interviewer is checking: do you recognise expensive work inside a loop (the “N+1 queries” problem)?
Show a strong answer
The loop makes one database call per order: 200 × 40 ms = 8 seconds, plus the first query. This is the classic N+1 query problem.
- Collect all product IDs first, then load them in one query (
findAllById(ids)), put them in a map, and look each up in memory inside the loop. - Or use a database join / the ORM's fetch join so products come with the orders.
- Measure before and after; the page should drop to well under a second.
Avoid saying: “Add more servers.” The work itself is wasteful.
A loop that never ends
A sensor job samples readings with for (double t = 0.0; t != 1.0; t += 0.1). In production the job never finishes and keeps one CPU core at 100%. Why?
The interviewer is checking: do you connect floating-point rounding (Lesson 2.2) with loop conditions?
Show a strong answer
0.1 can't be stored exactly in binary, so after ten additions t is 0.9999999999999999, not 1.0. The != check never becomes false, and t keeps growing forever.
- Loop over an integer counter and calculate the double from it:
for (int i = 0; i < 10; i++) { double t = i / 10.0; … }. - Never use
==or!=with floating-point values in loop conditions; use<at least. - Add a timeout or a maximum iteration count to long-running jobs, and CPU alerts in monitoring.
Avoid: “Change 0.1 to 0.1f.” float has the same problem.
Designing a safe retry loop
Calls to a payment gateway sometimes fail with a timeout. A developer suggests while (!success) { success = callGateway(); }. Your lead asks you to design something safer with a for loop. What would you write, and what must you be careful about?
The interviewer is checking: do you know bounded retries, backoff, and the danger of repeating payments?
Show a strong answer
- Use a bounded loop:
for (int attempt = 1; attempt <= 3; attempt++); break on success, and after the last attempt report failure. An unbounded loop can hammer a struggling gateway forever. - Wait longer between attempts (exponential backoff, e.g. 1 s, 2 s, 4 s, with a little randomness).
- Only retry safe failures (timeouts, 503), not “insufficient funds”.
- Most important: send an idempotency key with each request, so a retried payment can't charge the customer twice if the first attempt actually succeeded.
Avoid: retrying payments without idempotency. Double charges are far worse than a failed payment.