Check Anagram in Java
Problem
Anagrams are words or strings that contain the same characters with the same frequencies, but possibly in a different order.
Given two strings, determine whether they are anagrams.
Java Program
import java.util.Arrays;
public class AnagramCheck {
public static void main(String[] args) {
String a = "listen", b = "silent";
char[] ca = a.toCharArray();
char[] cb = b.toCharArray();
// Sorting puts both arrays into the same canonical order
Arrays.sort(ca);
Arrays.sort(cb);
// Anagrams sort to identical character arrays
boolean isAnagram = Arrays.equals(ca, cb);
System.out.println("Anagram: " + isAnagram);
}
}Output
Core Logic
Sort the letters of both strings and compare — if they match, one is just a shuffled version of the other.
- 1Both strings are converted to
char[]arrays withtoCharArray(). - 2
Arrays.sort()puts each array's characters into the same canonical (alphabetical) order. - 3
Arrays.equals()compares the two sorted arrays element by element. - 4If the sorted arrays are identical, the original strings must contain exactly the same characters, just rearranged.
"listen" sorts to eilnst, and "silent" also sorts to eilnst — so they're reported as anagrams.Key Point: Sorting both strings turns the comparison into a simple array-equality check — no manual character-frequency counting needed.
Why: Sorting each character array dominates the cost, and both sorted copies are held in memory for the final comparison.
Key Concepts
Approach 2: Frequency Count Array
public class AnagramCheckFrequency {
public static void main(String[] args) {
String a = "listen", b = "silent";
boolean isAnagram = true;
// Different lengths can never be anagrams
if (a.length() != b.length()) {
isAnagram = false;
} else {
int[] counts = new int[26]; // one slot per letter a-z
for (int i = 0; i < a.length(); i++) {
counts[a.charAt(i) - 'a']++; // increment for each letter in a
counts[b.charAt(i) - 'a']--; // decrement for each letter in b
}
// If every increment was canceled by a matching decrement, all slots are 0
for (int count : counts) {
if (count != 0) {
isAnagram = false;
break;
}
}
}
System.out.println("Anagram: " + isAnagram);
}
}
Output
Core Logic
Sorting isn't the only option — tallying letter counts in a small array gets the same answer without touching either string's order.
- 1A quick length check runs first — strings of different lengths can never be anagrams.
- 2A 26-element
int[]tracks the running difference in letter counts, one slot per letter of the alphabet. - 3
counts[a.charAt(i) - 'a']++increments the slot for each letter ina; the matching decrement forbhappens in the same loop pass. - 4If the strings are anagrams, every increment from
ais canceled out by a decrement fromb, leaving every slot at0. - 5A final pass checks that no slot ended up non-zero.
"listen" and "silent", every letter appears the same number of times in both, so every slot in counts ends at 0.Key Point: This runs in O(n) time, faster than the O(n log n) sorting approach — the trade-off is that it only works cleanly for a known, fixed character set like lowercase letters.
Why: Each string is scanned once to update a fixed 26-element array, whose size never grows with the input.
Key Concepts
Approach 3: Java 8
import java.util.stream.Collectors;
public class AnagramCheckStream {
// Sorts the character codes, then joins them back into a canonical String
static String sortChars(String str) {
return str.chars()
.sorted()
.mapToObj(c -> String.valueOf((char) c))
.collect(Collectors.joining());
}
public static void main(String[] args) {
String a = "listen", b = "silent";
// Anagrams sort down to the same canonical String
boolean isAnagram = sortChars(a).equals(sortChars(b));
System.out.println("Anagram: " + isAnagram);
}
}
Output
Core Logic
Sorting still does the heavy lifting, but a stream pipeline can produce each string's canonical sorted form without ever touching a char[] directly.
- 1
a.chars()andb.chars()each return anIntStreamof character codes, one per string. - 2
.sorted()puts each stream's codes into ascending order, the stream equivalent ofArrays.sort()on achar[]. - 3
.mapToObj(c -> String.valueOf((char) c)).collect(Collectors.joining())turns the sorted codes back into a single sortedString. - 4Comparing the two sorted strings with
.equals()gives the same answerArrays.equals()gave on the sorted arrays.
"listen" and "silent" both sort down to "eilnst" through the pipeline, so the final .equals() check returns true.Key Point: This does the same O(n log n) sort as the array version, just expressed as a stream pipeline — it builds two intermediate sorted Strings along the way, so the frequency-count approach is still leaner if performance matters more than readability.
Why: Each string's characters are still sorted before comparison, and the pipeline builds two full sorted String copies along the way.
Key Concepts
Interview Questions
Does the sorting approach work for Unicode and uppercase letters?
Sorting compares raw char values, so 'A' and 'a' are different. Lower-case both strings first, and strip spaces if phrases like "dormitory" and "dirty room" should count as anagrams.
Which approach is faster, sorting or counting?
Counting. Sorting both strings costs O(n log n), while a frequency array of 26 counters checks anagrams in O(n). For alphabets larger than a–z, use a HashMap<Character, Integer> instead of the fixed array.
What's the quickest check before doing any real work?
Compare the lengths. Two strings of different lengths can never be anagrams, so returning false early skips the sort or the counting entirely.