FizzBuzz in Java
Problem
FizzBuzz is a classic warm-up exercise built around checking divisibility with the modulo operator.
Print the numbers 1 through 30, replacing multiples of 3 with 'Fizz', multiples of 5 with 'Buzz', and multiples of both with 'FizzBuzz'.
Java Program
public class FizzBuzz {
public static void main(String[] args) {
for (int i = 1; i <= 30; i++) {
// Check the combined case first so multiples of both aren't caught by % 3 or % 5 alone
if (i % 15 == 0) System.out.println("FizzBuzz");
else if (i % 3 == 0) System.out.println("Fizz");
else if (i % 5 == 0) System.out.println("Buzz");
else System.out.println(i);
}
}
}Output
Core Logic
The modulo operator does all the heavy lifting here — check divisibility by 15 first, then fall back to 3 and 5.
- 1A for loop counts
ifrom 1 to 30. - 2
i % 15 == 0is checked first — 15 is 3 × 5, so this catches numbers divisible by both before the individual checks run. - 3
i % 3 == 0catches remaining multiples of 3 and prints"Fizz". - 4
i % 5 == 0catches remaining multiples of 5 and prints"Buzz". - 5Anything left over is just printed as the number itself.
i = 15, the % 15 check fires first, printing "FizzBuzz" instead of falling through to the % 3 or % 5 branches.Key Point: Ordering the % 15 check before % 3 and % 5 is what prevents 'FizzBuzz' from being printed as just 'Fizz'.
Why: Each number from 1 to n is visited exactly once, and only the loop counter and constant strings are held at any point.
Key Concepts
Approach 2: StringBuilder (Independent Conditions)
public class FizzBuzzStringBuilder {
public static void main(String[] args) {
for (int i = 1; i <= 30; i++) {
StringBuilder output = new StringBuilder();
if (i % 3 == 0) output.append("Fizz"); // independent check for 3
if (i % 5 == 0) output.append("Buzz"); // independent check for 5
// If neither condition matched, fall back to printing the number
System.out.println(output.length() > 0 ? output.toString() : String.valueOf(i));
}
}
}
Output
Core Logic
Instead of special-casing 'divisible by both', let 'Fizz' and 'Buzz' get appended independently — the combination takes care of itself.
- 1An empty
StringBuilderis created fresh for every number. - 2
if (i % 3 == 0)appends"Fizz"— independently of whether 5 also dividesi. - 3
if (i % 5 == 0)appends"Buzz"in the same way, so a multiple of both ends up with"FizzBuzz"naturally. - 4If neither condition added anything,
output.length() > 0is false, so the number itself is printed instead.
i = 15, both if blocks run, appending "Fizz" then "Buzz", so output becomes "FizzBuzz" without a dedicated % 15 check.Key Point: This scales better if more rules were added later (like '% 7 → Bazz') — each rule is an independent if, instead of needing a new combined-case branch for every pair of rules.
Why: A fresh, small StringBuilder is created and discarded each iteration, so its size never grows with n.
Key Concepts
Approach 3: Java 8
import java.util.stream.IntStream;
public class FizzBuzzStream {
public static void main(String[] args) {
IntStream.rangeClosed(1, 30)
// Same % 15 → % 3 → % 5 ordering as the loop version, as a ternary chain
.mapToObj(i -> i % 15 == 0 ? "FizzBuzz" : i % 3 == 0 ? "Fizz" : i % 5 == 0 ? "Buzz" : String.valueOf(i))
.forEach(System.out::println);
}
}
Output
Core Logic
The same 1-to-30 sweep can be expressed as a stream pipeline — map each number to its FizzBuzz string, then print the whole stream.
- 1
IntStream.rangeClosed(1, 30)produces the numbers 1 through 30 as a stream, replacing the for loop's counter. - 2
.mapToObj(i -> ...)turns eachintinto the rightString, using the same% 15,% 3, and% 5checks as a ternary chain instead of if/else if. - 3
.forEach(System.out::println)prints each mapped string in order, using a method reference instead of a lambda body.
15 checks 15 % 15 == 0 first, producing "FizzBuzz", the same as the loop version's combined check.Key Point: The ternary chain inside mapToObj() has to preserve the same '% 15 before % 3 or % 5' ordering as the loop version — streams don't change the underlying logic, just how it's expressed.
Why: mapToObj() and forEach() process and print one number at a time without ever materializing the full sequence into a collection.
Key Concepts
Interview Questions
Why must divisibility by 15 be checked first?
A number like 30 is divisible by 3, 5 and 15. If the check for 3 came first, it would print "Fizz" and never reach "FizzBuzz". Testing the most specific condition first prevents that.
Can FizzBuzz be written without checking 15 at all?
Yes. Build the output in a StringBuilder: append "Fizz" if divisible by 3, append "Buzz" if divisible by 5, and print the number only if nothing was appended. That version also extends easily to extra rules such as "Bazz" for 7.
Why is FizzBuzz such a common interview question?
It's small enough to write in a few minutes but quickly shows whether a candidate understands loops, the modulo operator and the order of conditions.