How to Check Anagram in Java
What is an Anagram?
An anagram is a word formed by rearranging the letters of another word. Examples: "listen" and "silent", "triangle" and "integral"
Solutions
Method 1: Using Sorting
import java.util.Arrays;
public static boolean isAnagram(String str1, String str2) {
// Remove spaces and convert to lowercase
str1 = str1.replaceAll("\\s", "").toLowerCase();
str2 = str2.replaceAll("\\s", "").toLowerCase();
// Check if lengths are different
if (str1.length() != str2.length()) {
return false;
}
// Sort both strings and compare
char[] arr1 = str1.toCharArray();
char[] arr2 = str2.toCharArray();
Arrays.sort(arr1);
Arrays.sort(arr2);
return Arrays.equals(arr1, arr2);
}
// Usage
System.out.println(isAnagram("listen", "silent")); // true
System.out.println(isAnagram("hello", "world")); // falseMethod 2: Using Character Count
public static boolean isAnagram(String str1, String str2) {
str1 = str1.replaceAll("\\s", "").toLowerCase();
str2 = str2.replaceAll("\\s", "").toLowerCase();
if (str1.length() != str2.length()) {
return false;
}
int[] count = new int[26];
for (int i = 0; i < str1.length(); i++) {
count[str1.charAt(i) - 'a']++;
count[str2.charAt(i) - 'a']--;
}
for (int c : count) {
if (c != 0) {
return false;
}
}
return true;
}
// Usage
System.out.println(isAnagram("triangle", "integral")); // trueDid You Know?
The longest one-word anagrams in English are "conversationalists" and "conservationalists" - both have 18 letters!
Pro Tip
The character count method is more efficient (O(n)) than sorting (O(n log n)) for large strings!
Real-World Use Cases
- Word games: Scrabble, anagram solvers
- Cryptography: Simple encryption techniques
- Plagiarism detection: Identify rearranged text
- Data deduplication: Find similar entries
›Short versionOpen if you only have a minute.
- Same characters, same counts, order ignored. "listen" and "silent" match.
- Sorting both char arrays is O(n log n). A frequency count is linear.
- An int[26] indexed by c - 'a' throws as soon as a space, a digit, or an uppercase letter appears.
- toLowerCase() without Locale.ROOT follows the default locale. Turkish I does not fold to i.
Anagram check
Decide whether two strings contain the same characters with the same frequencies.
Working approach
- If the contract ignores spaces and case, normalize both copies with Locale.ROOT first.
- Reject a length mismatch after that normalization.
- Count with a map when the alphabet is not known to be a-z. Use int[26] only after you have checked that every char is in range.
Walk the sample
- "listen" and "silent"
- Lengths match
- Each letter increments on one side and decrements on the other
- Every count ends at 0
The trap
count[c - 'a'] assumes every remaining character is a lowercase English letter. A space makes a negative index.
static boolean sameLetters(String a, String b) {
if (a.length() != b.length()) {
return false;
}
int[] count = new int[26];
for (int i = 0; i < a.length(); i++) {
int left = a.charAt(i) - 'a';
int right = b.charAt(i) - 'a';
if (left < 0 || left >= 26 || right < 0 || right >= 26) {
throw new IllegalArgumentException("expected lowercase a-z");
}
count[left]++;
count[right]--;
}
for (int n : count) {
if (n != 0) {
return false;
}
}
return true;
}What does count[c - 'a'] do when c is a space?
' ' - 'a' is negative. The write into the 26-slot array throws ArrayIndexOutOfBoundsException.
Strip or reject out-of-range characters before indexing, or count with a Map. Also fold case with Locale.ROOT so a Turkish default locale does not turn I into ı.
A count is O(n) time. Sorting is O(n log n). Space depends on the alphabet, not on the length, for a fixed map.
Easy to get wrong
- Indexing a 26-slot array with arbitrary text.
- Comparing lengths before removing the spaces the contract told you to ignore.