Java Strings

Within the Java programming language, a string is essentially an object that serves as a representation of a sequence of character values. In Java, a string is essentially operated as an array of characters. For instance:

Example

char[] ch={'t','p','o','i','n','t'};  

String s=new String(ch);

is same as:

Example

String s="Hello World";

The Java String class offers numerous methods for manipulating strings, including compare, concat, equals, split, length, replace, compareTo, intern, substring, and more.

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

CharSequence Interface

The CharSequence interface is employed for representing character sequences in Java. The String, StringBuffer, and StringBuilder classes all make use of this interface. This implies that strings can be created in Java through the utilization of these three classes.

In Java, the String data type is immutable, indicating that its value cannot be altered once it is created. Modifying a String will result in the creation of a new instance. To work with mutable strings in Java, the StringBuffer and StringBuilder classes can be utilized.

The topic of immutable strings will be covered later. For now, let's delve into the concept of strings in Java and explore the process of creating a String object.

What is String in Java?

In most cases, a String refers to a series of characters. However, in Java, a string is an instance that embodies a series of characters. The java.lang.String class is utilized for string object creation.

How to create a string object?

String objects can be created in two ways:

  • Through a string literal
  • Using the new keyword
  • 1) String Literal

A Java String literal is formed by enclosing characters within double quotation marks. For instance:

Example

String s="welcome";

When you define a string literal, the Java Virtual Machine (JVM) first examines the "string constant pool". If the string is already present in the pool, it retrieves a reference to that existing instance. However, if the string is not found in the pool, a new instance of the string is generated and added to the pool. An illustration of this process is:

Example

String s1="Welcome";

String s2="Welcome";//It doesn't create a new instance

In the scenario outlined, a single object gets instantiated. Initially, the JVM searches the string constant pool for an object containing the "Welcome" value; failing to find a match, it proceeds to create a new object. Subsequently, upon encountering a string with the "Welcome" value already present in the pool, the JVM refrains from creating a fresh object and instead provides a reference to the existing instance.

Example

Example

//Java Program to create string using string literal  

public class Main {  

 public static void main(String[] args) {

    String s1="Welcome";  

    String s2="Welcome";//It doesn't create a new instance  

    System.out.println(s1+" "+s2);

 }  

}

Output:

Output

Welcome Welcome

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

Why Java uses the concept of String literal?

In order to enhance the memory efficiency of Java, it is beneficial to avoid creating new objects if they already exist in the string constant pool.

2) By new keyword

Example

String s=new String("Welcome");//creates two objects and one reference variable

When this transpires, a new string object will be generated by the JVM in the regular heap memory, while the string "Welcome" will be stored in the string constant pool. The variable s will point to the object in the heap (non-pool).

Example

Example

//Java Program to create string using new keyword

public class Main {  

 public static void main(String[] args) {

    String s1=new String("Welcome");

    String s2=new String("Welcome");

    System.out.println(s1+" "+s2);

 }  

}

Output:

Output

Welcome Welcome

Java String class

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.
  • 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.
  • 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.

  • String
  • StringBuffer
  • StringBuilder
  • String

The String class in Java serves as a container for sequences of characters. When a String object is created, its content becomes unchangeable, establishing its immutable characteristic. This unchangeability guarantees the safety of String objects in multi-threaded environments and contributes to their efficient performance, especially when dealing with static textual data. Java utilizes a method known as string interning to improve memory usage by optimizing the handling and retrieval of frequently used string constants.

Syntax:

Direct assignment using string literals:

Example

String str = "Hello, World!";

Using the String constructor:

Example

String str = new String("Hello, World!");

Filename: StringExample.java

Example

public class StringExample {

    public static void main(String[] args) {

        // Creating a String

        String greeting = "Hello";

        // Concatenating strings

        String sentence = greeting + ", World!";

        // Using a method from the String class

        int length = sentence.length();

        System.out.println(sentence); // Output: Hello, World!

        System.out.println("Length: " + length); // Output: Length: 13

    }

}

Output:

Output

Hello, World!

Length: 13

StringBuffer

StringBuffer is utilized to manage a changeable series of characters while maintaining thread safety, which is beneficial for applications where multiple threads are involved in altering a character sequence. It offers functionalities for manipulating strings such as inserting, deleting, and appending characters. By eliminating the need to create new objects for each modification, this approach improves efficiency especially in cases where frequent modifications to the string content are necessary.

Syntax

Example

StringBuffer sb = new StringBuffer();

Filename: StringBufferExample.java

Example

public class StringBufferExample {

    public static void main(String[] args) {

        // Creating a StringBuffer

        StringBuffer sb = new StringBuffer("Hello");

        // Appending to the StringBuffer

        sb.append(", World!");

        // Inserting into the StringBuffer

        sb.insert(5, " Java");

        // Deleting from the StringBuffer

        sb.delete(5, 10);

        System.out.println(sb); // Output: Hello, World!

    }

}

Output:

Output

Hello, World!

StringBuilder

The mutable character sequence in StringBuilder is akin to that in StringBuffer. However, the key difference is that StringBuilder is unsynchronized, making it unsuitable for operations requiring thread safety. This lack of synchronization actually boosts StringBuilder's performance in scenarios involving single-threaded or specific-thread environments. Consequently, StringBuilder is preferred for string manipulation in situations where concurrent thread access safety is not a concern.

Syntax

Example

StringBuilder sb = new StringBuilder();

Filename: StringBuilderExample.java

Example

public class StringBuilderExample {

    public static void main(String[] args) {

        // Creating a StringBuilder

        StringBuilder sb = new StringBuilder("Hello");

        // Appending to the StringBuilder

        sb.append(", World!");

        // Inserting into the StringBuilder

        sb.insert(5, " Java");

        // Deleting from the StringBuilder

        sb.delete(5, 10);

        System.out.println(sb); // Output: Hello, World!

    }

}

Output:

Output

Hello, World!

Immutable String in Java

In Java, strings are immutable, indicating that once a String object is established, its value cannot be altered. Any attempt to modify a String actually results in the generation of a new String object, leaving the original string unaltered. This immutability feature of strings in Java carries various consequences concerning performance, security, and functionality.

Filename: ImmutableStringExample.java

Example

public class ImmutableStringExample {

    public static void main(String[] args) {

        // Original string

        String originalString = "Java";

        System.out.println("Original string: " + originalString);

        // Attempt to modify the original string

        String modifiedString = originalString.concat(" Programming");

        // Showing that the original string remains unchanged

        System.out.println("After modification, original string: " + originalString);

        // The result of the modification attempt is stored in a new string

        System.out.println("Modified string: " + modifiedString);

        // Demonstrating further that the original string is immutable

        originalString.toUpperCase(); // This operation does not change the original string

        System.out.println("After calling toUpperCase on original string: " + originalString);

        // Correct way to use the result of a string operation

        String upperCaseString = originalString.toUpperCase(); // Stores the result in a new string

        System.out.println("Original string in uppercase: " + upperCaseString);

    }

}

Output:

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

The memory allocation for strings in Java presents an intriguing aspect because of Java's management of string immutability and the string pool system. Having a grasp of how strings are stored can be beneficial for enhancing memory efficiency in Java programs, particularly those that extensively involve string operations.

String Literal Storage: In Java, when you declare a string using string literals, the string pool is the initial point of reference. If the string already exists, the new variable will reference the existing string. However, if the string is not found in the pool, the new string will be added to the pool, and the variable will then point to this newly added string.

Syntax:

Example

String s1 = "Hello"; // String literal

String s2 = "Hello"; // Points to the same "Hello" in the Pool as s1

The new operator is used to create strings that are not automatically added to the String Pool. Instead, these strings are stored in the heap memory separate from the Pool. This implies that every time the new operator is used, a new object is generated, even if it holds identical string information.

Syntax:

Example

String s3 = new String("Hello"); // A new string object is created in the heap

During an internship, we have the option to add a string to the Pool manually or make sure it is using the Pool by invoking the intern method on a string object. When the Pool already has a matching string, the string from the Pool is retrieved. If there isn't a matching string, it will be added to the Pool.

Syntax:

Example

String s4 = new String("Hello").intern(); // Ensures use of the string pool

Filename: StringMemoryAllotment.java

Example

public class StringMemoryAllotment {

    public static void main(String[] args) {

        // String literals - stored in the string pool

        String str1 = "Java";

        String str2 = "Java";

        // Checking if str1 and str2 point to the same object

        System.out.println("str1 == str2: " + (str1 == str2)); // true, because both refer to the same string literal in the pool

        // Strings created with 'new' - stored in heap memory outside the string pool

        String str3 = new String("Java");

        String str4 = new String("Java");

        // Checking if str3 and str4 point to the same object

        System.out.println("str3 == str4: " + (str3 == str4)); // false, because 'new' creates a new object each time

        // Interning str3

        String str5 = str3.intern();

        // Checking if str1 and str5 point to the same object

        System.out.println("str1 == str5: " + (str1 == str5)); // true, str5 is interned, so it refers to the string in the pool

        // Demonstrating the effect of interning on memory allocation

        String str6 = new String("Java").intern();

        // Checking if str6 is the same as str1

        System.out.println("str1 == str6: " + (str1 == str6)); // true, str6 is interned and points to the pooled instance

    }

}

Output:

Output

str1 == str2: true

str3 == str4: false

str1 == str5: true

str1 == str6: true

Construct String from a subset of the char array

In Java, it is possible to construct a String from a segment of a char array using a dedicated constructor within the String class. This constructor necessitates three arguments: the char array to utilize, a starting index denoting the beginning of the specified subset, and the number of characters to include in the subset. Below is the syntax along with an illustration:

Syntax:

Example

String(char[] value)

String(char[] value, int offset, int count)
  • value: The char array.
  • offset: The initial offset into the array.
  • count: The number of characters to use from the array.

Filename: CharArrayToString.java

Example

public class CharArrayToString {

    public static void main(String[] args) {

        // Define a char array

        char[] charArray = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'};

        // Construct a string from a subset of the char array

        // Here, we start at index 6 (the space character) and use the next 5 characters

        String resultString = new String(charArray, 6, 5);

        // Output the result

        System.out.println(resultString); 

    }

}

Output:

Let's explore another instance of a Java String that is generated utilizing a char array.

StringExample.java

Example

public class StringExample{  

public static void main(String args[]){  

String s1="java";//creating string by Java string literal  

char ch[]={'s','t','r','i','n','g','s'};  

String s2=new String(ch);//converting char array to string  

String s3=new String("example");//creating Java string by new keyword  

System.out.println(s1);  

System.out.println(s2);  

System.out.println(s3);  

}}

Output:

Output

java

strings

example

The code snippet above is responsible for transforming a character array into a String object. It then showcases these String objects, denoted as s1, s2, and s3, on the console by utilizing the println method.

Java String MCQ

  1. Which method can be used to compare two strings lexicographically in Java?
  • compareTo
  • equals
  • compare
  • equalsIgnoreCase

The compareTo function is used to compare two strings based on their lexicographical order. It returns a negative number if the first string comes before the second one, zero if the strings are the same, and a positive number if the first string comes after the second string.

  1. What will the code snippet below output?
  2. Example
    
    String s = "Java";
    
    s.concat("Point");
    
    System.out.println(s);
    
  • Java
  • C# Tutorial
  • C# Tutorial
  • Point

Explanation: Strings in Java are immutable. The concat method creates a new string but does not change the original string. Therefore, the original string s remains "Java".

  1. How can you create a new string object from a character array in Java?
  • new String(chars)
  • String.valueOf(chars)
  • String.copyValueOf(chars)
  • All of the above

Explanation: All of the listed methods can create a new string from a character array. new String(chars), String.valueOf(chars), and String.copyValueOf(chars) are different ways to achieve this.

  1. Which method is used to convert all characters in a string to lowercase in Java?
  • toLowerCase
  • toLower
  • toLowerCase(Locale locale)
  • a and c

The function toLowerCase changes all characters in the string to lowercase based on the default locale, while the toLowerCase(Locale locale) function converts all characters to lowercase based on the specified locale.

  1. What will be the output of the code snippet below?
  2. Example
    
    String str = "  Hello World  ";
    
    System.out.println(str.trim());
    
  • " Hello World "
  • "Hello World"
  • "Hello World "
  • " Hello World"

Explanation: The trim method removes leading and trailing whitespace from the string, so the output is "Hello World."

  • 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?
  • 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

Input Required

This code uses input(). Please provide values below: