Java Programs for Practice
A cricketer doesn't only watch matches; they spend hours in the nets playing the same shots until they come without thinking. Programming is the same. Reading lessons teaches you what loops, arrays and strings are; writing small, classic programs again and again is what makes them automatic. These are also the programs that appear in school exams, college practicals and the first round of almost every Java interview. In this lesson, you will find the most common practice programs, grouped into number, pattern, string and array programs, each written cleanly with its output and the idea behind it.
How to Use This Page
- Read the task, then close the page and try it yourself first.
- Compare with the solution: is yours correct for the edge cases (0, 1, negative numbers, empty input)?
- Explain the approach out loud in two sentences, the way you would in an interview.
- Change one thing (a different input, the opposite order) and run it again.
Number Programs
| Task | Approach |
|---|---|
| Is a number prime? | Try divisors from 2 up to √n; any divisor means not prime |
| Is a number a palindrome? | Reverse its digits with % 10 and / 10, compare with the original |
| Is it an Armstrong number? | Sum of each digit raised to the number of digits equals the number (153 = 1³ + 5³ + 3³) |
| Factorial of n | Multiply 1 × 2 × ... × n in a long |
| Fibonacci series | Each term is the sum of the previous two |
| GCD of two numbers | Euclid: gcd(a, b) = gcd(b, a % b) until b is 0 |
public class NumberPrograms {
static boolean isPrime(int n) {
if (n < 2) return false;
for (int d = 2; (long) d * d <= n; d++) {
if (n % d == 0) return false;
}
return true;
}
static boolean isPalindrome(int n) {
int original = n, reversed = 0;
while (n > 0) {
reversed = reversed * 10 + n % 10;
n /= 10;
}
return original == reversed;
}
static boolean isArmstrong(int n) {
int digits = String.valueOf(n).length(), sum = 0;
for (int t = n; t > 0; t /= 10) {
sum += (int) Math.pow(t % 10, digits);
}
return sum == n;
}
static long factorial(int n) {
long result = 1;
for (int i = 2; i <= n; i++) result *= i;
return result;
}
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
public static void main(String[] args) {
System.out.print("primes up to 30:");
for (int i = 1; i <= 30; i++) if (isPrime(i)) System.out.print(" " + i);
System.out.println();
System.out.println("12321 palindrome? " + isPalindrome(12321));
System.out.println("153 Armstrong? " + isArmstrong(153));
System.out.println("10! = " + factorial(10));
System.out.print("Fibonacci:");
int a = 0, b = 1;
for (int i = 0; i < 10; i++) {
System.out.print(" " + a);
int next = a + b;
a = b;
b = next;
}
System.out.println();
System.out.println("gcd(84, 36) = " + gcd(84, 36));
}
}primes up to 30: 2 3 5 7 11 13 17 19 23 29
12321 palindrome? true
153 Armstrong? true
10! = 3628800
Fibonacci: 0 1 1 2 3 5 8 13 21 34
gcd(84, 36) = 12Explanation: isPrime stops at √n, because if n has a divisor larger than √n, it also has one smaller. Writing (long) d * d avoids overflow for numbers near Integer.MAX_VALUE. factorial uses long, since 13! is already too big for an int.
Pattern Programs
Pattern programs test nested loops: the outer loop counts rows, and inner loops print spaces and symbols for each row.
public class Patterns {
public static void main(String[] args) {
int rows = 4;
System.out.println("Right triangle:");
for (int r = 1; r <= rows; r++) {
System.out.println("* ".repeat(r));
}
System.out.println("Pyramid:");
for (int r = 1; r <= rows; r++) {
System.out.println(" ".repeat(rows - r) + "* ".repeat(r));
}
System.out.println("Floyd's triangle:");
int n = 1;
for (int r = 1; r <= rows; r++) {
StringBuilder line = new StringBuilder();
for (int c = 1; c <= r; c++) {
line.append(n++).append(' ');
}
System.out.println(line.toString().trim());
}
}
}Right triangle:
*
* *
* * *
* * * *
Pyramid:
*
* *
* * *
* * * *
Floyd's triangle:
1
2 3
4 5 6
7 8 9 10Explanation: row r of the pyramid has rows - r leading spaces and r stars. String.repeat (Java 11) keeps the code short; with plain loops, each repeat becomes an inner for loop. Floyd's triangle keeps one counter running across all rows.
String Programs
| Task | Approach |
|---|---|
| Reverse a string | new StringBuilder(s).reverse(), or swap characters from both ends |
| Count vowels | Loop over characters and check "aeiou".indexOf(c) >= 0 |
| Are two words anagrams? | Sort both character arrays and compare, or count letters |
| Character frequency | A TreeMap<Character, Integer> with merge(c, 1, Integer::sum) |
| First non-repeated character | Count with a LinkedHashMap, then find the first count of 1 |
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class StringPrograms {
public static void main(String[] args) {
String name = "Srihitha";
System.out.println("reversed: " + new StringBuilder(name).reverse());
long vowels = name.toLowerCase().chars()
.filter(c -> "aeiou".indexOf(c) >= 0).count();
System.out.println("vowels in " + name + ": " + vowels);
char[] x = "listen".toCharArray(), y = "silent".toCharArray();
Arrays.sort(x);
Arrays.sort(y);
System.out.println("listen/silent anagrams? " + Arrays.equals(x, y));
Map<Character, Integer> freq = new TreeMap<>();
for (char c : "anamaneni".toCharArray()) freq.merge(c, 1, Integer::sum);
System.out.println("frequency: " + freq);
Map<Character, Integer> counts = new LinkedHashMap<>();
for (char c : "navika".toCharArray()) counts.merge(c, 1, Integer::sum);
counts.entrySet().stream()
.filter(e -> e.getValue() == 1)
.findFirst()
.ifPresent(e -> System.out.println(
"first unique in navika: " + e.getKey()));
}
}reversed: ahtihirS
vowels in Srihitha: 3
listen/silent anagrams? true
frequency: {a=3, e=1, i=1, m=1, n=3}
first unique in navika: nExplanation: merge(c, 1, Integer::sum) adds 1 to the count, or puts 1 for a new character. A TreeMap prints the letters in order; a LinkedHashMap keeps the order in which they first appeared, which is what "first non-repeated" needs.
Array Programs
| Task | Approach |
|---|---|
| Largest and smallest | One pass, updating both |
| Second largest | One pass with two variables, first and second |
| Reverse in place | Swap from both ends towards the middle |
| Remove duplicates | A LinkedHashSet keeps the first occurrence of each, in order |
| Rotate left by k | Reverse the first k, reverse the rest, reverse the whole array |
import java.util.Arrays;
import java.util.LinkedHashSet;
public class ArrayPrograms {
static void reverse(int[] a, int from, int to) {
while (from < to) {
int t = a[from]; a[from] = a[to]; a[to] = t;
from++;
to--;
}
}
public static void main(String[] args) {
int[] marks = {72, 95, 61, 88, 95, 40};
int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
int first = Integer.MIN_VALUE, second = Integer.MIN_VALUE;
for (int m : marks) {
max = Math.max(max, m);
min = Math.min(min, m);
if (m > first) {
second = first;
first = m;
} else if (m > second && m != first) {
second = m;
}
}
System.out.println("max " + max + ", min " + min
+ ", second " + second);
LinkedHashSet<Integer> unique = new LinkedHashSet<>();
for (int m : marks) unique.add(m);
System.out.println("without duplicates: " + unique);
int[] days = {1, 2, 3, 4, 5, 6, 7};
int k = 2;
reverse(days, 0, k - 1);
reverse(days, k, days.length - 1);
reverse(days, 0, days.length - 1);
System.out.println("rotated left by 2: " + Arrays.toString(days));
}
}max 95, min 40, second 88
without duplicates: [72, 95, 61, 88, 40]
rotated left by 2: [3, 4, 5, 6, 7, 1, 2]Explanation: the second-largest check m != first makes sure a repeated maximum (95 appears twice) isn't counted as second. The three-reversal trick rotates the array in place with O(1) extra memory.
Interview Corner
Why loop only up to the square root when checking for a prime?
If n = a × b and both a and b were larger than √n, their product would be larger than n. So any composite number has a divisor no larger than √n.
How do you find the second largest element in one pass?
Keep two variables. When a value beats the largest, the old largest becomes second. When a value is between them (and not equal to the largest), it becomes the new second.
How do you check whether two strings are anagrams in O(n)?
Count each letter of the first string up and each letter of the second string down in an int[26]; they are anagrams if every count ends at zero.
Practice
- Easy: Write a program that prints the sum of the digits of 98765 (answer: 35), and one that checks whether a year is a leap year (divisible by 4, except centuries unless divisible by 400).
- Harder: Print an inverted pyramid of 5 rows, then a diamond made of a pyramid and an inverted pyramid.
Key Takeaways
Was this tutorial helpful?