Java String

In Java, string is basically an object that represents sequence of char values. An array of characters works same as Java string. For example:

is same as:

Java String class provides a lot of methods to perform operations on strings such as compare(), concat(), equals(), split(), length(), replace(), compareTo(), intern(), substring() etc.

The java.lang.String class implements Serializable, Comparable and CharSequence interfaces.

String in Java

CharSequence Interface

The CharSequence interface is used to represent the sequence of characters. String, StringBuffer and StringBuilder classes implement it. It means, we can create strings in Java by using these three classes.

CharSequence in Java

The Java String is immutable which means it cannot be changed. Whenever we change any string, a new instance is created. For mutable strings, you can use StringBuffer and StringBuilder classes.

We will discuss immutable string later. Let's first understand what String in Java is and how to create the String object.

What is String in Java?

Generally, String is a sequence of characters. But in Java, string is an object that represents a sequence of characters. The java.lang.String class is used to create a string object.

How to create a string object?

There are two ways to create String object:

  1. By string literal
  2. By new keyword

1) String Literal

Java String literal is created by using double quotes. For Example:

Each time you create a string literal, the JVM checks the "string constant pool" first. If the string already exists in the pool, a reference to the pooled instance is returned. If the string doesn't exist in the pool, a new string instance is created and placed in the pool. For example:


Java String

In the above example, only one object will be created. Firstly, JVM will not find any string object with the value "Welcome" in string constant pool that is why it will create a new object. After that it will find the string with the value "Welcome" in the pool, it will not create a new object but will return the reference to the same instance.

Note: String objects are stored in a special memory area known as the "string constant pool".

Why Java uses the concept of String literal?

To make Java more memory efficient (because no new objects are created if it exists already in the string constant pool).

2) By new keyword

In such case, JVM will create a new string object in normal (non-pool) heap memory, and the literal "Welcome" will be placed in the string constant pool. The variable s will refer to the object in a heap (non-pool).

Interfaces and Classes in Strings in Java

In Java, both String and CharBuffer interact with sequences of characters, but they are designed with different use cases and underlying mechanisms in mind. Here's an exploration of their interfaces, classes, and how they fit into the Java ecosystem.

String

The String class is one of the most fundamental types in Java, designed to represent immutable sequences of characters. Here's a closer look at its characteristics and the interfaces it implements:

  • Immutability: Once instantiated, a String object cannot be modified. This immutable design is a deliberate choice to ensure thread safety, consistency, and efficiency, especially regarding the String pool mechanism.
  • String Pool: Java maintains a pool of string literals to help save memory. When a new string literal is created, Java checks the Pool for a matching string. If found, the new variable references the pooled string. If not, the new string is added to the Pool.
  • Implemented Interfaces: The String class implements several interfaces, including:
    • Serializable: Allows string objects to be serialized into byte streams, facilitating their transmission or storage.
    • Comparable<String>: Enables lexical comparison between two strings, supporting natural ordering within collections.
    • CharSequence: Provides a unified read-only interface for different kinds of char sequences, allowing String objects to be manipulated and accessed generically.

CharBuffer

CharBuffer, on the other hand, is part of the java.nio package, which provides a set of classes for non-blocking I/O operations. CharBuffer is a mutable sequence of characters with more flexibility for manipulation. Here's more about CharBuffer:

  • Mutability and Direct Buffers: Unlike strings, CharBuffer instances can be modified. They can be either heap-based or direct buffers. Direct buffers can offer higher performance, especially for I/O operations, as they are managed outside the Java heap and interact directly with the operating system's native I/O operations.
  • Implemented Interfaces: CharBuffer extends the Buffer class and implements the CharSequence, Appendable, Comparable<CharBuffer>, and Readable interfaces, providing a rich set of functionalities for character sequence manipulation, comparison, and reading operations.
  • Usage Scenarios: It is particularly useful for reading and writing to channels, regular expressions, and character processing in a more efficient manner, especially when dealing with large datasets or requiring fine-grained control over character data.

CharSequence Interface

Java's CharSequence interface provides a unified, read-only view of character sequences and is a component of the java.lang package. It facilitates consistent access and manipulation across various types of character sequences, including String, StringBuilder, StringBuffer, and CharBuffer. Through this interface, key functionalities for handling character data are defined, enabling actions like measuring sequence length, accessing particular characters, generating character subsequences, and transforming into a String format. By providing a common blueprint for character sequences, `CharSequence` enables flexible and implementation-independent text processing across the Java platform.

  1. String
  2. StringBuffer
  3. StringBuilder

String

In Java, the String class encapsulates a series of characters. Once instantiated, a String object's content is fixed and cannot be modified, attributing to its immutable nature. This immutability ensures that String objects are safe for concurrent use across threads and are optimally performant in situations where the textual content remains constant. To enhance memory efficiency, Java employs a technique called string interning. This approach optimizes the storage and access of commonly utilized string literals.

Syntax:

Direct assignment using string literals:

Using the String constructor:

Filename: StringExample.java

Output:

Hello, World!
Length: 13

StringBuffer

StringBuffer represents a mutable sequence of characters that ensures thread safety, making it suitable for scenarios involving multiple threads that modify a character sequence. It includes various string manipulation capabilities, including the ability to insert, delete, and append characters. This design avoids the necessity of generating new objects with each change, leading to enhanced efficiency in situations requiring regular adjustments to the string content.

Syntax

Filename: StringBufferExample.java

Output:

Hello, World!

StringBuilder

StringBuilder shares similarities with StringBuffer by being a mutable character sequence. The crucial distinction lies in StringBuilder not being synchronized, rendering it not suitable for thread-safe operations. This absence of synchronization, though, contributes to StringBuilder offering superior performance in environments that are single-threaded or confined to a specific thread. As a result, StringBuilder becomes the favored option for manipulating strings in contexts where the safety of concurrent thread access is not an issue.

Syntax

Filename: StringBuilderExample.java

Output:

Hello, World!

StringTokenizer

Java's StringTokenizer class, housed within the java.util package, simplifies the process of segmenting a string into multiple tokens, utilizing designated separators. This class is exceptionally beneficial for parsing strings and navigating through their tokens, especially in scenarios involving user inputs, file contents, or network transmissions formatted with straightforward separators such as commas, spaces, or tabs. It offers an efficient means to dissect and examine the tokenized segments of a string, catering to situations that demand basic parsing capabilities.

The StringTokenizer class implements the Enumeration<Object> interface, allowing the tokens of the string to be iterated like other enumeration types in Java. It offers a straightforward approach to tokenization, avoiding the need for more complex regular expressions, making it suitable for simple parsing needs.

Syntax:

Filename: StringTokenizer.java

Output:

Apple, Banana, Cherry

Immutable String in Java

In Java, strings are immutable. It means that its value cannot be changed once a String object is created. If any operation appears to modify a String, what happens is the creation of a new String object. The original string remains unchanged. This immutable characteristic of strings in Java has several implications for performance, security, and functionality.

Filename: ImmutableStringExample.java

Output:

Original string: Java
After modification, original string: Java
Modified string: Java Programming
After calling toUpperCase on original string: Java
Original string in uppercase: JAVA

Memory Allotment of String

Memory allotment for strings in Java is interesting due to Java's handling of string immutability and the string pool mechanism. Understanding how strings are stored can help optimize memory usage in Java applications, especially those that heavily use string manipulations.

String Literal Storage: When you create a string using string literals, Java checks the string pool first. The new variable points to the existing string if it already exists. If it doesn't exist, the new string is added to the Pool, and the variable points to this new string.

Syntax:

new Keyword and String Pool: Strings created with the new operator do not use the Pool by default. They are stored in the heap memory outside the Pool, which means each new operation results in a new object, even if it contains the same string data.

Syntax:

Interning: We can manually add a string to the Pool or ensure it uses the Pool by calling the intern() method on a string object. If the Pool already contains an equal string, the string from the Pool is returned. Otherwise, the string is added to the Pool.

Syntax:

Filename: StringMemoryAllotment.java

Output:

str1 == str2: true
str3 == str4: false
str1 == str5: true
str1 == str6: true

Why did the String pool move from PermGen to the normal heap area?

Java 8 introduced a notable shift in memory management within the Java Virtual Machine (JVM) by moving the String Pool from the Permanent Generation (PermGen) to the general heap space. This adjustment was a key element of a wider effort to improve memory utilization, ease the management and configuration of memory, and boost the efficiency and scalability of Java-based applications. To fully comprehend the significance of this change, it's important to understand both the constraints associated with PermGen and the advantages that stem from transferring the String Pool and additional metadata to the heap area.

Syntax:

Filename: StringInternExample.java

Output:

Interned String and Literal String refer to the same object: true

Construct String from a subset of the char array

In Java, creating a String based on a portion of a char array is achievable through a specific constructor in the String class. This constructor requires three parameters: the char array to be used, an index indicating the starting point of the desired subset, and the count of characters to encompass in the subset. Here's the syntax and an example:

Syntax:

  • value: The char array.
  • offset: The initial offset into the array.
  • count: The number of characters to use from the array.

Filename: CharArrayToString.java

Output:

World

Java String Example

StringExample.java

Test it Now

Output:

java
strings
example

The above code, converts a char array into a String object. And displays the String objects s1, s2, and s3 on console using println() method.

Java String class methods

The java.lang.String class provides many useful methods to perform operations on sequence of char values.

No.MethodDescription
1char charAt(int index)It returns char value for the particular index
2int length()It returns string length
3static String format(String format, Object... args)It returns a formatted string.
4static String format(Locale l, String format, Object... args)It returns formatted string with given locale.
5String substring(int beginIndex)It returns substring for given begin index.
6String substring(int beginIndex, int endIndex)It returns substring for given begin index and end index.
7boolean contains(CharSequence s)It returns true or false after matching the sequence of char value.
8static String join(CharSequence delimiter, CharSequence... elements)It returns a joined string.
9static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)It returns a joined string.
10boolean equals(Object another)It checks the equality of string with the given object.
11boolean isEmpty()It checks if string is empty.
12String concat(String str)It concatenates the specified string.
13String replace(char old, char new)It replaces all occurrences of the specified char value.
14String replace(CharSequence old, CharSequence new)It replaces all occurrences of the specified CharSequence.
15static String equalsIgnoreCase(String another)It compares another string. It doesn't check case.
16String[] split(String regex)It returns a split string matching regex.
17String[] split(String regex, int limit)It returns a split string matching regex and limit.
18String intern()It returns an interned string.
19int indexOf(int ch)It returns the specified char value index.
20int indexOf(int ch, int fromIndex)It returns the specified char value index starting with given index.
21int indexOf(String substring)It returns the specified substring index.
22int indexOf(String substring, int fromIndex)It returns the specified substring index starting with given index.
23String toLowerCase()It returns a string in lowercase.
24String toLowerCase(Locale l)It returns a string in lowercase using specified locale.
25String toUpperCase()It returns a string in uppercase.
26String toUpperCase(Locale l)It returns a string in uppercase using specified locale.
27String trim()It removes beginning and ending spaces of this string.
28static String valueOf(int value)It converts given type into string. It is an overloaded method.

Do You Know?
  • Why are String objects immutable?
  • How to create an immutable class?
  • What is string constant pool?
  • What code is written by the compiler if you concatenate any string by + (string concatenation operator)?
  • What is the difference between StringBuffer and StringBuilder class?

What will we learn in String Handling?
  • Concept of String
  • Immutable String
  • String Comparison
  • String Concatenation
  • Concept of Substring
  • String class methods and its usage
  • StringBuffer class
  • StringBuilder class
  • Creating Immutable class
  • toString() method
  • StringTokenizer class