Summary

This article mainly introduces Java String related APIs and usage, string operations.

String Core Knowledge Points

Strings in Java are immutable, once created cannot be modified. All operations on original strings such as deletion, replacement, concatenation, etc., will not modify the original string, but produce a new string.

And to reduce memory usage, when created directly with literals, it will look up in the string constant pool. If the same exists, directly return the reference. As shown in the following example.

// Strings created with literals will first look up in the string constant pool, if same exists, return reference  
String s1 = "Hello World";  
String s2 = "Hello World";  
System.out.println("s1 == s2 ? " + (s1 == s2));// true  
  
// Strings created with new String() will be created on heap memory  
String s3 = new String("Hello World");  
System.out.println("s1 == s3 ? " + (s1 == s3));// false

String Operations

String operations can be divided into the following categories:

  1. Creation:

    String s1 = "Hello World";// Create directly with literal
    String s2 = new String("Hello World");// new a String, placed on heap
    String oneStr = String.valueOf(1);// Create by converting from other data types
    
  2. Concatenation:

    // Concatenate with + sign
    String s1 = "Hello" + " World";
    
  3. Splitting:

    // Split by specified string
    String str = "apple,banana,cherry";  
    String[] parts = str.split(",");  
    for (String part : parts) {  
        System.out.println(part);  
    }
    
  4. Substring:

    substring function, pass in start and end positions, substring position follows left-closed right-open principle, i.e., includes start position, excludes end position

    String str = "Hello, world!";  
    String subStr = str.substring(7);  
    System.out.println(subStr);  // Output: world!
    String subStr = str.substring(7, 12);
    System.out.println(subStr); // Output: world
    
  5. Search:

    String str = "Hello";  
    System.out.println(str.contains("ll"));//true  
    System.out.println(str.startsWith("H"));//true  
    System.out.println(str.endsWith("o"));//true  
    // Locate character position  
    System.out.println(str.indexOf("l"));//2  
    System.out.println(str.lastIndexOf("l"));//3  
    // Get from position  
    System.out.println(str.charAt(0));//H  
    System.out.println(str.charAt(str.length() - 1));//o
    
  6. Replacement and Modification:

    String str = "Hello";  
    System.out.println(str.replace("H","h"));//hello  
    System.out.println(str.replace("llo",""));//He, used for deletion
    System.out.println(str.replaceAll("[a-z]", ""));//H, delete all lowercase letters
    
  7. Formatting:

    String formattedString = String.format("Integer: %d", 2);
    System.out.println(formattedString);  // Output: Integer: 42
    
  8. Case Conversion:

    String str = "Hello";  
    System.out.println(str.toLowerCase());//hello  
    System.out.println(str.toUpperCase());//HELLO
    
  9. Remove Specified Characters:

    System.out.println("  hello  ".trim());//hello
    

StringBuilder and StringBuffer Usage

Because String cannot be modified once created, for strings that need frequent modification, StringBuilder and StringBuffer should be used.

  • StringBuilder is not thread-safe, but efficient, suitable for single-thread situations
  • StringBuffer is thread-safe, suitable for multiple threads modifying the same string

For specific implementation principles, check the source code analysis section below.

StringsUtils Utility Library

StringsUtils is Apache’s string processing utility library, encapsulating common complex string processing. And null-safe (i.e., if the passed string is null, it won’t cause Null Point Exception).

  • IsEmpty - Check if string is empty string, i.e. ""
  • IsBlank - Check if string is blank string, e.g. "\n\t" such blank strings return true
  • Trim/Strip - Remove leading and trailing spaces
  • Equals/Compare - Compare two strings in a null-safe way
  • startsWith - Check if string starts with prefix in a null-safe way
  • endsWith - Check if string ends with suffix in a null-safe way
  • IndexOf/LastIndexOf/Contains - null-safe index checking
  • IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut - Retrieve index of any in a set of strings
  • ContainsOnly/ContainsNone/ContainsAny - Check if string only contains/doesn’t contain/contains any of these characters
  • Substring/Left/Right/Mid - null-safe substring extraction
  • SubstringBefore/SubstringAfter/SubstringBetween - Substring extraction relative to other strings
  • Split/Join - Split string into substring array, vice versa
  • Remove/Delete - Remove part of string
  • Replace/Overlay - Search in string and replace with another string
  • Chomp/Chop - Remove last part of string
  • AppendIfMissing - Append suffix at end of string if not exists
  • PrependIfMissing - Add prefix at beginning of string if not exists
  • LeftPad/RightPad/Center/Repeat - Pad string
  • UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize - Change string case
  • CountMatches - Count occurrences of one string in another string
  • IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable - Check characters in string
  • DefaultString - Prevent null input string
  • Rotate - Rotate (circular shift) string
  • Reverse/ReverseDelimited - Reverse string
  • Abbreviate - Abbreviate string using ellipsis or another given string
  • Difference - Compare strings and report their differences
  • LevenshteinDistance - Number of changes needed to transform one string to another

Source Code Analysis

String

String class is final, immutable

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    }

StringBuilder and StringBuffer

StringBuilder and StringBuffer classes, main method is append for adding strings, both inherit from AbstractStringBuilder. The main implementation of append is in the parent class. append in both StringBuilder and StringBuffer calls parent class methods, but StringBuffer for thread safety, each method uses synchronized locking.

StringBuilder thread unsafe

@Override
public StringBuilder append(CharSequence s) {
    super.append(s);
    return this;
}

StringBuffer is thread-safe, you can see all append methods use synchronized keyword

@Override
public synchronized StringBuffer append(CharSequence s) {
    toStringCache = null;
    super.append(s);
    return this;
}

References