Strings
Text is just an array of characters, with a few sharp edges.
Every password checker, autocomplete box, and DNA-matching tool is doing the same underlying thing: walking through text one character at a time. Under the hood, a string is just an array of characters, "cat" is the char sequence 'c', 'a', 't' sitting in slots 0, 1, and 2. Everything you learned about arrays applies immediately.
But Java strings come with a few sharp edges that trip up beginners in interviews: strings cannot be changed after creation, comparing them with == quietly does the wrong thing, and building a string inside a loop can accidentally turn an O(n) solution into an O(n squared) one. This lesson covers the concepts and the Java specifics together.
A string is a read-only array of characters
In Java, a String wraps a character array and gives you array-flavored tools to inspect it. length() tells you how many characters it holds. charAt(i) hands you the character at index i in O(1), exactly like arr[i]. Indexes run from 0 to length() - 1, and going outside that range throws StringIndexOutOfBoundsException.
When a problem needs heavy character-by-character work, it is often cleaner to call toCharArray(), which copies the string's characters into a real char[] you can index and even modify freely. The copy costs O(n) once, and afterward you are back in familiar array territory. One more useful trick: characters are numbers underneath, so arithmetic like s.charAt(i) - 'a' converts a lowercase letter into an index from 0 to 25. The backbone of counting problems.
Immutability: strings never change
Here is the sharpest edge: Java strings are immutable, meaning once a String object is created, its characters can never be altered. There is no s.setCharAt(2, 'x'). Methods that look like they modify a string (toUpperCase, replace, substring, trim) actually build and return a brand-new string, leaving the original untouched. If you ignore the return value, nothing happens.
Why design it this way? Immutability makes strings safe to share between parts of a program and lets Java cache and reuse them internally. The practical consequences for you: every "modification" allocates a new string and copies characters, costing O(n); and if you truly need in-place edits, convert to a char[] first, edit the array, and build a new String from it at the end.
StringBuilder: how to build strings in a loop
Immutability creates a classic performance trap. Concatenating with += in a loop looks harmless, but each += builds an entirely new string by copying everything so far plus the new piece. After n rounds, you have copied roughly 1 + 2 + 3 + ... + n characters, that sum is on the order of n squared, so the loop is O(n squared) even though it looks like one pass.
The fix is StringBuilder, a mutable companion class that works like an ArrayList of characters. Its append method drops characters into an internal resizable array in amortized O(1), and one final toString() call produces the result. Total cost: O(n). The rule is simple and worth stating in interviews: any time you assemble a string piece by piece in a loop, reach for StringBuilder. It also gives you reverse(), the one-liner behind many palindrome and reversal problems.
Comparing strings, and where to go next
The other famous Java gotcha: never compare string contents with ==. The == operator asks whether two references point to the same object in memory, not whether the characters match. Two strings can hold identical text and still fail ==. Always use s.equals(t) for content equality, equalsIgnoreCase for case-blind comparison, and compareTo for alphabetical ordering. This is a one-line mistake that can sink an otherwise correct solution.
Zoom out and the toolkit is compact: charAt and toCharArray for inspection, StringBuilder for construction, equals for comparison, and the knowledge that every hidden copy costs O(n). Most interview string problems (counting characters, detecting anagrams, checking palindromes) combine these tools with one more idea: a fast way to count and look things up. That idea is the hash map, and it is next.
Frequently asked
Why does "abc" == "abc" sometimes return true if == is wrong?
Java keeps a pool of string literals and reuses the same object for identical literals in source code, so two literals can genuinely be the same object. But strings built at runtime (from input, concatenation, or new String) are separate objects, and == returns false even when the text matches. Because the behavior is inconsistent, always use equals for content comparison.
Should I use toCharArray or charAt when looping over a string?
Both are fine for a read-only pass; charAt avoids the O(n) copy while toCharArray can make the loop body cleaner and lets you modify characters. If you need to edit characters or sort them, toCharArray is the way to go. In complexity terms they are identical: one O(n) pass either way.
What exactly is the difference between String and StringBuilder?
String is immutable: its characters are fixed forever, and every apparent modification allocates a new object. StringBuilder is mutable: it holds characters in a resizable internal array you can append to, insert into, and reverse cheaply. Build with StringBuilder, then call toString() when you need the final immutable String.