Java Strings
Java - The String Class
Section titled “Java - The String Class”Strings are fundamental in Java, representing sequences of characters. Unlike primitive types, strings in Java are objects provided by the java.lang.String class.
This tutorial explores how to create and manipulate strings using modern Java practices.
Creating Strings
Section titled “Creating Strings”The most common and recommended way to create a string is using a string literal:
// Assigns a reference to an existing or new String object in the string pool.String greeting = "Hello, world!";When the compiler encounters a string literal, it creates a String object. For efficiency, Java maintains a special memory area called the “String Pool”. If a literal already exists in the pool, the existing object’s reference is reused.
You can also create strings from character arrays:
public class StringCreationDemo {
public static void main(String[] args) { char[] helloArray = { 'H', 'e', 'l', 'l', 'o', '.' }; String helloString = new String(helloArray); System.out.println(helloString); // Output: Hello. }}Note: While you can use new String("literal"), it’s generally discouraged as it bypasses the string pool and creates a new object unnecessarily in most cases.
For multi-line strings (Java 15+), Text Blocks are cleaner:
String html = """ <html> <body> <p>Hello, world</p> </body> </html> """;System.out.println(html);Understanding String Immutability
Section titled “Understanding String Immutability”A crucial concept in Java is that String objects are immutable. This means once a String object is created, its internal state (the sequence of characters) cannot be changed. Any method that seems to modify a string (like toUpperCase() or substring()) actually creates and returns a new String object with the modified content, leaving the original unchanged.
Why immutability? It offers several advantages:
- Thread Safety: Immutable objects can be shared safely between multiple threads without synchronization.
- Security: String parameters (like file paths or URLs) cannot be unexpectedly changed after validation.
- Performance: Immutability allows for optimizations like the String Pool (caching identical string literals).
When you need to perform many modifications to a sequence of characters (e.g., building a string inside a loop), creating numerous intermediate String objects can be inefficient. For these scenarios, Java provides mutable classes:
StringBuilder: The preferred choice for mutable string operations in a single-threaded environment. It’s generally faster.StringBuffer: A thread-safe alternative toStringBuilder. Use it only if you specifically need thread safety, as it incurs a performance overhead.
Example using StringBuilder:
StringBuilder builder = new StringBuilder();builder.append("Hello, ");builder.append("world!");builder.append(" The year is ");builder.append(2024);
String result = builder.toString(); // Convert back to an immutable StringSystem.out.println(result); // Output: Hello, world! The year is 2024Common String Operations
Section titled “Common String Operations”Getting String Length:
Section titled “Getting String Length:”The length() method returns the number of characters in the string.
public class StringLengthDemo {
public static void main(String[] args) { String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); System.out.println("String Length is: " + len); // Output: String Length is: 17 }}Concatenating Strings:
Section titled “Concatenating Strings:”The most common way to concatenate strings is using the + operator.
String firstName = "Ada";String lastName = "Lovelace";String fullName = firstName + " " + lastName; // "Ada Lovelace"System.out.println(fullName);For simple cases, the + operator is convenient. However, concatenating strings inside a loop using + can be inefficient as it may create many intermediate String objects. Use StringBuilder for better performance in loops:
String[] words = {"Java", "is", "fun"};StringBuilder sentence = new StringBuilder();for (String word : words) { sentence.append(word).append(" ");}String finalSentence = sentence.toString().trim(); // "Java is fun"System.out.println(finalSentence);The String class also has a concat(String str) method, but the + operator and StringBuilder are generally preferred.
Creating Formatted Strings:
Section titled “Creating Formatted Strings:”The static String.format() method allows creating formatted strings, similar to printf in C/C++.
double floatVar = 3.14159;int intVar = 42;String stringVar = "Example";
String fs = String.format("Float: %.2f, Integer: %d, String: %s", floatVar, intVar, stringVar);System.out.println(fs);// Output: Float: 3.14, Integer: 42, String: ExampleSince Java 15, you can also use the formatted() instance method, often useful with text blocks:
String name = "World";int year = 2024;String formattedString = """ Hello, %s! Welcome to %d. """.formatted(name, year);System.out.println(formattedString);Core String Methods
Section titled “Core String Methods”The String class provides a rich set of methods. Here are some of the most commonly used ones, grouped by functionality:
Basic Information & Comparison:
Section titled “Basic Information & Comparison:”int length(): Returns the number of characters. Ex:"Java".length() // 4boolean isEmpty(): Returnstrueif length is 0. Ex:"".isEmpty() // trueboolean isBlank()(Java 11+): Returnstrueif the string is empty or contains only white space. Ex:" ".isBlank() // trueboolean equals(Object obj): Compares string content for equality (case-sensitive). Crucial: Use this, not==, for comparing string content.boolean equalsIgnoreCase(String anotherString): Compares string content, ignoring case.int compareTo(String anotherString): Compares strings lexicographically (0 if equal, <0 if this string is first, >0 ifanotherStringis first). Useful for sorting.int compareToIgnoreCase(String str): Lexicographical comparison, ignoring case.
Searching & Checking Content:
Section titled “Searching & Checking Content:”boolean contains(CharSequence s): Checks if the string contains the specified sequence. Ex:"Hello".contains("ell") // trueint indexOf(int ch / String str): Returns the index of the first occurrence, or -1 if not found. Can search from a specific index:indexOf(..., int fromIndex).int lastIndexOf(int ch / String str): Returns the index of the last occurrence, or -1. Can search backward from an index:lastIndexOf(..., int fromIndex).boolean startsWith(String prefix): Checks if the string starts with the specified prefix. Ex:"Java".startsWith("Ja") // trueboolean endsWith(String suffix): Checks if the string ends with the specified suffix. Ex:"Java".endsWith("va") // true
Extracting Substrings & Characters:
Section titled “Extracting Substrings & Characters:”String substring(int beginIndex): Returns a substring frombeginIndexto the end.String substring(int beginIndex, int endIndex): Returns a substring frombeginIndexup to (but not including)endIndex. Ex:"Example".substring(1, 4) // "xam"char charAt(int index): Returns the character at the specified index (0-based). Ex:"Java".charAt(0) // 'J'char[] toCharArray(): Converts the string to a new character array.
Manipulation (Case, Whitespace, Replacing):
Section titled “Manipulation (Case, Whitespace, Replacing):”String toLowerCase(): Converts the string to lower case.String toUpperCase(): Converts the string to upper case.String trim(): Removes leading and trailing whitespace (legacy definition of whitespace).String strip()(Java 11+): Removes leading and trailing whitespace (Unicode-aware). Preferred overtrim().String stripLeading()/stripTrailing()(Java 11+): Removes whitespace from only the beginning or end.String replace(char oldChar, char newChar): Replaces all occurrences ofoldCharwithnewChar.String replace(CharSequence target, CharSequence replacement): Replaces all occurrences of a target sequence.String replaceAll(String regex, String replacement): Replaces substrings matching a regular expression.String replaceFirst(String regex, String replacement): Replaces the first substring matching a regular expression.String repeat(int count)(Java 11+): Returns a string concatenated with itselfcounttimes.
Splitting & Joining:
Section titled “Splitting & Joining:”String[] split(String regex): Splits the string around matches of the given regular expression. Ex:"a,b,c".split(",") // {"a", "b", "c"}static String join(CharSequence delimiter, CharSequence... elements)(Java 8+): Joins elements with a delimiter. Ex:String.join("-", "a", "b", "c") // "a-b-c"static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)(Java 8+): Joins elements from a collection.
Working with Bytes (Encoding):
Section titled “Working with Bytes (Encoding):”byte[] getBytes(Charset charset): Encodes the string into a sequence of bytes using the specified character set. Best Practice: Always specify aCharset, e.g.,StandardCharsets.UTF_8.byte[] getBytes(): Encodes using the platform’s default charset. Warning: Avoid this method as the default charset varies between systems, leading to potential bugs. Use the version with an explicitCharsetinstead.
This list covers many essential methods. For a complete overview and advanced methods, consult the official Java API documentation for the java.lang.String class.