Introduction
Just like Armstrong numbers, once you know how to check whether a single number is a palindrome, the next natural step is finding every palindrome number within a given range — a common interview and assignment extension that tests whether you can cleanly refactor a single-value check into a reusable, range-friendly building block.
The good news is that palindrome numbers are considerably more common than Armstrong numbers, making this an interesting contrast once you've worked through both range-based problems.
This guide covers:
- A basic range-based loop
- A reusable
isPalindrome()method - Finding the largest palindrome within a range
- A modern Java Streams approach
- A comparison of palindrome and Armstrong number frequency
Quick Recap: What Makes a Number a Palindrome?
As covered in our dedicated guide, a palindrome number reads the same forwards and backwards.
Examples include:
121133112321
The standard approach reverses the digits using modulus (%) and division (/) operations, then compares the reversed number with the original.
Method 1: Basic Range-Based Loop
The simplest approach is to loop through every number in the specified range and perform the palindrome check directly inside the loop.
public class PalindromeRangeBasic {
public static void main(String[] args) {
int start = 100, end = 500;
System.out.println("Palindrome numbers between " + start + " and " + end + ":");
for (int num = start; num <= end; num++) {
int original = num;
int reversed = 0;
int temp = num;
while (temp != 0) {
int digit = temp % 10;
reversed = reversed * 10 + digit;
temp = temp / 10;
}
if (original == reversed) {
System.out.print(num + " ");
}
}
}
}
Output (Partial)
Palindrome numbers between 100 and 500:
101 111 121 131 141 151 161 171 181 191 202 212 ...
Although this works correctly, the palindrome-checking logic is written directly inside main(). This is acceptable for small programs but becomes difficult to reuse in larger applications.
Method 2: Using a Reusable isPalindrome() Method
A cleaner solution is to extract the palindrome logic into a reusable method. This separates the checking logic from the range iteration.
public class PalindromeRangeReusable {
static boolean isPalindrome(int num) {
int original = num;
int reversed = 0;
int temp = num;
while (temp != 0) {
int digit = temp % 10;
reversed = reversed * 10 + digit;
temp = temp / 10;
}
return original == reversed;
}
public static void main(String[] args) {
int start = 100, end = 200;
System.out.println("Palindrome numbers between " + start + " and " + end + ":");
for (int num = start; num <= end; num++) {
if (isPalindrome(num)) {
System.out.print(num + " ");
}
}
}
}
Output
Palindrome numbers between 100 and 200:
101 111 121 131 141 151 161 171 181 191
This design makes isPalindrome() reusable throughout your application.
For example, you can use it to:
- Count palindrome numbers
- Filter arrays or collections
- Combine with other conditions (such as prime numbers)
- Reuse across multiple classes without duplicating logic
Method 3: Finding the Largest Palindrome Number in a Range
A common interview variation asks you to find only the largest palindrome within a range.
Instead of collecting every palindrome, simply search backward from the upper limit.
public class LargestPalindromeInRange {
static boolean isPalindrome(int num) {
int original = num;
int reversed = 0;
int temp = num;
while (temp != 0) {
reversed = reversed * 10 + (temp % 10);
temp /= 10;
}
return original == reversed;
}
public static void main(String[] args) {
int start = 100, end = 999;
int largest = -1;
for (int num = end; num >= start; num--) {
if (isPalindrome(num)) {
largest = num;
break;
}
}
System.out.println("Largest palindrome between " + start + " and " + end + " is: " + largest);
}
}
Output
Largest palindrome between 100 and 999 is: 999
Why Is This More Efficient?
Instead of checking every number and maintaining a running maximum:
- Start from the highest value.
- Move downward.
- Stop immediately when the first palindrome is found.
Because the numbers are checked in descending order, the first palindrome encountered is automatically the largest one.
This early termination can significantly reduce the number of iterations.
Method 4: Using Java Streams
Java Streams provide a concise, declarative way to filter palindrome numbers.
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PalindromeRangeStreams {
static boolean isPalindrome(int num) {
int original = num;
int reversed = 0;
int temp = num;
while (temp != 0) {
reversed = reversed * 10 + (temp % 10);
temp /= 10;
}
return original == reversed;
}
public static void main(String[] args) {
int start = 100, end = 200;
List<Integer> palindromes =
IntStream.rangeClosed(start, end)
.filter(PalindromeRangeStreams::isPalindrome)
.boxed()
.collect(Collectors.toList());
System.out.println("Palindrome numbers: " + palindromes);
}
}
This approach:
- Generates numbers using
IntStream.rangeClosed() - Filters them with
isPalindrome() - Converts primitive
intvalues intoIntegerobjects using.boxed() - Collects the results into a
List
How Palindrome Frequency Compares to Armstrong Number Frequency
This is an interesting observation often worth mentioning during interviews.
Palindrome numbers are far more common than Armstrong numbers.
For example, between 1 and 10,000:
- Palindrome numbers: 198
- Armstrong numbers: 16
Those 16 Armstrong numbers include:
- Single-digit numbers (
0–9) 153370371407163482089474
This difference exists because:
- A palindrome only requires digit symmetry.
- An Armstrong number requires an exact arithmetic equality between the number and the sum of its digits raised to a specific power.
Digit symmetry is much easier to satisfy than a mathematical coincidence.
How Java Handles This Internally (Memory Concept)
Methods 1–3
- All numeric variables are primitive
intvalues. - They are stored on the stack.
- The digit reversal process performs no heap allocation.
Method 3
Looping backward changes only the execution flow.
It reduces runtime by terminating early with break, but the memory usage remains unchanged.
Method 4
Using Java Streams introduces additional objects:
IntStream.rangeClosed()creates an internal stream pipeline..boxed()converts primitiveintvalues into heap-allocatedIntegerobjects.- The collected
List<Integer>also resides on the heap.
Real-Life Analogy: Scanning a Library Shelf for Mirror-Image Titles
Imagine scanning a shelf of numbered library catalog entries, searching for IDs that read exactly the same forwards and backwards.
If you wanted every mirror-image catalog number, you'd examine the entire shelf.
If you wanted only the largest mirror-image catalog number, you'd begin from the highest-numbered shelf and move backward, stopping immediately after finding the first match.
That is exactly how Method 3 works.
Comparison of All Methods
| Method | Reusable Logic? | Finds | Best Used When |
|---|---|---|---|
| Basic Range Loop | ❌ No | All palindrome numbers | Quick scripts and simple practice programs |
| Reusable Method | ✅ Yes | All palindrome numbers | Production code and reusable utilities |
| Largest in Range (Backward Loop) | ✅ Yes | Only the largest palindrome | When only the maximum value is required |
| Java Streams | ✅ Yes | All palindrome numbers | Modern Java applications using streams |
Best Practices
- Extract the palindrome logic into a reusable
isPalindrome(int num)method. - When searching only for the largest or smallest palindrome, loop in the appropriate direction and terminate immediately after finding the first match.
- Prefer reusable methods over duplicating the digit reversal logic.
- Use Java Streams when your codebase already follows a functional programming style.
- Remember that palindrome numbers occur much more frequently than Armstrong numbers.
- For very large ranges, decide whether you need the complete list or simply a count to avoid unnecessary memory usage.
Common Mistakes Beginners Make
- Searching the entire range when only the largest palindrome is required.
- Forgetting to preserve the original number before reversing its digits.
- Assuming palindrome numbers are as rare as Armstrong numbers.
- Writing the palindrome logic repeatedly instead of creating a reusable method.
- Ignoring edge cases such as negative numbers or zero.
Expert Tips for Interviews
A strong interview answer might sound like this:
"To find palindrome numbers within a range, I'd first extract the digit-reversal logic into a reusable
isPalindrome()method. Then I'd iterate through the required range and apply that method to each number. If I only needed the largest palindrome, I'd iterate backward from the upper bound and stop immediately after finding the first match, since that would already be the largest palindrome. I'd also mention that palindrome numbers are much more common than Armstrong numbers because digit symmetry is a far less restrictive condition than satisfying an exact digit-power sum."
Mentioning the backward-search optimization and comparing palindrome numbers with Armstrong numbers demonstrates both algorithmic understanding and practical optimization skills.
Pros and Cons
Basic Range Loop
Pros
- ✅ Very simple to write
- ✅ Easy to understand
Cons
- ❌ Not reusable
- ❌ Logic is duplicated
Reusable Method
Pros
- ✅ Clean and modular
- ✅ Easy to test
- ✅ Supports multiple use cases
Cons
- ❌ Slightly more setup code
Largest in Range
Pros
- ✅ Very efficient when only the maximum is required
- ✅ Supports early termination
Cons
- ❌ Does not return all palindrome numbers
Java Streams
Pros
- ✅ Concise
- ✅ Modern and expressive
- ✅ Easy to chain additional operations
Cons
- ❌ Slightly higher overhead
- ❌ Less beginner-friendly
Frequently Asked Questions
1. How do I find all palindrome numbers between two numbers in Java?
Loop through every number in the specified range and apply the palindrome check to each one, printing or storing those that qualify.
2. Why should I extract the palindrome check into its own method?
A reusable method avoids duplicate code and allows the same logic to be reused for counting, filtering, searching, or combining with other conditions.
3. How do I find the largest palindrome number in a range efficiently?
Loop backward from the upper limit and stop immediately after finding the first palindrome.
4. Are palindrome numbers more common than Armstrong numbers?
Yes. Between 1 and 10,000, there are 198 palindrome numbers but only 16 Armstrong numbers.
5. How do I find palindrome numbers using Java Streams?
Use:
IntStream.rangeClosed(start, end)
.filter(this::isPalindrome)
.boxed()
.collect(Collectors.toList());
6. What is the time complexity of finding palindrome numbers in a range?
The overall time complexity is O(n × d), where:
- n is the number of values in the range.
- d is the average number of digits in each number.
7. Can I find the smallest palindrome number instead of the largest?
Yes. Iterate from the lower bound upward and stop after finding the first palindrome.
8. Is this a common Java interview question?
Yes. It frequently appears as a follow-up after implementing a single-number palindrome check.
9. Does this approach work for negative numbers?
Zero is naturally treated as a palindrome.
Negative numbers require explicit handling because the negative sign is not considered part of the digit reversal process.
10. Can I count palindrome numbers without printing them?
Yes. Replace the print statement with a counter that increments whenever a palindrome is found.
11. Why is the backward-loop optimization faster?
It allows the search to terminate immediately after finding the largest palindrome instead of scanning the entire range.
12. Can this logic work with other number bases?
Yes.
Replace:
% 10with% base/ 10with/ base
to reverse digits in any number base.