[post-views]
In this lesson, you will learn
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.
String
is a sequence of characters that is treated as an object.
There are mainly two ways to create a String
in Java.
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.
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.
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() 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.
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.
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");
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.
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.
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.
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.
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.
StringBuffer
is thread-safe, which means it is synchronized. Multiple threads can safely modify a StringBuffer
object without causing any inconsistency in data.StringBuffer
operations are slower compared to StringBuilder
, because it requires obtaining locks on the object for each operation.
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
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.StringBuilder
is more efficient than StringBuffer
in single-threaded environments due to the lack of synchronization overhead.
StringBuilder builder = new StringBuilder("Hello");
builder.append(" World");
System.out.println(builder); // Prints "Hello World"
StringBuffer
and StringBuilder
StringBuffer
when you need to ensure thread safety in a multi-threaded environment.StringBuilder
when working in a single-threaded environment, or thread-safety is not a concern, for better performance.
Note: Both StringBuffer
and StringBuilder
allow for the modification of strings without generating new objects for every modification.
There are no reviews yet. Be the first one to write one.
You must be logged in to submit a review.