Java Programs for Practice

Naveen AnamaneniUpdated · 9 min read

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

  1. Read the task, then close the page and try it yourself first.
  2. Compare with the solution: is yours correct for the edge cases (0, 1, negative numbers, empty input)?
  3. Explain the approach out loud in two sentences, the way you would in an interview.
  4. Change one thing (a different input, the opposite order) and run it again.

Number Programs

TaskApproach
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 nMultiply 1 × 2 × ... × n in a long
Fibonacci seriesEach term is the sum of the previous two
GCD of two numbersEuclid: gcd(a, b) = gcd(b, a % b) until b is 0
NumberPrograms.java▶ Try it
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));
    }
}
Output
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) = 12

Explanation: 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.

Patterns.java▶ Try it
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());
        }
    }
}
Output
Right triangle:
*
* *
* * *
* * * *
Pyramid:
   *
  * *
 * * *
* * * *
Floyd's triangle:
1
2 3
4 5 6
7 8 9 10

Explanation: 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

TaskApproach
Reverse a stringnew StringBuilder(s).reverse(), or swap characters from both ends
Count vowelsLoop over characters and check "aeiou".indexOf(c) >= 0
Are two words anagrams?Sort both character arrays and compare, or count letters
Character frequencyA TreeMap<Character, Integer> with merge(c, 1, Integer::sum)
First non-repeated characterCount with a LinkedHashMap, then find the first count of 1
StringPrograms.java▶ Try it
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()));
    }
}
Output
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: n

Explanation: 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

TaskApproach
Largest and smallestOne pass, updating both
Second largestOne pass with two variables, first and second
Reverse in placeSwap from both ends towards the middle
Remove duplicatesA LinkedHashSet keeps the first occurrence of each, in order
Rotate left by kReverse the first k, reverse the rest, reverse the whole array
ArrayPrograms.java▶ Try it
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));
    }
}
Output
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

  1. 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).
  2. Harder: Print an inverted pyramid of 5 rows, then a diamond made of a pyramid and an inverted pyramid.

Quick check: Practice programs

4 questions
1Why does isPrime use (long) d * d?
2Which loop variable decides the number of rows in a pattern?
3Which map keeps characters in first-seen order?
4How many reversals rotate an array left by k in place?

Key Takeaways

Was this tutorial helpful?

Lesson 566 of 578