Java String Programs and FAQs

Naveen AnamaneniUpdated · 6 min read

These ten programs come up again and again in fresher interviews, coding tests and college labs. Each uses the tools from this chapter: loops over characters, StringBuilder, split, Character methods, and a couple of maps (collections get their own lessons later; here a map simply counts things). Try each one yourself first, then compare with the solution and read why it works.

The Ten Programs

#ProgramInputOutput
S1Reverse a stringhelloolleh
S2Palindrome, ignoring case and punctuationA man, a plan, a canal: Panamatrue
S3Count vowels and consonantsProgrammingvowels=3, consonants=8
S4Frequency of each characterbanana{a=3, b=1, n=2}
S5Anagram checklisten, silenttrue
S6First non-repeating characterswissw
S7Reverse the order of wordsJava is funfun is Java
S8Remove duplicate characters, keeping orderprogrammingprogamin
S9Count words with extra spaces" Java is fun "3
S10Run-length compressionaaabbca3b2c1

The Solutions

StringPrograms.java▶ Try it
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
 
public class StringPrograms {
    static boolean isPalindrome(String s) {
        String clean = s.toLowerCase().replaceAll("[^a-z0-9]", "");
        return clean.equals(new StringBuilder(clean).reverse().toString());
    }
 
    static String vowelsAndConsonants(String s) {
        int vowels = 0, consonants = 0;
        for (char ch : s.toLowerCase().toCharArray()) {
            if (!Character.isLetter(ch)) continue;
            if ("aeiou".indexOf(ch) >= 0) vowels++; else consonants++;
        }
        return "vowels=" + vowels + ", consonants=" + consonants;
    }
 
    static Map<Character, Integer> frequency(String s) {
        Map<Character, Integer> freq = new TreeMap<>();
        for (char ch : s.toCharArray()) freq.merge(ch, 1, Integer::sum);
        return freq;
    }
 
    static boolean isAnagram(String a, String b) {
        char[] x = a.toLowerCase().toCharArray();
        char[] y = b.toLowerCase().toCharArray();
        Arrays.sort(x);
        Arrays.sort(y);
        return Arrays.equals(x, y);
    }
 
    static char firstNonRepeating(String s) {
        Map<Character, Integer> counts = new LinkedHashMap<>();
        for (char ch : s.toCharArray()) counts.merge(ch, 1, Integer::sum);
        for (Map.Entry<Character, Integer> e : counts.entrySet()) {
            if (e.getValue() == 1) return e.getKey();
        }
        return '-';
    }
 
    static String reverseWords(String s) {
        String[] words = s.strip().split("\\s+");
        StringBuilder sb = new StringBuilder();
        for (int i = words.length - 1; i >= 0; i--) {
            sb.append(words[i]);
            if (i > 0) sb.append(' ');
        }
        return sb.toString();
    }
 
    static String removeDuplicates(String s) {
        StringBuilder sb = new StringBuilder();
        for (char ch : s.toCharArray()) {
            if (sb.indexOf(String.valueOf(ch)) < 0) sb.append(ch);
        }
        return sb.toString();
    }
 
    static int countWords(String s) {
        return s.isBlank() ? 0 : s.strip().split("\\s+").length;
    }
 
    static String compress(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); ) {
            char ch = s.charAt(i);
            int run = 0;
            while (i < s.length() && s.charAt(i) == ch) {
                i++;
                run++;
            }
            sb.append(ch).append(run);
        }
        return sb.toString();
    }
 
    public static void main(String[] args) {
        System.out.println("S1  " + new StringBuilder("hello").reverse());
        String panama = "A man, a plan, a canal: Panama";
        System.out.println("S2  " + isPalindrome(panama));
        System.out.println("S3  " + vowelsAndConsonants("Programming"));
        System.out.println("S4  " + frequency("banana"));
        System.out.println("S5  " + isAnagram("listen", "silent"));
        System.out.println("S6  " + firstNonRepeating("swiss"));
        System.out.println("S7  " + reverseWords("Java is fun"));
        System.out.println("S8  " + removeDuplicates("programming"));
        System.out.println("S9  " + countWords("  Java   is  fun "));
        System.out.println("S10 " + compress("aaabbc"));
    }
}
Output
S1  olleh
S2  true
S3  vowels=3, consonants=8
S4  {a=3, b=1, n=2}
S5  true
S6  w
S7  fun is Java
S8  progamin
S9  3
S10 a3b2c1

Why Each Solution Works

#The key idea
S1StringBuilder.reverse() (see "How to Reverse a String in Java" for the manual way)
S2First clean the text: lower case, then replaceAll("[^a-z0-9]", "") deletes everything that isn't a letter or digit. Then compare it with its reverse
S3Skip non-letters with Character.isLetter; "aeiou".indexOf(ch) >= 0 is a neat "is it a vowel?" test
S4merge(ch, 1, Integer::sum) means "store 1 the first time, otherwise add 1". A TreeMap keeps the letters in order
S5Two words are anagrams if they contain the same letters: sort both character arrays and compare
S6Count first, then scan in the original order. LinkedHashMap remembers insertion order, so the first count of 1 is the answer
S7strip() then split("\\s+") gives clean words; append them from last to first
S8Keep a character only if the result doesn't contain it yet, which preserves the first occurrence
S9split("\\s+") treats any run of spaces as one separator; isBlank() handles empty input
S10Walk through runs of the same character, counting each run before moving on

How Fast Are They?

Common Mistakes

Comparing characters as strings with ==. char values compare correctly with ==; strings need equals.

Forgetting to normalize case. "Listen" and "silent" are anagrams only after lower-casing.

Splitting on a single space. "a b".split(" ") contains an empty piece; use "\\s+".

Interview Corner

How do you check whether two strings are anagrams?

Normalize both (for example, lower-case them and remove spaces), then either sort their character arrays and compare with Arrays.equals, which takes O(n log n), or count each letter's occurrences in an int[26] array, adding for one string and subtracting for the other, and check that every count is zero, which takes O(n).

How do you find the first non-repeating character?

Count every character's occurrences in one pass, using a LinkedHashMap or an array, then make a second pass in the original order and return the first character whose count is 1. Both passes are linear, so the whole solution is O(n).

Practice

  1. Easy: Change S3 to also count digits and spaces, and run it on "Navika joined in 2026".
  2. Harder: Rewrite S5 using an int[26] count array instead of sorting, and S8 using a boolean[256] "seen" array. Check that the outputs are unchanged.

Quick check: String programs

4 questions
1Which map keeps keys in the order they were first added?
2What does merge(ch, 1, Integer::sum) do?
3Why sort both arrays in the anagram check?
4Which split handles several spaces between words?

Key Takeaways

Was this tutorial helpful?

Lesson 208 of 482