What is JDK?
What are Strings in Java?
In Java, a string is a sequence of characters that is used to represent text. Strings are objects of the String class, which is part of the java.lang package. Strings are one of the most commonly used data types in Java programming because they allow us to work with text data.
Strings in Java are immutable, which means once a String object is created, its value cannot be changed. This immutability has important implications for performance and memory usage. When you perform operations that appear to modify a string, Java actually creates a new String object.
Creating Strings
There are two main ways to create strings in Java:
1. String Literals
String literals are created using double quotes and are stored in the string pool for memory efficiency:
public class StringLiterals {
public static void main(String[] args) {
// String literal - stored in string pool
String str1 = "Hello, World!";
String str2 = "Hello, World!";
// Both str1 and str2 refer to the same object in the string pool
System.out.println(str1 == str2); // true
}
}
2. Using the new Keyword
Strings can also be created using the new keyword, which creates objects in the heap memory:
public class StringObjects {
public static void main(String[] args) {
// String object - created in heap memory
String str1 = new String("Hello, World!");
String str2 = new String("Hello, World!");
// str1 and str2 refer to different objects
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // true
}
}
String Methods
The String class provides numerous methods for string manipulation. Here are some of the most commonly used ones:
Length and Character Access
public class StringMethods {
public static void main(String[] args) {
String str = "Hello, World!";
// Get string length
System.out.println("Length: " + str.length()); // 13
// Get character at specific index
System.out.println("Character at index 0: " + str.charAt(0)); // H
// Get substring
System.out.println("Substring (0-5): " + str.substring(0, 5)); // Hello
System.out.println("Substring (7): " + str.substring(7)); // World!
}
}
String Comparison
public class StringComparison {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
// Using == operator (compares references)
System.out.println("str1 == str2: " + (str1 == str2)); // true
System.out.println("str1 == str3: " + (str1 == str3)); // false
// Using equals() method (compares content)
System.out.println("str1.equals(str2): " + str1.equals(str2)); // true
System.out.println("str1.equals(str3): " + str1.equals(str3)); // true
// Case-insensitive comparison
System.out.println("equalsIgnoreCase: " + "Hello".equalsIgnoreCase("HELLO")); // true
// Compare lexicographically
System.out.println("compareTo: " + "Apple".compareTo("Banana")); // Negative value
}
}
Searching and Replacing
public class StringSearchReplace {
public static void main(String[] args) {
String str = "Hello, World! Welcome to Java programming.";
// Check if string contains substring
System.out.println("Contains 'Java': " + str.contains("Java")); // true
// Find index of substring
System.out.println("Index of 'World': " + str.indexOf("World")); // 7
System.out.println("Last index of 'o': " + str.lastIndexOf("o")); // 27
// Replace characters/substrings
System.out.println("Replace 'o' with '0': " + str.replace('o', '0')); // Hell0, W0rld!
System.out.println("Replace 'Java' with 'Python': " + str.replace("Java", "Python"));
}
}
Case Conversion and Trimming
public class StringCaseTrim {
public static void main(String[] args) {
String str = " Hello, World! ";
// Convert to uppercase/lowercase
System.out.println("Uppercase: " + str.toUpperCase());
System.out.println("Lowercase: " + str.toLowerCase());
// Trim whitespace
System.out.println("Trimmed: '" + str.trim() + "'");
// Check if string starts/ends with substring
System.out.println("Starts with ' He': " + str.startsWith(" He"));
System.out.println("Ends with 'd! ': " + str.endsWith("d! "));
}
}
String Concatenation
There are several ways to concatenate strings in Java:
1. Using the + Operator
public class StringConcatenation {
public static void main(String[] args) {
String firstName = "John";
String lastName = "Doe";
int age = 25;
// Using + operator
String message = "Hello, my name is " + firstName + " " + lastName + " and I am " + age + " years old.";
System.out.println(message);
}
}
2. Using concat() Method
public class StringConcat {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = " World";
String result = str1.concat(str2);
System.out.println(result); // Hello World
}
}
3. Using StringBuilder (Recommended for multiple concatenations)
public class StringBuilderConcat {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.append("!");
sb.append(" Welcome to Java.");
String result = sb.toString();
System.out.println(result);
}
}
StringBuilder vs StringBuffer
For mutable string operations, Java provides two classes: StringBuilder and StringBuffer. Both are used for creating mutable strings, but they differ in thread safety.
StringBuilder (Not Thread-Safe, Faster)
public class StringBuilderExample {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // Append string
sb.insert(5, ","); // Insert at position
sb.replace(6, 11, "Java"); // Replace substring
sb.delete(5, 6); // Delete character
sb.reverse(); // Reverse string
System.out.println(sb.toString());
System.out.println("Capacity: " + sb.capacity());
System.out.println("Length: " + sb.length());
}
}
StringBuffer (Thread-Safe, Slower)
public class StringBufferExample {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World");
sb.insert(5, ",");
sb.replace(6, 11, "Java");
System.out.println(sb.toString());
}
}
When to Use Which?
- StringBuilder: Use in single-threaded environments where performance is critical
- StringBuffer: Use in multi-threaded environments where thread safety is required
- String: Use for immutable strings and simple operations
String Pool and Memory Management
Java maintains a special memory area called the "String Pool" (or "String Constant Pool") to store string literals. This optimization helps save memory by reusing string objects.
public class StringPool {
public static void main(String[] args) {
// These literals are stored in the string pool
String s1 = "Hello";
String s2 = "Hello";
// s1 and s2 refer to the same object in the pool
System.out.println(s1 == s2); // true
// Using new keyword creates object in heap
String s3 = new String("Hello");
System.out.println(s1 == s3); // false
// intern() method adds string to pool if not present
String s4 = s3.intern();
System.out.println(s1 == s4); // true
}
}
String Formatting
Java provides several ways to format strings:
1. String.format()
public class StringFormatting {
public static void main(String[] args) {
String name = "Alice";
int age = 30;
double salary = 50000.50;
// Using String.format()
String formatted = String.format("Name: %s, Age: %d, Salary: $%.2f", name, age, salary);
System.out.println(formatted);
// Using printf() (same as format)
System.out.printf("Name: %s, Age: %d%n", name, age);
}
}
2. Text Blocks (Java 13+)
public class TextBlocks {
public static void main(String[] args) {
String html = """
Hello, World!
""";
System.out.println(html);
}
}
Common String Operations
Splitting Strings
public class StringSplit {
public static void main(String[] args) {
String csv = "John,Doe,30,Engineer";
String[] parts = csv.split(",");
for (String part : parts) {
System.out.println(part);
}
// Split with limit
String sentence = "The quick brown fox jumps over the lazy dog";
String[] words = sentence.split(" ", 3); // Split into 3 parts
for (String word : words) {
System.out.println(word);
}
}
}
Joining Strings
public class StringJoin {
public static void main(String[] args) {
String[] words = {"Hello", "World", "from", "Java"};
// Using String.join()
String result = String.join(" ", words);
System.out.println(result); // Hello World from Java
// Using StringJoiner
java.util.StringJoiner joiner = new java.util.StringJoiner(", ", "[", "]");
for (String word : words) {
joiner.add(word);
}
System.out.println(joiner.toString()); // [Hello, World, from, Java]
}
}
Best Practices for String Handling
- Use StringBuilder for concatenation in loops: Avoid using + operator in loops as it creates many temporary objects
- Use equals() for content comparison: Never use == to compare string contents
- Consider string interning: Use intern() judiciously for memory optimization
- Use StringBuilder over StringBuffer: Unless thread safety is required
- Prefer String.format() for complex formatting: It's more readable than concatenation
- Use trim() for user input: Always trim whitespace from user input strings
- Consider String.isEmpty() over length checks: More readable and efficient
Performance Considerations
- String immutability: Remember that strings are immutable - each modification creates a new object
- StringBuilder capacity: Set initial capacity when you know the approximate size
- Avoid unnecessary operations: Check string length before operations when possible
- Use appropriate methods: Some methods are more efficient than others for specific operations
Mastering string manipulation is essential for Java development. Strings are used everywhere in Java applications, from simple text processing to complex data parsing. The next tutorial will cover Java methods, which allow you to organize your code into reusable functions.