Curriculum
Course: Learn Java Programming
Login

Curriculum

Learn Java Programming

Text lesson

Introduction to Strings in Java

[post-views]

 

In this lesson, you will learn

  • Understanding String in Java
  • StringBuffer and StringBuilder Class

 

Strings in Java

In Java, string handling is primarily achieved through the String class, which provides immutable strings.

However, Java also offers classes for mutable strings: StringBuilder and StringBuffer.

Below is an explanation of these classes, including their mutability or immutability.

 

 

1. Immutable String: String Class

  1. In Java, a String is a sequence of characters that is treated as an object.
  2. Java strings are immutable, meaning their values cannot be changed once created.
  3. Instead, any modification to a string results in the creation of a new string object.

 

There are mainly two ways to create a String in Java.

 

1.1. String Literals

1. This is the most common method to create a string. When you create a string using string literal, Java first looks in the string pool to check if an identical string already exists.

2. If a match is found, it returns a reference to that same instance; if not, a new string instance is created and placed in the pool.

 

Example

String s1 = "Hello";
String s2 = "Hello";
/* s1 and s2 refer to the same instance 
in the string constant pool */

 

Note: In JVM, a special memory named string constant pool is used to store string literals.

The below figure shows how string literals are stored in the String Constant Pool and refer to the same string objects.

String s1 = "Hello";
String s2 = "Hello";

 

If you append the string literal, “World”, to the string reference variable, s1, then a new string object, “HelloWorld”, is created in the memory and the variable, s1, will refer to the new string object.

String s1="Hello";
s1=s1+"World";

 

However, the string object, “Hello”, still exists in the memory but has no reference, as shown in the following figure.

 

 

Note: Thus, every time you manipulate a string object, a new string object is created in the memory. Therefore the String object is called an immutable object.

 

Example 1: Understanding String

package ch11.l1;

public class StringExample1 {
	public static void main(String[] args) {

		String s1 = "Hello"; //use string literal
		String s2 = "Hello";
		System.out.println("s1 hashcode: "+s1.hashCode());
		System.out.println("s2 hashcode: "+s2.hashCode());
		//Modifying String s1
		s1+="World";
		/* New object is created for "HelloWorld" literal, 
		 * and now s1 is reffering to new object and s2
		 * still referring to "Hello"
		 */
		System.out.println("----------nAfter Modificationn----------");
		System.out.println("s1 hashcode: "+s1.hashCode());
		System.out.println("s2 hashcode: "+s2.hashCode());
	}
}

 

Output

s1 hashcode: 69609650
s2 hashcode: 69609650
----------
After Modification
----------
s1 hashcode: 439329280
s2 hashcode: 69609650

 

hashcode() function

hashcode() returns an integer hash code value for the object on which it is called, generated by a hashing algorithm.

 

1. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

2. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

 

1.2. Using the ‘new’ Keyword

Strings created with the new keyword are stored in the heap memory, and a new string object is created even if an identical string already exists in the string pool.

 

Example

String s3 = new String("Hello");
/* s3 is a different instance in the heap, 
not in the string pool */

 

Note: Heap memory is an area within the JVM where objects are stored.

The following figure shows the way to create a new string object using the ‘new’ keyword.

String s1 = "Hello";
String s2 = "Hello";
String s3 =  new String("Hello");

 

 

Comparing Both Methods

Using string literals is more memory-efficient due to the string pool mechanism. However, using the new keyword gives you a distinct string object separate from the string pool, which can be useful in certain scenarios.

 

Understanding equals( ) Versus ==

The equals( ) method compares the characters inside a String object. The == operator compares two object references to see whether they refer to the same instance.

 

Example: Comparing String Objects: equals( ) Versus ==

package ch11.l1;

public class StringExample2 {

	public static void main(String[] args) {
		String s1 = "Hello"; //use string literal
		String s2 = "Hello"; //use string literal
		String s3=new String("Hello");
		
		System.out.println(s1+" equals "+s2+" : "+s1.equals(s2));
		System.out.println(s1+" == "+s3+" : "+(s1==s3));
		System.out.println("s1 hashcode: "+s1.hashCode());
		System.out.println("s2 hashcode: "+s2.hashCode());
		System.out.println("s3 hashcode: "+s3.hashCode());
	}
}

 

Output

Hello equals Hello : true
Hello == Hello : false
s1 hashcode: 69609650
s2 hashcode: 69609650
s3 hashcode: 69609650

 

All objects have the same hashcode as they contain the same string literal even objects are not identical.

 

2. Creating Mutable Strings

Java allows for modification of the characters in the sequence and can dynamically change its size.

Java also offers classes for mutable strings using StringBuilder and StringBuffer classes.

 

Understanding StringBuffer and StringBuilder

StringBuffer and StringBuilder in Java are classes used to create mutable sequences of characters.

The key difference between StringBuffer and StringBuilder lies in their thread safety and performance.

 

2.1. Understanding StringBuffer

  • Thread-Safe: StringBuffer is thread-safe, which means it is synchronized. Multiple threads can safely modify a StringBuffer object without causing any inconsistency in data.
  • Performance: Due to its thread-safety, StringBuffer operations are slower compared to StringBuilder, because it requires obtaining locks on the object for each operation.

 

Example: Using StringBuffer

package ch11.l1;

public class StringBufferExample1 {
	public static void main(String[] args) {
		StringBuffer sb = new StringBuffer("Hello");
		System.out.println("Original String: "+sb);
		System.out.println("sb hashcode: "+sb.hashCode());
		//Modifying String
		sb.append(" World");
		System.out.println("Modified String: "+sb); //Prints "Hello World"
		System.out.println("sb hashcode: "+sb.hashCode());
	}
}

 

 

Output

Original String: Hello
sb hashcode: 883049899
Modified String: Hello World
sb hashcode: 883049899

 

Explanation

 

2.2. Understanding StringBuilder

  • Not Thread-Safe: StringBuilder is not synchronized, which means it is not thread-safe. This class should be used in scenarios where thread safety is not a concern.
  • Performance: StringBuilder is more efficient than StringBuffer in single-threaded environments due to the lack of synchronization overhead.

 

Example: Using StringBuilder

StringBuilder builder = new StringBuilder("Hello");
builder.append(" World");
System.out.println(builder); // Prints "Hello World"

 

Choosing Between StringBuffer and StringBuilder

  • Use StringBuffer when you need to ensure thread safety in a multi-threaded environment.
  • Use StringBuilder when working in a single-threaded environment, or thread-safety is not a concern, for better performance.

 

Important Note!

Note: Both StringBuffer and StringBuilder allow for the modification of strings without generating new objects for every modification.

 


 

End of the lesson….enjoy learning

 

 

Student Ratings and Reviews

 

 

 

There are no reviews yet. Be the first one to write one.

 

 

Submit a Review