String Class in Java
The String class in Java represents sequences of characters and is used for text data manipulation.
String Creation and Operations
Strings can be created using literals or the new keyword:
String greeting = "Hello";
String message = new String("Welcome");
Common string operations include:
- Length:
int len = greeting.length(); - Concatenation:
String combined = greeting.concat(" ").concat(message); - Comparison:
boolean match = greeting.equals("hello"); // false (case-sensitive) - Substring:
String part = message.substring(3); // "come" - Search:
int pos = message.indexOf("Wel"); // 0 - Replacement:
String updated = message.replace("Welcome", "Greetings"); - Splitting:
String[] words = "apple,banana,cherry".split(","); - Case Conversion:
String upper = message.toUpperCase();
Immutability of Strings
Strings are immutable because:
- Internal char array is declared final
- No methods modify the internal array
Benefits of immutability:
- Enhanced security and reliability
- Hash value caching for HashMap keys
- String Pool optimization
String, StringBuilder, and StringBuffer Comparison
| Feature | String | StringBuffer | StringBuilder |
|---|---|---|---|
| Mutbaility | Immutable | Mutable | Mutable |
| Thread Safety | Thread-safe | Thread-safe | Not thread-safe |
| Performance | Lower for modifications | Moderate | Higher for modifications |
| Use Case | Constants, configurations | Multi-threaded string operations | Single-threaded string operations |
replace() vs replaceAll()
replace() performs simple character/string replacement, while replaceAll() uses regular expressions for pattern-based replacement.
String Concatenation Best Practices
Use StringBuilder for single-threaded environments and StringBuffer for multi-threaded environments instead of + operator for better performance and memory efficiency.
equals() Method Comparison
String's equals() compares content, while Object's equals() compares reference addresses:
String s1 = "text";
String s2 = "text";
boolean contentMatch = s1.equals(s2); // true
boolean referenceMatch = (s1 == s2); // true (due to string pooling)
Object Creation with new String()
String a = new String("abc"); creates two objects: one in the string pool and one in the heap.
Member Variables
Member variables include instance variables (object-specific) and static variables (class-shared).
Instance Variables
Belong to individual objects, initialized when objects are created:
class Sample {
int instanceValue; // Instance variable
}
Static Variables
Shared across all class instances, allocated once during class loading:
class Sample {
static int sharedValue; // Static variable
}
Memory Allocation Differences
Instance variables get memory per object, static variables get memory once per class.
Thread Safety for Static Variables
Use synchronized or volatile keywords to ensure thread safety with static variables.
Creating Immutable Classes
- Declare class as final
- Declare variables as final
- Initialize values in constructor/static block
- Provide read-only access methods
Default Values and Access Modifiers
Primitivse default to 0/false, objects to null. Access controlled via public, private, protected, or package-private modifiers.
HashCode Implementation
hashCode() returns an integer hash value for object placement in hash-based collections.
hashCode() and equals() Relationship
Equal objects must have equal hashCodes. If equals() is overridden, hashCode() must also be overridden.
Hash Collisions
Different objects may have same hashCode due to limited range or similar attributes.
Collision Resolution Methods
- Open addressing (linear probing, quadratic probing, double hashing)
- Separate chaining (linked lists per bucket)
- Tree conversion for long chains (Java 8+ HashMap)
Hash Table Load Factor
Default load factor of 0.75 balances space utilization and performance. Triggers resizing when 75% full.
Exception Handling
Java exceptions are categorized as checked (compile-time enforced) and unchecked (runtime).
Exception Hierarchy
- Throwable (root class)
- Exception (program-handled)
- Checked exceptions (IOException, SQLException)
- Unchecked exceptions (RuntimeException and subclasses)
- Error (system-level, unrecoverable)
- Exception (program-handled)
Exception Handling Syntax
try {
// Risky code
} catch (SpecificException e) {
// Handle specific exception
} catch (Exception e) {
// Handle general exception
} finally {
// Cleanup code (always executes)
}
Exception Declaration and Throwing
Methods declare thrown exceptions with throws keyword. Exceptions are thrown with throw keyword:
void riskyMethod() throws CustomException {
if (errorCondition) {
throw new CustomException("Error message");
}
}
Exception Chaining
Link exceptions using initCause() or constructor chaining to preserve root cause information.
Custom Exception Creation
Extend Exception class and provide constructors:
class CustomException extends Exception {
CustomException(String msg) { super(msg); }
CustomException(String msg, Throwable cause) { super(msg, cause); }
}