DSA in Java: Strings & Common Patterns (Beginner Guide)
Master Java strings for DSA: immutability, essential methods, and the three go-to patterns — two pointers for palindromes, frequency counting, and StringBuilder.
Strings are everywhere — names, messages, passwords, file contents, URLs. And in coding interviews, string problems are some of the most common you'll face. The good news: most of them reuse a small set of patterns you already half-know from the arrays lesson. In this lesson we'll cover how strings really work in Java and the go-to techniques for solving string problems cleanly.
The one thing you must remember: Strings are immutable
In Java, a String cannot be changed after it's created. Every operation that looks like it modifies a string actually creates a brand new string. This is the single most important fact about strings, and it explains a lot of behaviour and performance gotchas.
String s = "hello"; s.toUpperCase(); // returns "HELLO" but does NOT change s System.out.println(s); // still "hello"! s = s.toUpperCase(); // you must reassign to keep the result System.out.println(s); // now "HELLO"
If you learned about immutability in the Core Java course, this is the same idea. It's why building a big string in a loop with + is slow — each + makes a new string. For that, use StringBuilder (below).
Essential String methods
| Method | Does | Example → result |
|---|---|---|
length() |
Number of characters | "cat".length() → 3 |
charAt(i) |
Character at index i | "cat".charAt(0) → 'c' |
substring(a,b) |
Slice from a up to b | "cat".substring(0,2) → "ca" |
indexOf(x) |
First position of x (or -1) | "cat".indexOf('a') → 1 |
equals(x) |
Compare contents | "cat".equals("cat") → true |
toCharArray() |
String → char[] | handy for looping |
==. Because strings are objects, == checks whether they're the same object, not whether the text matches. Always use .equals() to compare string contents. This is one of the most common beginner bugs — and a favourite interview trap.Looping through a string
String s = "hello"; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); System.out.println(c); }
Pattern 1: Two pointers for palindromes
Remember the two-pointer trick from the arrays lesson? It works beautifully on strings too. To check if a string is a palindrome (reads the same forwards and backwards, like "level"), walk one pointer from each end toward the middle:
boolean isPalindrome(String s) { int left = 0, right = s.length() - 1; while (left < right) { if (s.charAt(left) != s.charAt(right)) return false; left++; right--; } return true; // O(n) time, O(1) space }
Pattern 2: Frequency counting
Tons of string problems — anagrams, "first unique character", "most frequent letter" — boil down to counting how often each character appears. For lowercase letters, a size-26 int array is the classic trick:
int[] count = new int[26]; for (char c : s.toCharArray()) { count[c - 'a']++; // 'a'→0, 'b'→1, ... clever indexing trick }
The c - 'a' part is a neat idea: since characters are really numbers under the hood, subtracting 'a' maps 'a' to 0, 'b' to 1, and so on — giving you the array index for free. (For any characters beyond lowercase letters, use a HashMap<Character,Integer> instead — you'll meet hashing properly in a later lesson.)
Pattern 3: StringBuilder for building strings
When you need to build up a string piece by piece (especially in a loop), don't use + — it creates a new string every time (O(n²) overall). Use StringBuilder, which is mutable and efficient:
StringBuilder sb = new StringBuilder(); for (char c : s.toCharArray()) { sb.append(Character.toUpperCase(c)); } String result = sb.toString(); // build once, convert once // Bonus: reversing a string in one line String reversed = new StringBuilder(s).reverse().toString();
Strings tripped me up more than anything else when I started — mostly because I kept using == to compare them and couldn't figure out why my if conditions were "wrong." Once .equals() and immutability clicked, string problems became some of my favourites, because they nearly all reduce to the same three moves: walk it with two pointers, count characters in an array, or build the answer with a StringBuilder. Keep those three patterns in your back pocket and you'll recognise the shape of most string questions instantly.
Key takeaways
- Strings are immutable — methods return new strings; reassign to keep the result.
- Compare contents with
.equals(), never==. - Two pointers handle palindromes and reversals; a size-26 count array handles frequency/anagram problems.
- Build strings in loops with
StringBuilder, not+, to avoid O(n²) work.
← Previous: DSA Lesson 2 — Arrays & Two Pointers
Next: DSA Lesson 4 — Recursion & Backtracking Basics →
↑ Back to the DSA roadmap