String Fundamentals
Solve one Java logic problem at a time, then flip for the complete explanation and program.
Solve one Java logic problem at a time, then flip for the complete explanation and program.
Java Logic Development · Chapter 14 Companion Article
Fifteen foundational String-handling problems — reading input, manual length counting, character traversal, reversal, comparison, case conversion, and character/word counting — solved without relying on shortcut methods, followed by a comparison of core concepts: immutability, indexing, charAt() versus toCharArray(), String versus char, equals() versus ==, and StringBuilder for repeated modification. These fundamentals form the base for later string problems such as palindromes, anagrams, and substring algorithms.
A String stores a sequence of characters. In Java, Scanner is commonly used to read string input from the console.
next() reads only one word, while nextLine() reads the complete line including spaces.
Read a complete string entered by the user and print it.
Java Logic Development
You entered: Java Logic Development
Use Scanner.nextLine() when the input can contain spaces.
Scanner object.nextLine() to read the complete input line.String.nextLine() continues reading characters until the user presses Enter. Because it does not stop at whitespace, it is suitable for names, sentences, addresses, and other multi-word input.
Input:
Java Logic Development
Execution:
scanner.nextLine() reads the complete line.text becomes "Java Logic Development".text.import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String text = scanner.nextLine();
System.out.println("You entered: " + text);
scanner.close();
}
}
For input:
Java Logic Development
Output:
You entered: Java Logic Development
O(n)O(n)Here, n is the number of characters.
O(n) for storing the input string.
next() when the input contains spaces.nextLine() immediately after nextInt() without consuming the remaining newline.Know the difference between:
next() → reads one token.nextLine() → reads the complete line.Normally, Java provides String.length(). To practice logic without using this method, the string can be converted into a character array and the characters can be counted manually.
Find the number of characters in a string without calling String.length().
Java
Length: 4
Convert the string to a character array and increase a counter for every character.
toCharArray().count to 0.count.Every character in the original string becomes one element in the character array. Counting those elements gives the number of characters in the string without using String.length().
String:
Java
Characters:
| Character | Count |
|---|---|
| J | 1 |
| a | 2 |
| v | 3 |
| a | 4 |
Final length:
4
public class Main {
public static void main(String[] args) {
String text = "Java";
int count = 0;
for (char ch : text.toCharArray()) {
count++;
}
System.out.println("Length: " + count);
}
}
Length: 4
O(n)
O(n) because toCharArray() creates a character array.
A character iterator such as text.chars() can also process the characters, but using a simple character array is easier for basic logic development.
For an empty string:
""
The counter remains 0.
Do not confuse:
string.length() → method.array.length → field.If an interviewer specifically prohibits length(), confirm whether converting the string to a character array is allowed.
Character traversal means visiting every character of a string one by one.
The most common approach uses:
charAt(index)
String indexes start from 0.
Traverse a string and print every character separately.
String:
Java
Expected output:
J
a
v
a
Run a loop from index 0 to length() - 1.
i = 0.i < text.length().text.charAt(i).For:
Java
| Index | charAt(index) |
|---|---|
| 0 | J |
| 1 | a |
| 2 | v |
| 3 | a |
public class Main {
public static void main(String[] args) {
String text = "Java";
for (int i = 0; i < text.length(); i++) {
System.out.println(text.charAt(i));
}
}
}
J
a
v
a
O(n)
O(1)
The last valid index is:
text.length() - 1
For a four-character string, valid indexes are 0 through 3.
Using:
i <= text.length()
causes StringIndexOutOfBoundsException.
Correct condition:
i < text.length()
Character traversal is the foundation of many string problems such as palindrome checking, frequency counting, case conversion, filtering, and pattern matching.
Reversing a string means arranging its characters from the last character to the first.
Example:
Java → avaJ
Reverse a string without using StringBuilder.reverse().
Java
Reversed: avaJ
Start from the last index and move toward index 0.
StringBuilder.text.length() - 1.0.Strings are immutable in Java. Repeatedly using result = result + ch creates multiple temporary String objects.
StringBuilder allows characters to be appended efficiently.
Original:
Java
| Index | Character | Result |
|---|---|---|
| 3 | a | a |
| 2 | v | av |
| 1 | a | ava |
| 0 | J | avaJ |
public class Main {
public static void main(String[] args) {
String text = "Java";
StringBuilder reversed = new StringBuilder();
for (int i = text.length() - 1; i >= 0; i--) {
reversed.append(text.charAt(i));
}
System.out.println("Reversed: " + reversed);
}
}
Reversed: avaJ
O(n)
O(n)
Example:
Java 8! → !8 avaJ
Starting from:
text.length()
instead of:
text.length() - 1
The first attempt accesses an invalid index.
For an in-place reversal question, interviewers may ask you to convert the string to a character array and swap characters using two pointers.
Java strings should normally be compared using equals() rather than ==.
equals() compares character content.
== compares object references.
Check whether two strings contain exactly the same sequence of characters.
first = "Java"
second = "Java"
Expected output:
Strings are equal
Compare length first and then compare corresponding characters.
To understand the comparison internally:
Strings:
Java
Java
| Index | First | Second | Match |
|---|---|---|---|
| 0 | J | J | Yes |
| 1 | a | a | Yes |
| 2 | v | v | Yes |
| 3 | a | a | Yes |
All characters match.
public class Main {
public static void main(String[] args) {
String first = "Java";
String second = "Java";
boolean equal = true;
if (first.length() != second.length()) {
equal = false;
} else {
for (int i = 0; i < first.length(); i++) {
if (first.charAt(i) != second.charAt(i)) {
equal = false;
break;
}
}
}
if (equal) {
System.out.println("Strings are equal");
} else {
System.out.println("Strings are not equal");
}
}
}
Strings are equal
For normal Java applications:
first.equals(second)
For case-insensitive comparison:
first.equalsIgnoreCase(second)
O(n) in the worst case.
O(1)
Avoid:
first == second
when the goal is content comparison.
Be ready to explain why this can behave differently:
String a = new String("Java");
String b = new String("Java");
a.equals(b) is true because the contents match, while a == b is false because they refer to different objects.
Uppercase English letters A-Z can be converted to lowercase by applying the difference between uppercase and lowercase Unicode values.
For basic English letters:
'a' - 'A' = 32
Convert uppercase letters in a string to lowercase without using toLowerCase().
JAVA Logic
java logic
Check whether a character is between 'A' and 'Z'.
For every character:
ch >= 'A' && ch <= 'Z'.Input:
JAVA Logic
| Character | Action | Result Character |
|---|---|---|
| J | Convert | j |
| A | Convert | a |
| V | Convert | v |
| A | Convert | a |
| space | Keep | space |
| L | Convert | l |
| o | Keep | o |
| g | Keep | g |
| i | Keep | i |
| c | Keep | c |
Result:
java logic
public class Main {
public static void main(String[] args) {
String text = "JAVA Logic";
StringBuilder result = new StringBuilder();
for (char ch : text.toCharArray()) {
if (ch >= 'A' && ch <= 'Z') {
ch = (char) (ch + ('a' - 'A'));
}
result.append(ch);
}
System.out.println(result);
}
}
java logic
O(n)
O(n)
Production code normally uses:
text.toLowerCase()
Manual conversion is mainly useful for understanding character operations.
The manual 'A' to 'Z' logic handles basic English alphabet characters only. Java's built-in Unicode-aware APIs should be preferred when international text must be handled correctly.
Explain the difference between learning ASCII-style case conversion and writing Unicode-aware application code.
Lowercase English characters can be converted to uppercase by subtracting the character-value difference between 'a' and 'A'.
Convert lowercase English letters to uppercase without using toUpperCase().
java Logic
JAVA LOGIC
Only modify characters between 'a' and 'z'.
Input:
java Logic
| Character | Converted |
|---|---|
| j | J |
| a | A |
| v | V |
| a | A |
| space | space |
| L | L |
| o | O |
| g | G |
| i | I |
| c | C |
public class Main {
public static void main(String[] args) {
String text = "java Logic";
StringBuilder result = new StringBuilder();
for (char ch : text.toCharArray()) {
if (ch >= 'a' && ch <= 'z') {
ch = (char) (ch - ('a' - 'A'));
}
result.append(ch);
}
System.out.println(result);
}
}
JAVA LOGIC
O(n)
O(n)
Input:
java123!
Result:
JAVA123!
Digits and symbols remain unchanged.
Do not convert every character blindly. Applying arithmetic to digits or special characters changes them into unrelated characters.
The key requirement is the range check:
ch >= 'a' && ch <= 'z'
before performing the conversion.
Case toggling changes:
Example:
JaVa123 → jAvA123
Toggle the case of every alphabetic character in a string.
Use separate conditions for uppercase and lowercase letters.
For each character:
'A' and 'Z', convert it to lowercase.'a' and 'z', convert it to uppercase.Input:
JaVa 8!
| Character | Type | Result |
|---|---|---|
| J | Uppercase | j |
| a | Lowercase | A |
| V | Uppercase | v |
| a | Lowercase | A |
| space | Other | space |
| 8 | Other | 8 |
| ! | Other | ! |
Result:
jAvA 8!
public class Main {
public static void main(String[] args) {
String text = "JaVa 8!";
StringBuilder result = new StringBuilder();
for (char ch : text.toCharArray()) {
if (ch >= 'A' && ch <= 'Z') {
ch = (char) (ch + ('a' - 'A'));
} else if (ch >= 'a' && ch <= 'z') {
ch = (char) (ch - ('a' - 'A'));
}
result.append(ch);
}
System.out.println(result);
}
}
jAvA 8!
O(n)
O(n)
Using two independent if statements can accidentally convert a character twice.
For example, after converting uppercase J to lowercase j, a second lowercase check could convert it back.
Using if followed by else if avoids this problem.
This question tests character classification, conditional ordering, and conversion logic in a single traversal.
Character counting finds how many characters are present in a string.
Depending on the requirement, spaces may either be included or excluded. The requirement must therefore be clear.
Here, every character including spaces is counted.
Count the total number of characters in a string without using String.length().
Java 8
Characters: 6
Traverse the characters and increment one counter for each character encountered.
count = 0.count.Input:
Java 8
Characters:
J a v a [space] 8
| Character | Count |
|---|---|
| J | 1 |
| a | 2 |
| v | 3 |
| a | 4 |
| space | 5 |
| 8 | 6 |
public class Main {
public static void main(String[] args) {
String text = "Java 8";
int count = 0;
for (char ch : text.toCharArray()) {
count++;
}
System.out.println("Characters: " + count);
}
}
Characters: 6
O(n)
O(n) because toCharArray() creates an array.
The condition can be changed to:
if (ch != ' ') {
count++;
}
Do not assume that "character count" always means alphabetic characters. A character may also be a digit, whitespace, punctuation mark, or symbol.
Clarify whether the interviewer wants:
char values.The English vowels are:
a, e, i, o, u
Their uppercase forms should normally be counted as well.
Count the vowels present in a string.
Java Programming
Vowels: 5
Convert the current character to lowercase before comparing it with the five vowels.
count = 0.Character.toLowerCase().a, e, i, o, or u.Input:
Java Programming
Vowels encountered:
a
a
o
a
i
Total:
5
public class Main {
public static void main(String[] args) {
String text = "Java Programming";
int count = 0;
for (char ch : text.toCharArray()) {
char current = Character.toLowerCase(ch);
if (current == 'a' || current == 'e' || current == 'i' || current == 'o' || current == 'u') {
count++;
}
}
System.out.println("Vowels: " + count);
}
}
Vowels: 5
O(n)
O(n) because of the character array.
Input:
12345
Result:
Vowels: 0
Input:
AEIOU
Result:
Vowels: 5
Checking only lowercase vowels causes uppercase vowels to be ignored.
For repeated vowel checking in larger problems, a Set<Character> may improve readability. For only five vowels, direct comparisons are simple and efficient.
A consonant is an alphabetic character that is not a vowel.
Digits, spaces, and special characters must not be counted as consonants.
Count consonants in a string containing letters, digits, spaces, or symbols.
Java 8!
Consonants: 2
First check that the character is a letter. Then verify that it is not a vowel.
For each character:
'a' and 'z'.a, e, i, o, u.Checking only "not a vowel" would incorrectly count:
as consonants.
Input:
Java 8!
| Character | Letter? | Vowel? | Consonant Count |
|---|---|---|---|
| J | Yes | No | 1 |
| a | Yes | Yes | 1 |
| v | Yes | No | 2 |
| a | Yes | Yes | 2 |
| space | No | No | 2 |
| 8 | No | No | 2 |
| ! | No | No | 2 |
public class Main {
public static void main(String[] args) {
String text = "Java 8!";
int count = 0;
for (char ch : text.toCharArray()) {
char current = Character.toLowerCase(ch);
boolean isLetter = current >= 'a' && current <= 'z';
boolean isVowel = current == 'a' || current == 'e' || current == 'i' || current == 'o' || current == 'u';
if (isLetter && !isVowel) {
count++;
}
}
System.out.println("Consonants: " + count);
}
}
Consonants: 2
O(n)
O(n)
Java provides:
Character.isLetter(ch)
This is preferable when Unicode alphabetic characters must also be handled.
This condition is incomplete:
if (!isVowel) {
count++;
}
It also counts non-letter characters.
A good answer clearly separates character classification from vowel checking.
A string may contain alphabetic characters and numeric characters together.
Example:
Java17Version8
Digits are:
1, 7, 8
Count numeric digits present inside a string.
Java17Version8
Digits: 3
A decimal digit lies between '0' and '9'.
count = 0.ch >= '0' && ch <= '9'
Input:
Java17Version8
Relevant characters:
| Character | Digit? | Count |
|---|---|---|
| J | No | 0 |
| a | No | 0 |
| v | No | 0 |
| a | No | 0 |
| 1 | Yes | 1 |
| 7 | Yes | 2 |
| V | No | 2 |
| ... | No | 2 |
| 8 | Yes | 3 |
public class Main {
public static void main(String[] args) {
String text = "Java17Version8";
int count = 0;
for (char ch : text.toCharArray()) {
if (ch >= '0' && ch <= '9') {
count++;
}
}
System.out.println("Digits: " + count);
}
}
Digits: 3
O(n)
O(n)
Java also provides:
Character.isDigit(ch)
This handles a broader range of Unicode digit characters.
Counting digits is different from counting numbers.
For:
Java123Test45
Digit count:
5
Number groups:
2
The numbers are 123 and 45.
Clarify whether the problem asks for individual digits or complete numeric sequences.
For this problem, a special character is a character that is:
Examples include:
@ # $ % & ! ?
Count special characters in a string while ignoring letters, digits, and spaces.
Java@2026#Dev!
Special characters: 3
Count a character only when it does not belong to the letter, digit, or whitespace categories.
For every character:
Input:
Java@2026#Dev!
Special characters:
| Character | Special? | Count |
|---|---|---|
| J | No | 0 |
| a | No | 0 |
| v | No | 0 |
| a | No | 0 |
| @ | Yes | 1 |
| 2 | No | 1 |
| 0 | No | 1 |
| 2 | No | 1 |
| 6 | No | 1 |
| # | Yes | 2 |
| D | No | 2 |
| e | No | 2 |
| v | No | 2 |
| ! | Yes | 3 |
public class Main {
public static void main(String[] args) {
String text = "Java@2026#Dev!";
int count = 0;
for (char ch : text.toCharArray()) {
if (!Character.isLetterOrDigit(ch) && !Character.isWhitespace(ch)) {
count++;
}
}
System.out.println("Special characters: " + count);
}
}
Special characters: 3
O(n)
O(n)
Input:
Java 2026
Result:
Special characters: 0
The space is deliberately excluded from the special-character count.
Counting every non-alphanumeric character as special without deciding whether spaces should be included.
State the definition of "special character" before coding because requirements can vary between problems.
A word is a consecutive sequence of non-whitespace characters.
Consider:
Java Logic Development
There are three words even though several spaces appear between them.
A robust solution should therefore not assume exactly one space between words.
Count the number of words in a string without using split().
Java Logic Development
Words: 3
Count a word when a non-whitespace character appears immediately after whitespace or at the beginning of the string.
Use a boolean variable named inWord.
inWord = false.inWord is false:count.inWord = true.inWord = false.A word is counted only when entering a new sequence of non-space characters. Multiple consecutive spaces therefore do not increase the word count.
Input:
Java Logic Development
| Current Part | Action | Word Count |
|---|---|---|
| J | Start word | 1 |
| ava | Continue word | 1 |
| spaces | Leave word | 1 |
| L | Start word | 2 |
| ogic | Continue word | 2 |
| space | Leave word | 2 |
| D | Start word | 3 |
| evelopment | Continue word | 3 |
Final count:
3
public class Main {
public static void main(String[] args) {
String text = "Java Logic Development";
int count = 0;
boolean inWord = false;
for (char ch : text.toCharArray()) {
if (!Character.isWhitespace(ch)) {
if (!inWord) {
count++;
inWord = true;
}
} else {
inWord = false;
}
}
System.out.println("Words: " + count);
}
}
Words: 3
O(n)
O(n) because toCharArray() creates an array.
Empty string:
""
Result:
Words: 0
Only spaces:
" "
Result:
Words: 0
Leading and trailing spaces:
" Java Logic "
Result:
Words: 2
A convenient Java solution is:
text.trim().split("\\s+")
However, the manual traversal approach provides better logic practice and avoids creating an array of words.
Using:
spaces + 1
This fails when:
The state-based inWord technique is useful for parsing and scanning problems beyond simple word counting.
Removing spaces means building a new string that contains all required characters except space characters.
Example:
Java Logic Development
becomes:
JavaLogicDevelopment
Remove spaces from a string without using replace().
Java Logic Development
JavaLogicDevelopment
Append a character to the result only when it is not a space.
StringBuilder.ch != ' '.Input:
Java Logic
| Character | Action | Result |
|---|---|---|
| J | Keep | J |
| a | Keep | Ja |
| v | Keep | Jav |
| a | Keep | Java |
| space | Skip | Java |
| L | Keep | JavaL |
| o | Keep | JavaLo |
| g | Keep | JavaLog |
| i | Keep | JavaLogi |
| c | Keep | JavaLogic |
public class Main {
public static void main(String[] args) {
String text = "Java Logic Development";
StringBuilder result = new StringBuilder();
for (char ch : text.toCharArray()) {
if (ch != ' ') {
result.append(ch);
}
}
System.out.println(result);
}
}
JavaLogicDevelopment
O(n)
O(n)
To remove ordinary space characters:
text.replace(" ", "")
To remove different kinds of whitespace using regular expressions:
text.replaceAll("\\s+", "")
The manual condition:
ch != ' '
removes only the standard space character.
It does not remove tabs or newline characters.
For general whitespace handling, use:
!Character.isWhitespace(ch)
Using trim() when the requirement is to remove every space.
trim() removes leading and trailing spaces, not spaces in the middle.
Example:
" Java Logic ".trim()
becomes:
"Java Logic"
not:
"JavaLogic"
Clarify whether the requirement is to:
These are different string-processing problems.
| Problem | Core Technique | Main Java Feature | Time |
|---|---|---|---|
| Read a String | Input handling | nextLine() | O(n) |
Length Without length() | Manual counting | toCharArray() | O(n) |
| Character Traversal | Index traversal | charAt() | O(n) |
| Reverse String | Reverse traversal | StringBuilder | O(n) |
| Compare Strings | Character comparison | charAt() / equals() | O(n) |
| Uppercase to Lowercase | Character conversion | Range check | O(n) |
| Lowercase to Uppercase | Character conversion | Range check | O(n) |
| Toggle Case | Classification + conversion | if-else | O(n) |
| Count Characters | Counter | Character traversal | O(n) |
| Count Vowels | Classification | Character comparison | O(n) |
| Count Consonants | Letter + vowel checks | Conditions | O(n) |
| Count Digits | Character classification | '0' to '9' | O(n) |
| Count Special Characters | Multi-category filtering | Character methods | O(n) |
| Count Words | State tracking | inWord flag | O(n) |
| Remove Spaces | Filtering | StringBuilder | O(n) |
Java String objects are immutable. Once a string object is created, its contents cannot be modified.
For example:
String text = "Java";
text = text + " Logic";
The original "Java" object is not modified. A new string value is produced.
For repeated modifications inside loops, StringBuilder is generally more appropriate.
For:
String text = "Java";
Indexes are:
| Index | Character |
|---|---|
| 0 | J |
| 1 | a |
| 2 | v |
| 3 | a |
The valid range is:
0 to text.length() - 1
Accessing an index outside this range throws StringIndexOutOfBoundsException.
Use charAt() when working directly with positions:
char ch = text.charAt(i);
Use toCharArray() when a simple enhanced for loop is convenient:
for (char ch : text.toCharArray()) {
// Process character
}
toCharArray() creates an additional array, while charAt() can access the original string directly.
A char stores one UTF-16 code unit:
char ch = 'J';
A String stores a sequence:
String text = "Java";
Single quotes are used for char.
Double quotes are used for String.
Correct:
char ch = 'A';
String text = "A";
Incorrect:
char ch = "A";
String text = 'A';
Use:
first.equals(second)
for string content comparison.
Use:
first == second
only when you intentionally want to check whether both references point to the same object.
Avoid repeatedly doing this inside a large loop:
result = result + ch;
Each concatenation may create another string object.
Prefer:
StringBuilder result = new StringBuilder();
result.append(ch);
After processing:
String finalText = result.toString();
This technique is especially useful for:
Java's Character class contains useful methods for real application code.
Common examples:
Character.isLetter(ch)
Character.isDigit(ch)
Character.isLetterOrDigit(ch)
Character.isWhitespace(ch)
Character.isUpperCase(ch)
Character.isLowerCase(ch)
Character.toUpperCase(ch)
Character.toLowerCase(ch)
Manual 'A' to 'Z' checks are valuable for understanding logic, while these methods are usually preferable when broader character support is required.
== instead of equals() for content comparison.text.length() with charAt().0.next() when complete-line input is required.trim() when all internal spaces must be removed.char always represents an entire visible Unicode character.A learner should be able to explain and implement these operations without depending completely on built-in methods:
StringBuilder for repeated modifications.String is immutable.equals() versus ==.These fundamentals form the base for later string problems such as palindrome checking, anagram detection, character frequency, duplicate removal, substring problems, word reversal, compression, rotation, and interview-style string algorithms.