Java String Programs

String programs open most Java coding rounds for testers and SDETs. They're short, but interviewers use them to check fundamentals: immutability, == vs equals(), choosing the right collection, and edge cases like capitals, spaces and empty strings. Every program here was compiled and run; the outputs are real. For word-level programs (reverse each word, word frequency, anagrams) see String Programs Part 2.

Advertisement

First: Strings Are Immutable

A String can't be changed after it's created. Every "change" — concat, replace, toUpperCase, += — creates a new String. That's why the programs below build results with a StringBuilder (mutable) and swap characters through a char[].

1. Reverse a String ⭐

static String reverse(String s) {
    StringBuilder sb = new StringBuilder();
    for (int i = s.length() - 1; i >= 0; i--) sb.append(s.charAt(i));
    return sb.toString();
}
// reverse("Testing") → "gnitseT"

// One line
new StringBuilder("Testing").reverse().toString();   // "gnitseT"

Interviewers usually want the loop first, then ask for a shorter way. Avoid reversed = reversed + s.charAt(i) in a loop — each + creates a new String, making it O(n²) for long strings.

2. Palindrome Check ⭐

static boolean isPalindrome(String s) {
    String clean = s.toLowerCase().replaceAll("[^a-z0-9]", "");   // ignore case, spaces, punctuation
    int i = 0, j = clean.length() - 1;
    while (i < j) {
        if (clean.charAt(i++) != clean.charAt(j--)) return false;
    }
    return true;
}
// "Madam" → true
// "A man, a plan, a canal: Panama" → true
// "Selenium" → false

The two-pointer version stops at the first mismatch and uses no extra string, so it's the one to show when asked for the optimal approach (O(n) time, O(1) extra space apart from the cleaning step). Reversing and comparing with equals() is also correct. Ask the interviewer whether case and punctuation should be ignored — it shows you think like a tester.

3. Comparing Strings: == vs equals()

String a = "test", b = "test", c = new String("test");
a == b                    // true  — both literals point to the same object in the String pool
a == c                    // false — new String() creates a separate object
a.equals(c)               // true  — compares content ⭐
"TEST".equalsIgnoreCase(a)// true
"apple".compareTo("banana")   // -1 (negative → "apple" sorts first)

== compares references, so it can pass for literals and fail for strings built at runtime — exactly like text returned by getText(). Always use equals() for content. compareTo() returns a negative number, zero or a positive number for sorting.

4. Count Vowels and Consonants

static int[] vowelsConsonants(String s) {
    int v = 0, c = 0;
    for (char ch : s.toLowerCase().toCharArray()) {
        if (ch < 'a' || ch > 'z') continue;            // skip digits, spaces, punctuation
        if ("aeiou".indexOf(ch) >= 0) v++; else c++;
    }
    return new int[]{v, c};
}
// "Automation 2026!" → 6 vowels, 4 consonants

5. Duplicate Characters and Their Counts

static Map<Character, Integer> duplicates(String s) {
    Map<Character, Integer> freq = new LinkedHashMap<>();
    for (char ch : s.toCharArray()) freq.merge(ch, 1, Integer::sum);   // count every character
    freq.values().removeIf(n -> n < 2);                                 // keep only repeats
    return freq;
}
// "programming" → {r=2, g=2, m=2}
// "a0b0c1"      → {0=2}

Watch out for a popular broken version: the nested-loop approach that marks counted characters by overwriting them with '0'. On "a0b0c1" it prints nothing — the real zeros are skipped as if they'd already been counted. We ran it to confirm. The map version is also O(n) instead of O(n²).

merge(ch, 1, Integer::sum) is a shorter form of map.put(ch, map.getOrDefault(ch, 0) + 1) — both are fine in interviews.

6. Remove Duplicate Characters

static String removeDuplicates(String s) {
    StringBuilder sb = new StringBuilder();
    for (char ch : new LinkedHashSet<>(s.chars().mapToObj(c -> (char) c).toList())) sb.append(ch);
    return sb.toString();
}
// "programming" → "progamin"

A LinkedHashSet removes repeats and keeps first-seen order; a HashSet would lose the order.

7. First Non-Repeated Character

Count with a LinkedHashMap, then return the first entry with a count of 1 — "swiss" → 'w'; "aabb" → none. The full tested code is in String Programs Part 2. LinkedHashMap is essential: with a plain HashMap, "first" has no meaning.

8. Only Digits / Only Letters

static boolean onlyDigits(String s)  { return s != null && s.matches("\\d+"); }
static boolean onlyLetters(String s) { return s != null && s.matches("[a-zA-Z]+"); }
// onlyDigits("2026") → true, ("20a6") → false, ("") → false
// onlyLetters("Java") → true, ("Java 17") → false

The + means "one or more", so an empty string is rejected — decide with the interviewer whether that's the right behavior. The loop alternative uses Character.isDigit() / Character.isLetter() on each character (note that these also accept non-English digits and letters).

9. Swap Two Characters

static String swap(String s, int i, int j) {
    char[] a = s.toCharArray();
    char t = a[i]; a[i] = a[j]; a[j] = t;
    return new String(a);
}
// swap("java", 0, 3) → "aavj"

10. Is One String a Rotation of Another?

static boolean isRotation(String a, String b) {
    return a.length() == b.length() && (a + a).contains(b);
}
// ("abcd", "cdab") → true,   ("abcd", "acbd") → false

Every rotation of a appears inside a + a — a neat trick interviewers like as a follow-up.

13. Find a Pattern, Extract Numbers and Length Without length()

static List<Integer> findAll(String text, String pattern) {   // every start index
    List<Integer> hits = new ArrayList<>();
    for (int i = text.indexOf(pattern); i >= 0; i = text.indexOf(pattern, i + 1)) hits.add(i);
    return hits;
}
static List<Long> extractNumbers(String s) {
    List<Long> out = new ArrayList<>();
    java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\d+").matcher(s);
    while (m.find()) out.add(Long.parseLong(m.group()));
    return out;
}
static int lengthWithoutLength(String s) { int n = 0; for (char ignored : s.toCharArray()) n++; return n; }
findAll("abababa", "aba") → [0, 2, 4]
"Order 12 of 150".matches(".*\\d+.*") → true
extractNumbers("Order 12 of 150, id A007") → [12, 150, 7]
lengthWithoutLength("Selenium") → 8
  • Finding a pattern: indexOf(pattern, from) in a loop finds every occurrence — including overlapping ones, which is why "aba" is found at 0, 2 and 4. Regular expressions (Pattern/Matcher) handle "any number", "any email" and similar patterns; KMP is the classic algorithm when an interviewer asks you to write the search yourself in O(n + m).
  • Extracting numbers: \d+ finds each run of digits; Long.parseLong turns "007" into 7. This is how tests read an order ID or a total out of a confirmation message.
  • Length without length(): count the characters in a loop. (Note that characters outside the Basic Multilingual Plane, such as most emoji, take two chars; codePointCount counts them once.)

The code in this section comes from one class that was compiled and run on Java 21; the outputs are real.

11. Digits and Numbers Inside Strings

static int[] countCategories(String s) {                     // letters, digits, spaces, special
    int letters = 0, digits = 0, spaces = 0, special = 0;
    for (char ch : s.toCharArray()) {
        if (Character.isLetter(ch)) letters++;
        else if (Character.isDigit(ch)) digits++;
        else if (Character.isWhitespace(ch)) spaces++;
        else special++;
    }
    return new int[]{letters, digits, spaces, special};
}
static int sumOfDigits(String s) {
    int sum = 0;
    for (char ch : s.toCharArray()) if (ch >= '0' && ch <= '9') sum += ch - '0';
    return sum;
}
static int compareNumeric(String a, String b) {               // "10" vs "9" as numbers, any length
    return new BigInteger(a.trim()).compareTo(new BigInteger(b.trim()));
}
countCategories("Order #A12 costs ₹450!") → letters 11, digits 5, spaces 3, special 3
sumOfDigits("a1b2c3") → 6
"10".compareTo("9") → -8   (text order: "10" sorts first)
compareNumeric("10", "9") → 1
compareNumeric(" 007 ", "7") → 0
compareNumeric of 25-digit numbers → -1
compareNumeric("12a", "5") → NumberFormatException
  • Counting categories: Character.isLetter, isDigit and isWhitespace — everything else is "special" (here #, ₹ and !).
  • Digit sum: ch - '0' turns the character '7' into the number 7.
  • Comparing numbers stored as text is a classic automation bug: "10".compareTo("9") is negative, so "10" sorts before "9". Convert first. BigInteger handles any length and leading zeros; invalid text throws NumberFormatException, which is what you want in a test. Prices read from a page need cleaning (currency symbols, commas) before conversion — and BigDecimal for decimals.

The code in this section comes from one class that was compiled and run on Java 21; the outputs are real.

12. Replace, Remove Whitespace and Concatenate

static String replaceChar(String s, char from, char to) { return s.replace(from, to); }
static String removeAllWhitespace(String s)            { return s.replaceAll("\\s+", ""); }
static String collapseWhitespace(String s)             { return s.strip().replaceAll("\\s+", " "); }
static String concatWithoutPlus(String... parts) {
    StringBuilder sb = new StringBuilder();
    for (String p : parts) sb.append(p);
    return sb.toString();
}
replaceChar("a-b-c", '-', '_') → a_b_c
removeAllWhitespace("  Total:\t 1,250 \n INR  ") → "Total:1,250INR"
collapseWhitespace("  Total:\t 1,250 \n INR  ") → "Total: 1,250 INR"
"Pay\u00A0Now".replaceAll("\\s+", "") → "Pay Now"   (non-breaking space is not \s)
concatWithoutPlus("Sele", "nium", " 4") → Selenium 4
String.join(" > ", "Home", "Cart") → Home > Cart, "a".concat("b") → ab
  • replace(char, char) replaces every occurrence and returns a new string — strings are immutable, so assign the result.
  • Removing vs collapsing whitespace: removing all of it merges words; for comparing UI text, collapsing runs of spaces, tabs and new lines into one space (plus strip()) is usually what you want.
  • The non-breaking space trap: web pages often use &nbsp; (\u00A0), which \s does not match — our run left "Pay Now" untouched. Replace \u00A0 explicitly (or use [\s\u00A0]+) before asserting on page text.
  • Concatenating without +: StringBuilder.append(), concat() or String.join(). Inside loops, StringBuilder avoids creating a new string on every iteration.

The code in this section comes from one class that was compiled and run on Java 21; the outputs are real.

Complexity Summary

Program Time Extra space
Reverse (StringBuilder), palindrome, vowels, swap O(n) O(n) / O(1)
Duplicates, remove duplicates, first non-repeated (map/set) O(n) O(k) distinct characters
Duplicates with nested loops O(n²) O(n)
Reverse with += in a loop O(n²) O(n)

Step through any program line by line — watching the pointers and the map change — in the Java Code Visualizer.

From the Interview Room

Java has been the language of every automation framework I've worked with — Selenium, TestNG, POM classes and Apache POI for Excel data. Interviews for automation roles regularly include basic programs like this one, often followed by a question on OOP concepts. Practice writing it by hand and explaining how you'd test it. On Canolog, the many forms and screens across sales, inventory, finance and service are where keeping page details in POM classes and reusable steps in a business library paid off. Check null and empty strings before anything else.

📚 Official documentation: dev.java: Learn Java (Oracle) · Java 21 API documentation

👉 See also: Count Vowels and Consonants in Java | Step-by-Step Guide with Code Examples

Frequently Asked Questions

How do you reverse a string in Java?

Loop from the last index to the first, appending to a StringBuilder — or use new StringBuilder(s).reverse().toString().

How do you check a palindrome?

Compare characters from both ends with two pointers, or reverse and compare with equals(). Normalize case and remove non-alphanumeric characters if the question allows.

Why use equals() instead of ==?

== compares object references; equals() compares content. Two strings with the same text can be different objects.

How do you find duplicate characters?

Count characters in a LinkedHashMap and keep those with a count above 1 — one pass, O(n).

Why are strings immutable in Java?

For safety and efficiency: they can be shared through the String pool, used safely as HashMap keys and across threads, and can't be changed by other code after they're passed around.

How do you check that a string contains only digits?

s.matches("\\d+"), or loop with Character.isDigit().