Mastering Java Strings: When to Use equals vs == and Common Pitfalls
Java's String class is immutable and stored in a constant pool; the article explains the difference between == and equals, demonstrates common methods for inspection, transformation, splitting, and conversion, and shows best practices for concatenation with StringBuilder, thread‑safe StringBuffer, and newer utilities like join, repeat, format, and text blocks.
What is String
String is the most frequently used class in Java for storing text. It is immutable: every modification creates a new object while the original remains unchanged.
String literal pool
Java stores string literals in a constant pool so that identical literals share the same object.
String a = "hello";
String b = "hello";
System.out.println(a == b); // true, same pool object
String c = new String("hello");
System.out.println(a == c); // false, new creates a heap object
System.out.println(a.equals(c)); // true, same contentTherefore, == compares references, equals() compares content. Placing a constant first in equals() avoids NullPointerException.
Common String methods
Information retrieval
String s = "Hello, World!";
s.length(); // 13
s.charAt(0); // 'H'
s.indexOf("World"); // 7
s.contains("World"); // true
s.startsWith("Hello"); // true
s.endsWith("!"); // true
s.isEmpty(); // false
s.isBlank(); // false (Java 11+)Transformations
String s = " Hello World ";
s.trim(); // "Hello World"
s.strip(); // "Hello World" (Java 11+)
s.toUpperCase(); // " HELLO WORLD "
s.toLowerCase(); // " hello world "
s.replace("World","Java"); // " Hello Java "Substring and split
String s = "2024-05-25";
s.substring(5); // "05-25"
s.substring(0,4); // "2024"
s.split("-"); // ["2024","05","25"]Two pitfalls of split() : The argument is a regular expression, so special characters like . must be escaped. Trailing empty strings are discarded unless a negative limit is supplied. <code>"a.b.c".split("."); // returns empty array! "a.b.c".split("\\."); // ["a","b","c"] "a,b,,".split(","); // ["a","b"] "a,b,,".split(",", -1); // ["a","b","",""] </code>
String comparison
Never use == to compare content; use equals() (or equalsIgnoreCase() for case‑insensitive comparison).
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false, compares addresses
System.out.println(a.equals(b)); // true, compares content
System.out.println(a.equalsIgnoreCase("HELLO")); // trueConstant‑first pattern prevents NullPointerException:
String status = null;
"active".equals(status); // safe, returns falseStringBuilder for efficient concatenation
In loops, avoid the + operator; use StringBuilder to modify a single mutable buffer.
// Bad: creates many temporary String objects
String result = "";
for (int i = 0; i < 1000; i++) {
result += i;
}
// Good: modifies the same buffer
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String result = sb.toString();Common StringBuilder methods:
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(", ").append("World");
sb.insert(5, "!");
sb.delete(0, 5);
sb.reverse();
sb.toString();StringBuilder vs StringBuffer
StringBuilder: not thread‑safe, fast, suitable for single‑threaded code. StringBuffer: methods are synchronized, slower, required only when multiple threads share the same mutable buffer.
Newer Java utilities (Java 8+)
// Join multiple strings with a delimiter (Java 8+)
String.join("-", "2024", "05", "25"); // "2024-05-25"
String.join(",", list); // joins List<String>
// Repeat a character N times (Java 11+)
"=".repeat(20); // 20 equal signs
// Format with placeholders
String.format("Name:%s Age:%d", "Zhang", 25); // "Name:Zhang Age:25"
// Switch on String (Java 7+)
switch (status) {
case "NEW" -> System.out.println("New order");
case "PAID" -> System.out.println("Paid");
default -> System.out.println("Unknown");
}Text blocks (Java 15+)
Triple‑quoted strings allow multi‑line literals without manual newline characters or concatenation. Common leading indentation is stripped automatically.
String json = """
{
"name": "Zhang",
"age": 25
}
""";
String sql = """
SELECT id, name, status
FROM orders
WHERE user_id = ?
AND status = 'PAID'
""";String and primitive conversion
// Number to String
String s1 = String.valueOf(100); // "100"
String s2 = 100 + ""; // "100"
// String to number
int n = Integer.parseInt("100"); // 100
double d = Double.parseDouble("3.14"); // 3.14
// Invalid format throws NumberFormatException
// int err = Integer.parseInt("abc"); // throwsPractical examples
// Build dynamic SQL (e.g., MyBatis)
StringBuilder sql = new StringBuilder("SELECT * FROM orders WHERE 1=1");
if (status != null) {
sql.append(" AND status = '").append(status).append("'");
}
if (userId != null) {
sql.append(" AND user_id = ").append(userId);
}
// Mask phone number
String phone = "13812345678";
String masked = phone.substring(0,3) + "****" + phone.substring(7); // 138****5678
// Split CSV line
String csv = "Zhang,25,Male,Beijing";
String[] fields = csv.split(",");
String name = fields[0]; // "Zhang"Summary
String is immutable; literals use the constant pool, new String() always creates a new heap object.
Use equals() for content comparison; == checks reference identity. Placing a constant first avoids NullPointerException.
Prefer StringBuilder for concatenation in single‑threaded code; use StringBuffer only when thread‑safe mutation is required. split() takes a regular expression; escape special characters and use a negative limit to retain trailing empty strings.
Java 8+ utilities such as String.join, repeat, format, and switch on strings simplify common tasks.
Text blocks (Java 15+) provide clean multi‑line literals with automatic indentation handling.
Convert between strings and numbers with Integer.parseInt, Double.parseDouble, handling NumberFormatException as needed.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
