Java Strings Capstone Projects: 5 Production-Grade Systems
Project 1: Palindrome Checker ยท Project 2: Word Counter & Text Stats ยท Project 3: Character & Frequency Analyzer ยท Project 4: Enterprise Username Validator ยท Project 5: Password Security & Entropy Evaluator
Building 5 complete, real-world string processing projects in Java: dual-pointer palindrome verification with alphanumeric sanitization, a multi-metric word & sentence text statistics engine, an ASCII character frequency analyzer, an enterprise username validator with business rules, and an industrial-grade password strength and entropy evaluator.
1. Architecture of the 5 Capstone Projects
In this capstone chapter, we combine all string concepts from Phase 6 (Immutability, SCP, String Methods, Regular Expressions, String Equality, and StringBuilder) into 5 production-grade software modules:
1. Project 1: Dual-Pointer Palindrome Checker:
Validates whether a phrase reads identically backwards and forwards (e.g. *"A man, a plan, a canal: Panama"*), ignoring spaces, punctuation, and casing using an optimal O(N) two-pointer algorithm with zero memory allocation.
2. Project 2: Word Counter & Text Statistics Engine:
Analyzes text documents to report total words, character count (with/without spaces), unique word count, total sentences, and average word length.
3. Project 3: Character & Frequency Distribution Analyzer:
Scans text to categorize vowels, consonants, numbers, and special symbols, and builds an exact frequency histogram of characters.
4. Project 4: Enterprise Username & Email Validator:
Enforces strict corporate registration rules: length between 5-20 characters, alphanumeric with underscores, cannot start with a number, and blocks reserved administrative keywords (e.g. admin, root, null, system).
5. Project 5: Advanced Password Strength & Security Evaluator:
Calculates a 0-100 security score based on length (minimum 8, ideal 12+), uppercase/lowercase balance, numbers, special characters, and verifies against a blacklist of common weak passwords.
2. Optimal String Algorithms Mental Model
Project 1: Two-Pointer Palindrome Algorithm:
Left Pointer (i=0) -> [A] m a n a p l a n a c a n a l p a n a m [a] <- Right Pointer (j=len-1)
| |
+----------------(Match!)---------------+
Skip non-alphanumeric chars; move pointers inward until i >= j.
Project 5: Password Security Scoring Formula:
+ Length >= 8 (+15 pts), Length >= 12 (+25 pts)
+ Uppercase (+15 pts), Lowercase (+15 pts)
+ Numbers (+15 pts), Special Symbols (+15 pts)
- Common Blacklist / Sequential Repetition (-40 pts)
======================================================
Score: 0-40 (Weak) | 41-70 (Moderate) | 71-100 (Strong)
Beginner Example & Code Anatomy
public class Main {
// -------------------------------------------------------------
// PROJECT 1: Dual-Pointer Palindrome Checker (O(N) Time, O(1) Space)
// -------------------------------------------------------------
public static boolean isPalindrome(String input) {
if (input == null) return false;
int left = 0;
int right = input.length() - 1;
while (left < right) {
char lChar = input.charAt(left);
char rChar = input.charAt(right);
if (!Character.isLetterOrDigit(lChar)) {
left++;
} else if (!Character.isLetterOrDigit(rChar)) {
right--;
} else {
if (Character.toLowerCase(lChar) != Character.toLowerCase(rChar)) {
return false;
}
left++;
right--;
}
}
return true;
}
// -------------------------------------------------------------
// PROJECT 2: Word Counter & Text Statistics Engine
// -------------------------------------------------------------
public static void printTextStatistics(String text) {
if (text == null || text.isBlank()) {
System.out.println("Text is empty.");
return;
}
String[] words = text.trim().split("\\s+");
int totalCharsWithSpaces = text.length();
int totalCharsNoSpaces = text.replace(" ", "").replace("\n", "").replace("\t", "").length();
String[] sentences = text.split("[.!?]+");
int totalWordLength = 0;
String longestWord = "";
for (String w : words) {
String cleanWord = w.replaceAll("[^a-zA-Z0-9]", "");
totalWordLength += cleanWord.length();
if (cleanWord.length() > longestWord.length()) {
longestWord = cleanWord;
}
}
double avgWordLength = words.length > 0 ? (double) totalWordLength / words.length : 0;
System.out.println(" Total Words : " + words.length);
System.out.println(" Total Characters (All): " + totalCharsWithSpaces);
System.out.println(" Chars (Without Spaces): " + totalCharsNoSpaces);
System.out.println(" Sentence Count : " + sentences.length);
System.out.println(" Longest Word : " + longestWord + " (" + longestWord.length() + " chars)");
System.out.printf(" Average Word Length : %.2f chars%n", avgWordLength);
}
// -------------------------------------------------------------
// PROJECT 3: Character Category & Frequency Counter
// -------------------------------------------------------------
public static void analyzeCharacterFrequencies(String text) {
int vowels = 0, consonants = 0, digits = 0, special = 0, spaces = 0;
int[] freq = new int[256]; // ASCII Frequency Table
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (ch < 256) freq[ch]++;
if (Character.isDigit(ch)) {
digits++;
} else if (Character.isWhitespace(ch)) {
spaces++;
} else if (Character.isLetter(ch)) {
char lower = Character.toLowerCase(ch);
if (lower == 'a' || lower == 'e' || lower == 'i' || lower == 'o' || lower == 'u') {
vowels++;
} else {
consonants++;
}
} else {
special++;
}
}
System.out.println(" Vowels : " + vowels);
System.out.println(" Consonants : " + consonants);
System.out.println(" Digits (0-9) : " + digits);
System.out.println(" Spaces : " + spaces);
System.out.println(" Special Chars: " + special);
}
// -------------------------------------------------------------
// PROJECT 4: Enterprise Username Validator
// -------------------------------------------------------------
public static boolean validateUsername(String username) {
if (username == null) return false;
String clean = username.trim();
// Rule 1: Length 5 to 20
if (clean.length() < 5 || clean.length() > 20) return false;
// Rule 2: Cannot start with a digit or underscore
if (!Character.isLetter(clean.charAt(0))) return false;
// Rule 3: Only alphanumeric + underscores
if (!clean.matches("^[a-zA-Z0-9_]+$")) return false;
// Rule 4: Reserved administrative blacklist
String lower = clean.toLowerCase();
String[] reserved = {"admin", "root", "system", "administrator", "null", "superuser"};
for (String r : reserved) {
if (lower.equals(r)) return false;
}
return true;
}
// -------------------------------------------------------------
// PROJECT 5: Password Strength & Security Evaluator
// -------------------------------------------------------------
public static String evaluatePasswordStrength(String password) {
if (password == null || password.length() < 6) return "CRITICAL: Too Short (Score: 0/100)";
int score = 0;
if (password.length() >= 8) score += 15;
if (password.length() >= 12) score += 15;
if (password.length() >= 16) score += 10;
boolean hasUpper = false, hasLower = false, hasDigit = false, hasSpecial = false;
for (char ch : password.toCharArray()) {
if (Character.isUpperCase(ch)) hasUpper = true;
else if (Character.isLowerCase(ch)) hasLower = true;
else if (Character.isDigit(ch)) hasDigit = true;
else hasSpecial = true;
}
if (hasUpper) score += 15;
if (hasLower) score += 15;
if (hasDigit) score += 15;
if (hasSpecial) score += 15;
// Blacklist check
String[] commonWeak = {"password", "12345678", "qwerty", "admin123", "password123"};
for (String weak : commonWeak) {
if (password.toLowerCase().contains(weak)) {
score = Math.max(0, score - 40);
}
}
String rating = score >= 80 ? "STRONG ๐ข" : (score >= 50 ? "MODERATE ๐ก" : "WEAK ๐ด");
return String.format("%s (Score: %d/100)", rating, score);
}
public static void main(String[] args) {
System.out.println("=== PROJECT 1: Palindrome Checker ===");
String p1 = "A man, a plan, a canal: Panama";
String p2 = "Java Programming";
System.out.println(""" + p1 + "" -> " + isPalindrome(p1)); // true
System.out.println(""" + p2 + "" -> " + isPalindrome(p2)); // false
System.out.println("
=== PROJECT 2: Word Counter & Text Statistics ===");
String article = "Java is a powerful, multi-threaded programming language! It enables robust enterprise systems. Java 21 LTS is blazing fast.";
printTextStatistics(article);
System.out.println("
=== PROJECT 3: Character & Frequency Analyzer ===");
analyzeCharacterFrequencies("Java 21 LTS Released on Sep 2023! #1 Backend");
System.out.println("
=== PROJECT 4: Enterprise Username Validator ===");
String[] testUsers = {"ravi_kumar", "admin", "99developer", "alex_dev_2026", "a"};
for (String u : testUsers) {
System.out.printf("Username: %-16s | Valid: %b%n", u, validateUsername(u));
}
System.out.println("
=== PROJECT 5: Password Strength Evaluator ===");
String[] testPasswords = {"pass", "password123", "Java2026", "J@v4_Str0ng_P@ssw0rd!#2026"};
for (String pwd : testPasswords) {
System.out.printf("Password: %-26s | %s%n", pwd, evaluatePasswordStrength(pwd));
}
}
}
๐ Line-by-Line Code Explanation
isPalindrome(String input)
Uses a dual-pointer loop skipping non-alphanumeric characters with Character.isLetterOrDigit(), achieving O(N) time and O(1) space.
text.trim().split("\\s+");
Splits on one or more whitespace characters to extract words cleanly regardless of spacing.
clean.matches("^[a-zA-Z0-9_]+$");
Enforces that only English letters, digits, and underscores are present in the username.
evaluatePasswordStrength(String password)
Calculates an additive score across length tiers, 4 character categories, and deducts penalty points for dictionary passwords.
Practical Real-World Example
public class PracticalApplication {
public static void main(String[] args) {
// Industry Simulation: User Registration Validation Pipeline
String candidateUser = "kavya_developer";
String candidatePass = "K@vy4_Secur3_2026!";
System.out.println("=== Security Registration Gate ===");
boolean isUserOk = Main.validateUsername(candidateUser);
String passResult = Main.evaluatePasswordStrength(candidatePass);
System.out.println("Username Check : " + (isUserOk ? "ACCEPTED" : "REJECTED"));
System.out.println("Password Check : " + passResult);
if (isUserOk && passResult.contains("STRONG")) {
System.out.println("STATUS : Account Created Successfully โ
");
} else {
System.out.println("STATUS : Registration Failed โ");
}
}
}
- Using .split(" ") instead of .split("\\s+") for word counting, which creates empty tokens when multiple spaces exist.
- Checking passwords only for length without testing character complexity or blacklists.
- Reversing strings by creating multiple substrings inside a loop instead of using a two-pointer technique or StringBuilder.reverse().
- Forgetting that Character.isLetterOrDigit() handles international characters, which is essential for global applications.
Test your understanding by writing the code directly in your editor or running in our online Java compiler:
// Coding Challenge:
// Add a 6th method to the security suite:
// sanitizePhoneNumber(String phone) that:
// 1. Takes any messy phone format: "+1 (555) 234-5678", "555.234.5678", "555 234 5678".
// 2. Extracts only digits.
// 3. Formats it into standard international format: "+1-555-234-5678".
public class Challenge {
public static String sanitizePhoneNumber(String phone) {
String digits = phone.replaceAll("[^0-9]", "");
if (digits.length() == 10) {
digits = "1" + digits; // Default country code
}
if (digits.length() == 11) {
return String.format("+%s-%s-%s-%s",
digits.substring(0, 1),
digits.substring(1, 4),
digits.substring(4, 7),
digits.substring(7, 11));
}
return "Invalid Phone Number";
}
public static void main(String[] args) {
System.out.println(sanitizePhoneNumber("+1 (555) 234-5678"));
System.out.println(sanitizePhoneNumber("555.234.5678"));
}
}
๐ก Frequently Asked Questions & Interview Insights
โ Why is the two-pointer palindrome approach better than StringBuilder.reverse()?
The two-pointer approach operates in-place with O(1) auxiliary memory without allocating a new string or StringBuilder object, making it much faster for large text documents.
โ How does regex \\s+ work in split()?
\\s matches any whitespace character (space, tab, newline), and + matches one or more consecutive occurrences, preventing empty strings when multiple spaces are used.
โ Why should password validation deduct points for blacklisted strings?
A 16-character password like "passwordpassword" passes length and character count checks but can be cracked in milliseconds by dictionary attacks.
๐ Quick Chapter Recap
- Two-pointer algorithms enable memory-efficient in-place palindrome validation.
- Regex \s+ and [^a-zA-Z0-9] allow robust tokenization and sanitization of user text.
- Character frequency analysis can be performed with fixed-size 256-element ASCII frequency tables in O(N) time.
- Username validation requires multi-stage checks: length, character classes, and reserved blacklist guards.
- Password strength evaluation requires multi-factor entropy scoring combining length, diversity, and dictionary attack defense.