Arrays, Strings, and StringBuilder in Java

When diving into Java programming, the foundational tools for handling data and text are Arrays, Strings, and Builders. Each serves a distinct purpose, and together, they form the backbone of efficient data processing and text manipulation.
Arrays offer fixed-size, contiguous storage, making them the go-to choice when you need fast, indexed access to elements. Arrays lay the groundwork for more sophisticated data structures such as linked lists, trees, and hash tables. Whether you're storing integers for computation or objects for a sorting algorithm, arrays ensure you have a predictable memory layout and direct access to elements.
Strings are immutable sequences of characters, playing a critical role in text processing. Because Strings are immutable, they are safe to use across threads and reduce errors from unintended modifications. Immutable objects also facilitate caching, making Strings ideal for handling fixed or frequently reused text data. Think of applications that require processing user input, generating reports, or sending formatted responses — Strings are indispensable.
However, immutability in Strings can become a bottleneck when repeated modifications are necessary. This is where StringBuilder (and its thread-safe counterpart, StringBuffer) come into play. These mutable classes offer efficient text manipulation by avoiding the creation of multiple intermediate objects. Whether you are concatenating a series of log entries, parsing input data, or constructing large text blocks dynamically, StringBuilder provides a much-needed boost in performance.
Common Scenarios Where They Shine:
Processing Large Datasets:
Arrays handle large, fixed-size data collections efficiently, making them suitable for batch processing, sorting, and searching operations.Efficient Text Concatenation:
When building a long message from multiple pieces, using a StringBuilder avoids the overhead of creating numerous String objects.Parsing and Formatting Input/Output:
Strings are essential for parsing structured input (like CSV or JSON), while StringBuilder helps format dynamic output for reports or logs.
Arrays in Java
Introduction to Arrays
Definition:
An array is a fixed-size, contiguous collection of elements of the same data type. Arrays offer direct indexed access, making operations like lookups very efficient. They differ from other collections such as ArrayList
or LinkedList
in that their size is determined at the time of creation and cannot be changed dynamically.
Syntax:
Arrays can be declared, initialized, and accessed in the following ways:
// Declaration and initialization
int[] numbers = new int[5];
numbers[0] = 10;
// Inline initialization
int[] values = {1, 2, 3, 4, 5};
// Accessing elements
System.out.println(numbers[0]); // Output: 10
Multi-dimensional Arrays
Java supports multi-dimensional arrays such as 2D and 3D arrays.
2D Arrays:
A 2D array can be visualized as a table with rows and columns.
int[][] matrix = new int[3][3];
// Initializing elements
matrix[0][0] = 1;
matrix[1][2] = 5;
// Inline initialization
int[][] presetMatrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Jagged Arrays:
Jagged arrays are multi-dimensional arrays where each row can have a different number of columns.
int[][] jagged = new int[3][];
jagged[0] = new int[2];
jagged[1] = new int[4];
jagged[2] = new int[3];
// Initializing jagged array elements
jagged[0][0] = 1;
jagged[1][2] = 5;
Array Operations
Insertion:
Adding an element at a specific position (note that arrays are fixed in size, so this often involves shifting elements).
int[] numbers = {1, 2, 4, 5};
int pos = 2;
int newValue = 3;
// Shifting elements
for (int i = numbers.length - 1; i > pos; i--) {
numbers[i] = numbers[i - 1];
}
numbers[pos] = newValue;
Deletion:
Removing an element by shifting subsequent elements.
int[] numbers = {1, 2, 3, 4, 5};
int pos = 2; // Delete the element at index 2
for (int i = pos; i < numbers.length - 1; i++) {
numbers[i] = numbers[i + 1];
}
Traversal:
Looping through array elements.
int[] numbers = {1, 2, 3, 4, 5};
// Using a for loop
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
// Using an enhanced for loop
for (int num : numbers) {
System.out.println(num);
}
Utility Methods (Arrays
Class)
The java.util.Arrays
class provides many useful static methods for array manipulation.
sort()
: Sorts the array in ascending order.int[] arr = {3, 1, 4, 1, 5}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); // Output: [1, 1, 3, 4, 5]
binarySearch()
: Searches for a value in a sorted array.int[] arr = {1, 2, 3, 4, 5}; int index = Arrays.binarySearch(arr, 3); System.out.println(index); // Output: 2
copyOf()
/copyOfRange()
: Creates a copy of the array.int[] arr = {1, 2, 3}; int[] copy = Arrays.copyOf(arr, 5); System.out.println(Arrays.toString(copy)); // Output: [1, 2, 3, 0, 0]
equals()
: Compares two arrays for equality.int[] arr1 = {1, 2, 3}; int[] arr2 = {1, 2, 3}; System.out.println(Arrays.equals(arr1, arr2)); // Output: true
fill()
: Fills the array with a specified value.int[] arr = new int[5]; Arrays.fill(arr, 7); System.out.println(Arrays.toString(arr)); // Output: [7, 7, 7, 7, 7]
asList()
: Converts an array to aList
.String[] words = {"Java", "Python", "C++"}; List<String> list = Arrays.asList(words); System.out.println(list); // Output: [Java, Python, C++]
parallelSort()
: Performs parallel sorting for large datasets.int[] arr = {5, 2, 9, 1, 3}; Arrays.parallelSort(arr); System.out.println(Arrays.toString(arr)); // Output: [1, 2, 3, 5, 9]
Sorting Techniques
Built-in Sorting (
Arrays.sort()
):Uses Dual-Pivot Quicksort for primitive types.
Uses TimSort for objects (a hybrid of MergeSort and InsertionSort).
int[] arr = {3, 1, 4, 1, 5};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); // Output: [1, 1, 3, 4, 5]
Parallel Sorting (
Arrays.parallelSort()
):Suitable for large datasets, utilizes multiple threads.
Internally splits the array into segments and sorts them concurrently.
int[] arr = {10, 2, 8, 6, 7, 3};
Arrays.parallelSort(arr);
System.out.println(Arrays.toString(arr)); // Output: [2, 3, 6, 7, 8, 10]
Best Practices for Arrays
When to Use Arrays:
- When you need fixed-size collections with fast indexed access.
Performance Considerations:
Prefer arrays for primitive types to avoid the overhead of objects.
For dynamic sizing, consider using
ArrayList
.
Strings in Java
In Java, a String is an immutable sequence of characters. The immutability of Strings means that once a String object is created, its value cannot be changed. Instead, any modification creates a new String object. This property makes Strings safe for use in multithreaded environments and allows them to be cached or pooled, reducing memory overhead.
Why Immutability Matters:
Thread Safety: Since Strings are immutable, multiple threads can safely access the same String without synchronization.
Caching: The JVM maintains a string pool to reduce memory usage. If two String literals have the same value, they refer to the same object in the pool.
Security: Immutable Strings are useful in security contexts, such as storing passwords, because they cannot be modified.
String Pooling and Memory Management
When a String is created as a literal, it is automatically added to the string pool if it doesn't already exist. If a String with the same value exists, the new reference points to the existing String in the pool.
String s1 = "hello"; // Added to the string pool
String s2 = "hello"; // Points to the same object in the pool
System.out.println(s1 == s2); // Output: true
When using the new
keyword, a new String object is created on the heap, bypassing the string pool.
String s3 = new String("hello"); // New object on the heap
System.out.println(s1 == s3); // Output: false
Creating Strings
There are two primary ways to create Strings in Java:
String Literals (Added to the String Pool):
String s1 = "hello";
Using
new String()
(Creates a New Object):String s2 = new String("hello");
Common Methods in the String
Class
Manipulation Methods
concat()
: Concatenates the specified string to the end.String str = "Hello"; String result = str.concat(", World!"); System.out.println(result); // Output: Hello, World!
toUpperCase()
,toLowerCase()
: Converts to upper or lower case.String str = "Java"; System.out.println(str.toUpperCase()); // Output: JAVA
trim()
: Removes leading and trailing spaces.String str = " Hello "; System.out.println(str.trim()); // Output: Hello
replace()
,replaceAll()
: Replaces characters or substrings.String str = "banana"; System.out.println(str.replace('a', 'o')); // Output: bonono
substring()
: Extracts a substring.String str = "Programming"; System.out.println(str.substring(0, 4)); // Output: Prog
Search Methods
indexOf()
: Returns the index of the first occurrence of a character or substring.String str = "Hello, World!"; System.out.println(str.indexOf('W')); // Output: 7
lastIndexOf()
: Returns the last occurrence.System.out.println(str.lastIndexOf('o')); // Output: 8
contains()
: Checks if the string contains a substring.System.out.println(str.contains("World")); // Output: true
startsWith()
,endsWith()
: Checks the prefix or suffix.System.out.println(str.startsWith("Hello")); // Output: true
Comparison Methods
equals()
,equalsIgnoreCase()
: Compares strings for equality.String str1 = "Java"; String str2 = "java"; System.out.println(str1.equals(str2)); // Output: false System.out.println(str1.equalsIgnoreCase(str2)); // Output: true
compareTo()
: Lexicographically compares two strings.System.out.println(str1.compareTo(str2)); // Output: -32
matches()
: Checks if the string matches a regex.System.out.println(str1.matches("[Jj]ava")); // Output: true
Splitting and Joining
split()
: Splits the string based on a delimiter.String data = "apple,banana,cherry"; String[] fruits = data.split(","); for (String fruit : fruits) { System.out.println(fruit); } // Output: apple banana cherry
join()
: Joins strings with a delimiter.String result = String.join("-", "2024", "05", "01"); System.out.println(result); // Output: 2024-05-01
Character Access
charAt()
: Returns the character at a specified index.String str = "Java"; System.out.println(str.charAt(1)); // Output: a
getChars()
: Copies characters into a char array.char[] chars = new char[3]; str.getChars(0, 3, chars, 0); System.out.println(chars); // Output: Jav
Length and Empty Check
length()
: Returns the length of the string.String str = "Hello"; System.out.println(str.length()); // Output: 5
isEmpty()
: Checks if the string is empty.System.out.println(str.isEmpty()); // Output: false
String Interning and Performance
Concept of intern()
and String Pools
In Java, string interning is a technique where the JVM stores a single copy of each distinct string literal in a common pool, called the string pool or intern pool. This pool is part of the heap memory and helps optimize memory usage by reusing string literals instead of creating duplicate objects.
When a string is created using a string literal, it is automatically placed in the string pool:
String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2); // Output: true (same reference)
If a string is created using the new
keyword, it is stored in the heap rather than the string pool:
String str3 = new String("hello");
System.out.println(str1 == str3); // Output: false (different references)
You can force a string created with new
to be placed in the string pool using the intern()
method:
String str4 = new String("hello").intern();
System.out.println(str1 == str4); // Output: true (both reference the string pool)
Memory Optimization with Interning
String interning reduces memory usage by ensuring that only one copy of each distinct string literal is kept in the pool. This is particularly beneficial when dealing with a large number of duplicate strings.
Example:
String name1 = "Java";
String name2 = new String("Java").intern();
System.out.println(name1 == name2); // Output: true
In this example, after calling intern()
, name2
references the same string pool object as name1
.
Immutability and Concatenation Inefficiencies
Since Strings are immutable, any modification, such as concatenation or replacement, results in the creation of a new string object. This can lead to inefficiencies when performing repeated string modifications, especially within loops.
Example of Inefficient String Concatenation:
String result = "";
for (int i = 0; i < 5; i++) {
result += i; // Each iteration creates a new String object
}
System.out.println(result); // Output: 01234
In the above example, each iteration creates a new string object, which can be very slow and memory-intensive for large loops. To avoid the inefficiencies of immutable strings, Java provides StringBuilder
for mutable string manipulation. Unlike String
, StringBuilder
allows modifications without creating new objects each time.
StringBuilder and StringBuffer in Java
Java provides two classes for mutable sequences of characters: StringBuilder and StringBuffer. These classes are ideal for situations where repeated string modifications are required.
StringBuilder:
A mutable sequence of characters that is not thread-safe. This means that multiple threads accessing aStringBuilder
simultaneously can lead to unpredictable results. It is faster compared toStringBuffer
due to the absence of synchronization overhead.StringBuffer:
Similar toStringBuilder
, but it is thread-safe due to internal synchronization (locking mechanisms). This ensures that operations onStringBuffer
are safe in a multi-threaded environment, but this synchronization makes it slower compared toStringBuilder
.
Thread Safety in StringBuffer
means that only one thread can modify the instance at a time, ensuring consistency of data when accessed concurrently by multiple threads.
Creating Instances
Creating a StringBuilder
or StringBuffer
is straightforward:
// Creating a StringBuilder
StringBuilder sb = new StringBuilder("Hello");
// Creating a StringBuffer
StringBuffer sbf = new StringBuffer("Hello");
You can also create instances with an initial capacity to avoid frequent resizing:
StringBuilder sb = new StringBuilder(50);
Important Methods in StringBuilder
Both StringBuilder
and StringBuffer
offer the same set of methods. Here's a list of commonly used methods with examples:
append()
: Appends the specified string to the end.StringBuilder sb = new StringBuilder("Hello"); sb.append(", World!"); System.out.println(sb); // Output: Hello, World!
insert()
: Inserts a string at a specified position.sb.insert(5, " Java"); System.out.println(sb); // Output: Hello Java, World!
delete()
: Deletes a sequence of characters between two indices.sb.delete(5, 10); System.out.println(sb); // Output: Hello, World!
deleteCharAt()
: Deletes the character at a specified index.sb.deleteCharAt(5); System.out.println(sb); // Output: Hello World!
replace()
: Replaces characters between two indices with a specified string.sb.replace(6, 11, "Java"); System.out.println(sb); // Output: Hello Java!
reverse()
: Reverses the contents of theStringBuilder
.sb.reverse(); System.out.println(sb); // Output: !avaJ olleH
capacity()
: Returns the current capacity of the buffer.System.out.println(sb.capacity());
ensureCapacity()
: Ensures the buffer has a minimum capacity.sb.ensureCapacity(50);
charAt()
: Returns the character at the specified index.System.out.println(sb.charAt(0)); // Output: H
setCharAt()
: Sets the character at the specified index.sb.setCharAt(0, 'h'); System.out.println(sb); // Output: hello Java!
toString()
: Converts theStringBuilder
to aString
.String result = sb.toString(); System.out.println(result);
Code Example
StringBuilder sb = new StringBuilder("Java");
sb.append(" Programming").insert(0, "Learn ");
System.out.println(sb.toString()); // Output: Learn Java Programming
Differences Between String
, StringBuilder
, and StringBuffer
Feature | String | StringBuilder | StringBuffer |
Mutability | Immutable | Mutable | Mutable |
Thread Safety | Thread-safe | Not thread-safe | Thread-safe |
Performance | Slower for concatenation | Faster | Slower due to synchronization |
Use Case | Fixed or rarely modified strings | Frequent modifications in a single-threaded environment | Frequent modifications in a multi-threaded environment |
Regular Expressions with Strings in Java
Introduction to Regular Expressions
Regular Expressions (often abbreviated as regex) are sequences of characters that define a search pattern. They are incredibly powerful tools used for tasks such as:
Validating input (e.g., email addresses, phone numbers).
Searching within text (finding patterns).
Replacing parts of text (e.g., removing special characters).
Splitting text based on patterns (e.g., breaking a sentence into words).
In Java, the String
class provides methods like matches()
, replaceAll()
, and split()
that allow you to work with regular expressions effectively.
Java supports regex through the java.util.regex
package, but for basic use cases, the String
class methods are sufficient.
Regex Basics
Before diving into methods, let’s understand some basic components of regex:
Literal Characters: Match themselves directly.
Example:a
,b
,1
,A
Metacharacters: Special symbols with special meanings.
Example:.
,*
,+
,?
,^
,$
Character Classes: Match any character within a set.
Example:[abc]
matchesa
,b
, orc
.Quantifiers: Specify how many times a pattern should occur.
Example:a+
matches one or morea
s.Anchors: Specify positions in the text.
Example:^
(start of string),$
(end of string).
Common Regex Patterns
Here are some commonly used regex patterns:
.
– Matches any single character (except newline).\d
– Matches a digit (0-9).\D
– Matches a non-digit.\w
– Matches a word character (letters, digits, and underscores).\W
– Matches a non-word character.\s
– Matches a whitespace (space, tab, newline).\S
– Matches a non-whitespace.^
– Anchors the pattern to the beginning of the string.$
– Anchors the pattern to the end of the string.*
– Matches zero or more occurrences of the preceding character.+
– Matches one or more occurrences of the preceding character.?
– Matches zero or one occurrence of the preceding character.\
– Escapes a special character.
Using matches()
The matches()
method checks whether the entire string matches the given regex pattern. If the pattern matches the whole string, it returns true
; otherwise, false
.
Example 1: Validating an Email Address
String email = "user@example.com";
boolean isValid = email.matches("^[\\w.-]+@[a-zA-Z\\d.-]+\\.[a-zA-Z]{2,}$");
System.out.println(isValid); // Output: true
Explanation:
^
– Start of the string.[\\w.-]+
– One or more word characters (\w
), dots (.
), or hyphens (-
).@
– The@
symbol.[a-zA-Z\\d.-]+
– Domain name with letters, digits, dots, or hyphens.\\.
– A literal dot (.
).[a-zA-Z]{2,}
– At least two letters for the top-level domain (e.g.,com
,org
).$
– End of the string.
Example 2: Checking for a Numeric String
String number = "12345";
boolean isNumeric = number.matches("\\d+");
System.out.println(isNumeric); // Output: true
Explanation:
\\d+
– One or more digits (\d
).
Using replaceAll()
The replaceAll()
method replaces all substrings matching the regex pattern with the specified replacement string.
Example 1: Removing All Digits from a String
String text = "The year is 2024!";
String result = text.replaceAll("\\d", "");
System.out.println(result); // Output: The year is !
Explanation:
\\d
– Matches any digit.""
– Replaces each digit with an empty string (removes it).
Example 2: Replacing Multiple Spaces with a Single Space
String text = "This is a sentence.";
String result = text.replaceAll("\\s+", " ");
System.out.println(result); // Output: This is a sentence.
Explanation:
\\s+
– One or more whitespace characters." "
– Replaces them with a single space.
Example 3: Censoring Words
String text = "This is a bad word.";
String result = text.replaceAll("bad", "***");
System.out.println(result); // Output: This is a *** word.
Using split()
The split()
method splits the string based on the regex pattern and returns an array of substrings.
Example 1: Splitting a Sentence into Words
String sentence = "Java is fun to learn!";
String[] words = sentence.split("\\s");
for (String word : words) {
System.out.println(word);
}
Output:
Java
is
fun
to
learn!
Explanation:
\\s
– Matches any whitespace character (space, tab, etc.).
Example 2: Splitting by Commas
String data = "apple,banana,grape,orange";
String[] fruits = data.split(",");
for (String fruit : fruits) {
System.out.println(fruit);
}
Output:
apple
banana
grape
orange
Combining Methods for Complex Tasks
You can combine regex methods to perform more complex operations.
Example: Extracting and Formatting Data
Suppose you have a string with mixed data and want to extract digits and replace them with formatted numbers.
String data = "Item123Price456";
String formatted = data.replaceAll("(\\D+)(\\d+)", "$1: $2 ");
System.out.println(formatted); // Output: Item: 123 Price: 456
Explanation:
(\\D+)
– Captures one or more non-digits.(\\d+)
– Captures one or more digits."$1: $2 "
– Replaces the matched pattern with the first group ($1
), followed by:
, then the second group ($2
), and a space.
Example Programs
1. Anagram Checker (String)
Problem
Check if two strings are anagrams. Two strings are anagrams if they contain the same characters in a different order.
Solution Approach
Convert both strings to lowercase (to make it case-insensitive).
Remove any whitespace if necessary.
Convert both strings to character arrays and sort them.
Compare the sorted arrays. If they are equal, the strings are anagrams.
Java Code
import java.util.Arrays;
public class AnagramChecker {
public static boolean areAnagrams(String str1, String str2) {
// Convert to lowercase and remove whitespace
str1 = str1.toLowerCase().replaceAll("\\s+", "");
str2 = str2.toLowerCase().replaceAll("\\s+", "");
// Check if lengths are different
if (str1.length() != str2.length()) {
return false;
}
// Convert to char arrays and sort
char[] arr1 = str1.toCharArray();
char[] arr2 = str2.toCharArray();
Arrays.sort(arr1);
Arrays.sort(arr2);
return Arrays.equals(arr1, arr2);
}
public static void main(String[] args) {
String str1 = "Listen";
String str2 = "Silent";
System.out.println(areAnagrams(str1, str2)); // Output: true
}
}
Explanation
toLowerCase()
: Ensures case insensitivity.replaceAll("\\s+", "")
: Removes all whitespace.Arrays.sort()
: Sorts the character arrays.Arrays.equals()
: Compares the sorted arrays.
2. Reverse Words in a Sentence (StringBuilder)
Problem
Reverse the order of words in a given sentence.
Solution Approach
Split the sentence by spaces into words.
Use
StringBuilder
to reverse the words efficiently.Join the reversed words with spaces.
Java Code
public class ReverseWords {
public static String reverseWords(String sentence) {
String[] words = sentence.split("\\s+");
StringBuilder reversed = new StringBuilder();
for (int i = words.length - 1; i >= 0; i--) {
reversed.append(words[i]).append(" ");
}
return reversed.toString().trim();
}
public static void main(String[] args) {
String sentence = "Java is fun to learn";
System.out.println(reverseWords(sentence)); // Output: learn to fun is Java
}
}
Explanation
split("\\s+")
: Splits the sentence into words based on one or more spaces.StringBuilder
: Efficient for appending strings.trim()
: Removes any trailing spaces.
3. Palindrome Checker (String)
Problem
Check if a given string is a palindrome (reads the same forwards and backwards).
Solution Approach
Normalize the string by removing non-alphanumeric characters and converting to lowercase.
Use two pointers to compare characters from the beginning and end.
Java Code
public class PalindromeChecker {
public static boolean isPalindrome(String str) {
str = str.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
int left = 0;
int right = str.length() - 1;
while (left < right) {
if (str.charAt(left) != str.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
public static void main(String[] args) {
String str = "A man, a plan, a canal: Panama";
System.out.println(isPalindrome(str)); // Output: true
}
}
Explanation
replaceAll("[^a-zA-Z0-9]", "")
: Removes all non-alphanumeric characters.Two pointers:
left
starts from the beginning,right
from the end.Compare characters: If any mismatch occurs, return
false
.
4. Remove Duplicates from a String (String)
Problem
Remove all duplicate characters from a string while maintaining the original order.
Solution Approach
Use a
LinkedHashSet
to maintain insertion order and ensure uniqueness.Convert the set back to a string.
Java Code
import java.util.LinkedHashSet;
public class RemoveDuplicates {
public static String removeDuplicates(String str) {
LinkedHashSet<Character> set = new LinkedHashSet<>();
for (char c : str.toCharArray()) {
set.add(c);
}
StringBuilder result = new StringBuilder();
for (char c : set) {
result.append(c);
}
return result.toString();
}
public static void main(String[] args) {
String str = "programming";
System.out.println(removeDuplicates(str)); // Output: progamin
}
}
Explanation
LinkedHashSet
: Maintains the order of first occurrences.StringBuilder
: Efficiently constructs the final string without duplicates.
5. Find the First Non-Repeated Character (String)
Problem
Find the first character in a string that does not repeat.
Solution Approach
Use a
LinkedHashMap
to store character counts while maintaining order.Iterate through the string to find the first character with a count of 1.
Java Code
import java.util.LinkedHashMap;
import java.util.Map;
public class FirstNonRepeatedChar {
public static Character firstNonRepeatedChar(String str) {
LinkedHashMap<Character, Integer> charCount = new LinkedHashMap<>();
for (char c : str.toCharArray()) {
charCount.put(c, charCount.getOrDefault(c, 0) + 1);
}
for (Map.Entry<Character, Integer> entry : charCount.entrySet()) {
if (entry.getValue() == 1) {
return entry.getKey();
}
}
return null; // No non-repeated character found
}
public static void main(String[] args) {
String str = "swiss";
System.out.println(firstNonRepeatedChar(str)); // Output: w
}
}
Explanation
LinkedHashMap
: Stores characters and their counts while maintaining order.getOrDefault(c, 0) + 1
: Increments the count for each character.
6. Count Vowels and Consonants (String)
Problem
Count the number of vowels and consonants in a given string.
Solution Approach
Convert the string to lowercase.
Iterate through each character and check if it's a vowel or a consonant.
Count vowels and consonants separately.
Java Code
public class VowelConsonantCounter {
public static void countVowelsAndConsonants(String str) {
str = str.toLowerCase();
int vowels = 0, consonants = 0;
for (char c : str.toCharArray()) {
if (c >= 'a' && c <= 'z') {
if ("aeiou".indexOf(c) != -1) {
vowels++;
} else {
consonants++;
}
}
}
System.out.println("Vowels: " + vowels);
System.out.println("Consonants: " + consonants);
}
public static void main(String[] args) {
String str = "Java Programming";
countVowelsAndConsonants(str);
// Output: Vowels: 5, Consonants: 9
}
}
Explanation
Convert to lowercase to simplify comparison.
Check if each character is between
'a'
and'z'
."aeiou".indexOf(c) != -1
: Checks if the character is a vowel.
7. Log Parser with Regular Expressions (String + Regex)
Problem
Extract information such as timestamps, log levels, and messages from log entries.
Solution Approach
Use a regular expression to match timestamps, log levels, and messages.
Extract and display each part.
Java Code
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LogParser {
public static void parseLog(String log) {
String regex = "(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}) (\\w+): (.*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(log);
if (matcher.matches()) {
System.out.println("Timestamp: " + matcher.group(1));
System.out.println("Log Level: " + matcher.group(2));
System.out.println("Message: " + matcher.group(3));
} else {
System.out.println("Invalid log format");
}
}
public static void main(String[] args) {
String log = "2024-05-01 12:30:45 ERROR: Something went wrong";
parseLog(log);
// Output:
// Timestamp: 2024-05-01 12:30:45
// Log Level: ERROR
// Message: Something went wrong
}
}
Explanation
Regex Breakdown:
(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})
: Matches the timestamp.(\\w+)
: Matches the log level (e.g.,ERROR
,INFO
).(.*)
: Matches the message.
matcher.group
(n)
: Extracts matched groups.
8. Longest Substring Without Repeating Characters (String)
Problem
Find the longest substring without repeating characters.
Solution Approach
Use a sliding window and a
HashSet
to track characters.Expand the window while characters are unique.
Update the maximum length when duplicates are encountered.
Java Code
import java.util.HashSet;
public class LongestUniqueSubstring {
public static int longestUniqueSubstring(String str) {
int maxLength = 0;
int left = 0;
HashSet<Character> set = new HashSet<>();
for (int right = 0; right < str.length(); right++) {
while (set.contains(str.charAt(right))) {
set.remove(str.charAt(left));
left++;
}
set.add(str.charAt(right));
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
public static void main(String[] args) {
String str = "abcabcbb";
System.out.println(longestUniqueSubstring(str)); // Output: 3 ("abc")
}
}
Explanation
Sliding Window:
left
andright
track the window boundaries.HashSet
: Tracks unique characters in the current window.Update
maxLength
each time a longer unique substring is found.
9. String Compression (String)
Problem
Compress a string by replacing consecutive repeated characters with the character followed by the count.
Solution Approach
Iterate through the string.
Count consecutive characters.
Append the character and count to a
StringBuilder
.
Java Code
public class StringCompression {
public static String compress(String str) {
StringBuilder result = new StringBuilder();
int count = 1;
for (int i = 0; i < str.length(); i++) {
if (i < str.length() - 1 && str.charAt(i) == str.charAt(i + 1)) {
count++;
} else {
result.append(str.charAt(i));
if (count > 1) {
result.append(count);
}
count = 1;
}
}
return result.toString();
}
public static void main(String[] args) {
String str = "aabbbcc";
System.out.println(compress(str)); // Output: a2b3c2
}
}
Explanation
Count consecutive characters: Increment
count
if the next character is the same.Append character and count to
StringBuilder
.Reset
count
after each unique character.
10. Check for Balanced Parentheses (String + Stack)
Problem
Check if a string contains balanced parentheses {}
, []
, ()
.
Solution Approach
Use a
Stack
to track opening brackets.For each closing bracket, check if it matches the top of the stack.
At the end, the stack should be empty if balanced.
Java Code
import java.util.Stack;
public class BalancedParentheses {
public static boolean isBalanced(String str) {
Stack<Character> stack = new Stack<>();
for (char c : str.toCharArray()) {
if (c == '(' || c == '{' || c == '[') {
stack.push(c);
} else if (c == ')' && !stack.isEmpty() && stack.peek() == '(') {
stack.pop();
} else if (c == '}' && !stack.isEmpty() && stack.peek() == '{') {
stack.pop();
} else if (c == ']' && !stack.isEmpty() && stack.peek() == '[') {
stack.pop();
} else if (c == ')' || c == '}' || c == ']') {
return false;
}
}
return stack.isEmpty();
}
public static void main(String[] args) {
String str = "([{}])";
System.out.println(isBalanced(str)); // Output: true
}
}
Explanation
Push opening brackets onto the stack.
Match closing brackets with the top of the stack.
If mismatched or stack is not empty, return
false
..
11. Find the Missing Number in an Array (Array)
Problem
Given an array of numbers from 1 to n
with one number missing, find the missing number.
Solution Approach
Calculate the sum of numbers from 1 to
n
using the formula ( \text{sum} = n \times (n + 1) / 2 ).Subtract the sum of array elements from the expected sum to get the missing number.
Java Code
public class MissingNumber {
public static int findMissingNumber(int[] arr, int n) {
int expectedSum = n * (n + 1) / 2;
int actualSum = 0;
for (int num : arr) {
actualSum += num;
}
return expectedSum - actualSum;
}
public static void main(String[] args) {
int[] arr = {1, 2, 4, 5};
int n = 5;
System.out.println(findMissingNumber(arr, n)); // Output: 3
}
}
Explanation
Expected Sum: Calculate the sum of numbers from 1 to
n
.Actual Sum: Sum the elements in the array.
Difference: The missing number is the difference between the expected and actual sums.
12. Find the Largest and Smallest Elements (Array)
Problem
Find the largest and smallest elements in an array.
Solution Approach
- Traverse the array and track the largest and smallest elements.
Java Code
public class LargestAndSmallest {
public static void findLargestAndSmallest(int[] arr) {
int largest = arr[0];
int smallest = arr[0];
for (int num : arr) {
if (num > largest) {
largest = num;
}
if (num < smallest) {
smallest = num;
}
}
System.out.println("Largest: " + largest);
System.out.println("Smallest: " + smallest);
}
public static void main(String[] args) {
int[] arr = {3, 1, 4, 1, 5, 9, 2};
findLargestAndSmallest(arr);
// Output: Largest: 9, Smallest: 1
}
}
Explanation
Initialize
largest
andsmallest
with the first element.Traverse the array and update
largest
andsmallest
accordingly.
13. Rotate an Array (Array)
Problem
Rotate an array to the right by a given number of steps.
Solution Approach
Use the modulo operator to handle rotations greater than the array length.
Reverse parts of the array to achieve rotation.
Java Code
import java.util.Arrays;
public class RotateArray {
public static void rotate(int[] arr, int steps) {
int n = arr.length;
steps %= n; // Handle steps greater than array length
reverse(arr, 0, n - 1);
reverse(arr, 0, steps - 1);
reverse(arr, steps, n - 1);
}
private static void reverse(int[] arr, int start, int end) {
while (start < end) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
rotate(arr, 2);
System.out.println(Arrays.toString(arr)); // Output: [4, 5, 1, 2, 3]
}
}
Explanation
Reverse the entire array.
Reverse the first
steps
elements.Reverse the remaining elements.
14. Merge Two Sorted Arrays (Array)
Problem
Merge two sorted arrays into one sorted array.
Solution Approach
Use two pointers to traverse both arrays.
Compare elements and add the smaller one to the result array.
Java Code
import java.util.Arrays;
public class MergeSortedArrays {
public static int[] merge(int[] arr1, int[] arr2) {
int[] result = new int[arr1.length + arr2.length];
int i = 0, j = 0, k = 0;
while (i < arr1.length && j < arr2.length) {
if (arr1[i] <= arr2[j]) {
result[k++] = arr1[i++];
} else {
result[k++] = arr2[j++];
}
}
while (i < arr1.length) {
result[k++] = arr1[i++];
}
while (j < arr2.length) {
result[k++] = arr2[j++];
}
return result;
}
public static void main(String[] args) {
int[] arr1 = {1, 3, 5};
int[] arr2 = {2, 4, 6};
int[] merged = merge(arr1, arr2);
System.out.println(Arrays.toString(merged)); // Output: [1, 2, 3, 4, 5, 6]
}
}
Explanation
Two Pointers:
i
forarr1
,j
forarr2
, andk
forresult
.Merge elements in sorted order.
Copy remaining elements from either array.
Subscribe to my newsletter
Read articles from Jyotiprakash Mishra directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Jyotiprakash Mishra
Jyotiprakash Mishra
I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class. At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out. In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.