.Lang Package: What Is Your Favorite Package? Why Java - Lang Is Your Favorite Package?
.Lang Package: What Is Your Favorite Package? Why Java - Lang Is Your Favorite Package?
lang Package
1) Object
2) String
3) StringBuffer
4) StringBuilder
5) Wrapper Classes
6) Autoboxing and Autounboxing
For writing any java program the most commonly required classes and interfaces are
encapsulated in the separate package which is nothing but java.lang package.
It is not required to import java.lang package in our program because it is available by
default to every java program.
The following are some of important classes present in java.lang package.
1. Object
2. String
3. StringBuffer
4. StringBuilder
5. All wrapper classes
6. Execption API
7. Thread API….etc
What is your favorite package?
Why java.lang is your favorite package?
It is not required to import lang package explicitly but the remaining packages we have
to import.
Java.lang.Object class: For any java object whether it is predefine or customized the most
commonly required methods are encapsulated into a separate class which is nothing but object
class.
As object class acts as a root (or) parent (or) super for all java classes, by default its
methods are available to every java class.
The following is the list of all methods present in java.lang Object class.
1) public String toString();
2) public native int hashCode();
3) public boolean equals(Object o);
4) protected native Object clone()throws CloneNotSupportedException;
5) public final Class<?> getClass();
6) protected void finalize()throws Throwable;
7) public final void wait()throws InterruptedException;
8) public final native void wait()throws InterruptedException;
9) public final void wait(long ms,int ns)throws InterruptedException;
10) public final native void notify();
11) public final native void notifyAll();
toString() method: We can use this method to get string representation of an object.
Whenever we are try to print any object reference internally toString() method will be
executed.
If our class doesn’t contain toString() method then Object class toString() method will be
executed.
Example: System.out.println(s1); super(s1.toString());
Example 1:
class Student
{
String name;
int rollno;
Student(String name,int rollno)
{
this.name=name;
this.rollno=rollno;
}
public static void main(String args[]){
Student s1=new Student("vijayabhaskar",101);
Student s2=new Student("bhaskar",102);
System.out.println(s1);
System.out.println(s1.toString());
System.out.println(s2);
}
}
Output:
Student@3e25a5
Student@3e25a5
Student@19821f
In the above program Object class toString() method got executed which is
implemented as follows.
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
To provide our own String representation we have to override toString() method in our
class.
For example whenever we are try to print student reference to print his a name and roll
no we have to override toString() method as follows.
public String toString(){
return name+"........"+rollno;
}
In String class, StringBuffer, StringBuilder, wrapper classes and in all collection classes
toString() method is overridden for meaningful string representation. Hence in our
classes also highly recommended to override toString() method.
Example 2:
class Test
{
public String toString()
{
return "Test";
}
public static void main(String[] args){
Integer i=new Integer(10);
String s=new String("bhaskar");
Test t=new Test();
System.out.println(i);
System.out.println(s);
System.out.println(t);
}}
Output:
10
Bhaskar
Test
hashCode() method:
For every object jvm will generate a unique number which is nothing but hashCode.
hashCode of an object will be used by jvm while saving objects into HashSet, HashMap,
and Hashtable etc.
If the objects are stored according to hashCode searching will become very efficient
(The most powerful search algorithm is hashing which will work based on hashCode).
If we didn’t override hashCode() method then Object class hashCode() method will be
executed which generates hashCode based on address of the object but it doesn’t mean
hashCode represents address of the object.
Based on our programming requirement we can override hashCode() method in our
class.
Overriding hashCode() method is said to be proper if and only if for every object we
have to generate a unique number.
Example 3:
class Student class Student
{ {
public int hashCode() int rollno;
{ public int hashCode()
return 100; {
}} return rollno;
It is improper way of overriding }}
hashCode() method because for every It is proper way of overriding
object we are generating same hashcode() method because for every
hashcode. object we are generating a different
hashcode.
toString() method vs hashCode() method:
class Test class Test{
{ int i;
int i; Test(int i){
Test(int i) this.i=i;
{ }
this.i=i; public int hashCode(){
} return i;
public static void main(String[] args){ }
Test t1=new Test(10); public static void main(String[] args){
Test t2=new Test(100); Test t1=new Test(10);
System.out.println(t1); Test t2=new Test(100);
System.out.println(t2); System.out.println(t1);
} System.out.println(t2);
} }}
Object==toString() called. Object==toString() called.
Object==hashCode() called. Test==hashCode() called.
In this case Object class toString() In this case Object class toString()
method got executed which is internally method got executed which is
calls Object class hashCode() method. internally calls Test class hashCode()
method.
Example 4:
class Test
{
int i;
Test(int i)
{
this.i=i;
}
public int hashCode(){
return i;
}
public String toString()
{
return i+"";
}
public static void main(String[] args){
Test t1=new Test(10);
Test t2=new Test(100);
System.out.println(t1);
System.out.println(t2);
}
}
Output:
10
100
In this case Test class toString() method got executed.
Note: if we are giving optrurniuty to Object class toString() method it internally calls hashCode()
method. But if we are overriding toString() method it may not call hashCode() method.
We can use toString() method while printing object references and we can use
hashCode() method while saving objects into HashSet or Hashtable or HashMap.
equals() method:
We can use this method to check equivalence of two objects.
If our class doesn’t contain .equals() method then object class .equals() method will be
executed which is always meant for reference compression[address compression].
Example 5:
class Student
{
String name;
int rollno;
Student(String name,int rollno)
{
this.name=name;
this.rollno=rollno;
}
public static void main(String[] args){
Student s1=new Student("vijayabhaskar",101);
Student s2=new Student("bhaskar",102);
Student s3=new Student("vijayabhaskar",101);
Student s4=s1;
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println(s1.equals(s4));
}}
Output:
False
False
True
Diagram:
In the above program Object class .equals() method got executed which is always meant
for reference compression that is if two references pointing to the same object then
only .equals(() method returns true.
In object class .equals() method is implemented as follows which is meant for reference
compression.
public boolean equals(Object obj) {
return (this == obj);
}
Based on our programming requirement we can override .equals() method for content
compression purpose.
While overriding .equals() method we have to consider the following things.
1) Meaning of content compression like whether the names are equal (or) roll numbers
(or) both are equal.
2) If we are passing heterogeneous object our .equals() method should return false that is
we have to handle ClassCastException to return false.
3) If we are providing null argument our .equals() method should return false that is we
have to handle NullPointerException to return false.
The following is the proper way of overriding .equals() method for content compression
in Student class.
Example 6:
class Student
{
String name;
int rollno;
Student(String name,int rollno)
{
this.name=name;
this.rollno=rollno;
}
public boolean equals(Object obj)
{
try{
String name1=this.name;
int rollno1=this.rollno;
Student s2=(Student)obj;
String name2=s2.name;
int rollno2=s2.rollno;
if(name1.equals(name2)&&rollno1==rollno2)
{
return true;
}
else return false;
}
catch(ClassCastException e)
{
return false;
}
catch(NullPointerException e)
{
return false;
}
}
public static void main(String[] args){
Student s1=new Student("vijayabhaskar",101);
Student s2=new Student("bhaskar",102);
Student s3=new Student("vijayabhaskar",101);
Student s4=s1;
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println(s1.equals(s4));
System.out.println(s1.equals("vijayabhaskar"));
System.out.println(s1.equals("null"));
}
}
Output:
False
True
True
False
False
Simplified version of .equals() method:
public boolean equals(Object o){
try{
Student s2=(Student)o;
if(name.equals(s2.name)&&rollno==s2.rollno){
return true;}
else return false;
}
catch(ClassCastException e)
{
return false;
}
catch(NullPointerException e)
{
return false;
}}
More simplified version of .equals() method:
public boolean equals(Object o)
{
if(this==o)
return true;
if(o instanceof Student)
{
Student s2=(Student)o;
if(name.equals(s2.name)&&rollno==s2.rollno)
return true;
else
return false;
}
return false;
}
Example 7:
class Student
{
String name;
int rollno;
Student(String name,int rollno)
{
this.name=name;
this.rollno=rollno;
}
public boolean equals(Object o)
{
if(this==o)
return true;
if(o instanceof Student)
{
Student s2=(Student)o;
if(name.equals(s2.name)&&rollno==s2.rollno)
return true;
else
return false;
}
return false;
}
public static void main(String[] args){
Student s=new Student("vijayabhaskar",101);
Integer i=new Integer(10);
System.out.println(s.equals(i));
}
}
Output:
False
To make .equals() method more efficient we have to place the following code at the top
inside .equals() method.
if(this==o)
return true;
Diagram:
If 2 references pointing to the same object then .equals() method return true directly
without performing any content compression this approach improves performance of
the system.
Relationship between .equals() method and ==(double equal operator):
1) If r1==r2 is true then r1.equals(r2) is always true that is if two objects are equal by
double equal operator then these objects are always equal by .equals() method also.
2) If r1==r2 is false then we can’t conclude anything about r1.equals(r2) it may return true
(or) false.
3) If r1.equals(r2) is true then we can’t conclude anything about r1==r2 it may returns true
(or) false.
4) If r1.equals(r2) is false then r1==r2 is always false.
Differences between == (double equal operator) and .equals() method?
==(double equal operator) .equals() method
1) It is an operator applicable for both 1) It is a method applicable only for
primitives and object references. object references but not for
primitives.
2) In the case of primitives == (double 2) By default .equals() method present in
equal operator) meant for content object class is also meant for reference
compression, but in the case of object compression.
references == operator meant for
reference compression.
3) We can’t override== operator for 3) We can override .equals() method for
content compression in object content compression.
references.
4) If there is no relationship between 4) If there is no relationship between
argument types then we will get argument types then .equals() method
compile time error saying incompatible simply returns false and we won’t get
types. any compile time error and runtime
error.
5) For any object reference r, 5) For any object reference r,
r==null is always false. r.equals(null) is also returns false.
Note: in general we can use == (double equal operator) for reference compression whereas
.equals() method for content compression.
Contract between .equals() method and hashCode() method:
1) If 2 objects are equal by .equals() method compulsory their hashcodes must be equal
(or) same. That is
If r1.equals(r2) is true then r1.hascode()==r2.hashcode() must be true.
2) If 2 objects are not equal by .equals() method then there are no restrictions on
hashCode() methods. They may be same (or) may be different. That is
If r1.equals(r2) is false then r1.hashCode()==r2.hashCode() may be same (or) may be
different.
3) If hashcodes of 2 objects are equal we can’t conclude anything about .equals() method it
may returns true (or) false. That is
If r1.hashCode()==r2.hashCode() is true then r1.equals(r2) method may returns true (or)
false.
4) If hashcodes of 2 objects are not equal then these objects are always not equal by
.equals() method also. That is
If r1.hashCode()==r2.hashCode() is false then r1.equals(r2) is always false.
To maintain the above contract between .equals() and hashCode() methods whenever
we are overriding .equals() method compulsory we should override hashCode() method.
Violation leads to no compile time error and runtime error but it is not good
programming practice.
Consider the following person class.
Program:
class Person
{
String name;
int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public boolean equals(Object o)
{
if(this==o)
return true;
if(o instanceof Person)
{
Person p2=(Person)o;
if(name.equals(p2.name)&&age==p2.age)
return true;
else
return false;
}
return false;
}
public static void main(String[] args){
Person p1=new Person("vijayabhaskar",101);
Person p2=new Person("vijayabhaskar",101);
Integer i=new Integer(102);
System.out.println(p1.equals(p2));
System.out.println(p1.equals(i));
}}
Output:
True
False
Which of the following is appropriate way of overriding hashCode() method?
Based on whatever the parameters we override “.equals() method” we should use same
parameters while overriding hashCode() method also.
Note: in all wrapper classes, in string class, in all collection classes .equals() method is
overridden for content compression in our classes also it is highly recommended to override
.equals() method.
Which of the following is valid?
1) If hash Codes of 2 objects are not equal then .equals() method always return false.(valid)
Example:
class Test
{
int i;
Test(int i)
{
this.i=i;
}
public int hashCode()
{
return i;
}
public String toString()
{
return i+"";
}
public static void main(String[] args)
{
Test t1=new Test(10);
Test t2=new Test(20);
System.out.println(t1.hashCode());//10
System.out.println(t2.hashCode());//20
System.out.println(t1.hashCode()==t2.hashCode());//false
System.out.println(t1.equals(t2));//false
}
}
2) If 2 objects are equal by == operator then their hash codes must be same.(valid)
Example:
class Test
{
int i;
Test(int i)
{
this.i=i;
}
public int hashCode()
{
return i;
}
public String toString()
{
return i+"";
}
public static void main(String[] args)
{
Test t1=new Test(10);
Test t2=t1;
System.out.println(t1.hashCode());//10
System.out.println(t2.hashCode());//10
System.out.println(t1==t2);//true
}
}
3) If == operator returns false then their hash codes(may be same (or) may be different)
must be different.(invalid)
Example:
class Test
{
int i;
Test(int i)
{
this.i=i;
}
public int hashCode()
{
return i;
}
public String toString()
{
return i+"";
}
public static void main(String[] args)
{
Test t1=new Test(10);
Test t2=new Test(10);
System.out.println(t1.hashCode());//10
System.out.println(t2.hashCode());//10
System.out.println(t1==t2);//false
}
}
4) If hashcodes of 2 objects are equal then these objects are always equal by == operator
also.(invalid)
Clone () method:
The process of creating exactly duplicate object is called cloning.
The main objective of cloning is to maintain backup.
That is if something goes wrong we can recover the situation by using backup copy.
We can perform cloning by using clone() method of Object class.
protected native object clone() throws CloneNotSupportedException;
Example:
class Test implements Cloneable
{
int i=10;
int j=20;
public static void main(String[] args)throws CloneNotSupportedException
{
Test t1=new Test();
Test t2=(Test)t1.clone();
t2.i=888;
t2.j=999;
System.out.println(t1.i+"---------------"+t1.j);
System.out.println(t2.i+"---------------"+t2.j);
}
}
Output:
10---------------20
888---------------999
Diagram:
The process of creating exactly independent duplicate object is called deep cloning.
Example:
Test t1=new Test();
Test t2=(Test)t1.clone();
System.out.println(t1==t2);//false
System.out.println(t1.hashCode()==t2.hashCode());//false
Diagram:
Case 2:
Note:
1) Object creation in SCP is always optional 1st JVM will check is any object already created
with required content or not. If it is already available then it will reuse existing object
instead of creating new object. If it is not already there then only a new object will be
created. Hence there is no chance of existing 2 objects with same content on SCP that is
duplicate objects are not allowed in SCP.
2) Garbage collector can’t access SCP area hence even though object doesn’t have any
reference still that object is not eligible for GC if it is present in SCP.
3) All SCP objects will be destroyed at the time of JVM shutdown automatically.
Example 1:
String s1=new String("bhaskar");
String s2=new String("bhaskar");
String s3="bhaskar";
String s4="bhaskar";
Diagram:
Example 2:
String s=new String("bhaskar");
s.concat("software");
s=s.concat("solutions");
s="bhaskarsoft";
Diagram:
For every String Constant one object will be created in SCP. Because of runtime
operation if an object is required to create compulsory that object should be placed on
the heap but not SCP.
Example 3:
String s1=new String("spring");
s1.concat("fall");
s1=s1+"winter";
String s2=s1.concat("summer");
System.out.println(s1);
System.out.println(s2);
Diagram:
Example:
class StringDemo
{
public static void main(String[] args)
{
String s1=new String("you cannot change me!");
String s2=new String("you cannot change me!");
System.out.println(s1==s2);//false
String s3="you cannot change me!";
System.out.println(s1==s3);//false
String s4="you cannot change me!";
System.out.println(s3==s4);//true
String s5="you cannot "+"change me!";
System.out.println(s3==s5);//true
String s6="you cannot ";
String s7=s6+"change me!";
System.out.println(s3==s7);//false
final String s8="you cannot ";
String s9=s8+"change me!";
System.out.println(s3==s9);//true
System.out.println(s6==s8);//true
}
}
Diagram:
In our program if any String object is required to use repeatedly then it is not
recommended to create multiple object with same content it reduces performance of
the system and effects memory utilization.
We can create only one copy and we can reuse the same object for every requirement.
This approach improves performance and memory utilization we can achieve this
by”scp”.
In SCP several references pointing to same object the main disadvantage in this
approach is by using one reference if we are performing any change the remaining
references will be impacted. To parent this sun people declared String objects as
immutable.
According to this once we creates a String object we can’t perform any changes in the
existing object if we are trying to perform any changes with those changes a new String
object will be created hence immutability is the main disadvantage of scp.
1) What is the main difference between String and StringBuilder?
2) What is the meaning of immutability and mutability?
3) Explain immutability and mutability with an example?
4) What is SCP?
A specially designed memory area for the String literals.
5) What is the advantage of SCP?
Instead of creating a separate object for every requirement we can create only one
object and we can reuse same object for every requirement. This approach improves
performance and memory utilization.
6) What is the disadvantage of SCP?
In SCP as several references pointing to the same object by using one reference if we are
performing any changes the remaining references will be inflected. To prevent this
compulsory String objects should be immutable. That is immutability is the disadvantage
of SCP.
7) Why SCP like concept available only for the String but not for the StringBuffer?
As String object is the most commonly used object sun people provided a specially
designed memory area like SCP to improve memory utilization and performance.
But StringBuffer object is not commonly used object hence specially designed memory
area is not at all required.
8) Why String objects are immutable where as StringBuffer objects are mutable?
In the case of String as several references pointing to the same object, by using one
reference if we are allowed perform the change the remaining references will be
impacted. To prevent this once we created a String object we can’t perform any change
in the existing object that is immutability is only due to SCP.
But in the case of StringBuffer for every requirement we are creating a separate object
by using one reverence if we are performing any change in the object the remaining
references won’t be impacted hence immutability concept is not require for the
StringBuffer.
9) Similar to String objects any other objects are immutable in java?
In addition to String all wrapper objects are immutable in java.
10) Is it possible to create our own mutable class?
Yes.
11) Explain the process of creating our own immutable class with an example?
12) What is the difference between final and immutability?
13) What is interning of String objects?
Interning of String objects:
By using heap object reference, if we want to corresponding SCP object reference we
should go for intern() method.
Example 1:
class StringInternDemo
{
public static void main(String[] args)
{
String s1=new String("bhaskar");
String s2=s1.intern();
String s3="bhaskar";
System.out.println(s2==s3);//true
}
}
Diagram:
If the corresponding object is not there in SCP then intern() method itself will create
that object and returns it.
Example 2:
class StringInternDemo
{
public static void main(String[] args)
{
String s1=new String("bhaskar");
String s2=s1.concat("software");
String s3=s2.intern();
String s4="bhaskarsoftware";
System.out.println(s3==s4);//true
}
}
Diagram 2:
String class constructors:
1) String s=new String();
Creates an empty String Object.
2) String s=new String(String literals);
To create an equivalent String object for the given String literal on the heap.
3) String s=new String(StringBuffer sb);
Creates an equivalent String object for the given StringBuffer.
4) String s=new String(char[] ch);
Example:
class StringInternDemo
{
public static void main(String[] args)
{
char[] ch={'a','b','c'};
String s=new String(ch);
System.out.println(ch);//abc
}
}
5) String s=new String(byte[] b);
For the given byte[] we can create a String.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
byte[] b={100,101,102};
String s=new String(b);
System.out.println(s);//def
}
}
Important methods of String class:
1) public char charAt(int index);
Returns the character locating at specified index.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="bhaskar";
System.out.println(s.charAt(3));//s
System.out.println(s.charAt(100));//StringIndexOutOfBoundsException
}
}
2) public String concat(String str);
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="bhaskar";
s=s.concat("software");
//s=s+"software";
//s+="software";
System.out.println(s);//bhaskarsoftware
}
}
The overloaded “+” and “+=” operators also meant for concatenation purpose only.
3) public boolean equals(Object o);
For content compression where case is important.
It is the overriding version of Object class .equals() method.
4) public boolean equalsIgnoreCase(String s);
For content compression where case is not important.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="bhaskar";
System.out.println(s.equals("bhaskar"));//true
System.out.println(s.equalsIgnoreCase("BHASKAR"));//true
}
}
Note: We can validate username by using equalsIgnoreCase() method where case is not
important and we can validate password by using .equals() method where case is important.
5) public String substring(int begin);
Return the substring from begin index to end of the string.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="vijayabhaskar";
System.out.println(s.substring(6));//bhaskar
}
}
6) public String substring(int begin, int end);
Returns the substring from begin index to end-1 index.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="vijayabhaskar";
System.out.println(s.substring(6));//bhaskar
System.out.println(s.substring(3,7));//ayab
}
}
7) public int length();
Returns the no of characters present in the string.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="vijayabhaskar";
System.out.println(s.length());//13
//System.out.println(s.length);//compile time error
//StringInternDemo.java:7: cannot find symbol
//symbol : variable length
//location: class java.lang.String
}
}
Note: length is the variable applicable for arrays where as length() method is applicable for
String object.
8) public String replace(char old,char new);
To replace every old character with a new character.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="ababab";
System.out.println(s.replace('a','b'));//bbbbbb
}
}
9) public String toLowerCase();
Converts the all characters of the string to lowercase.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="BHASKAR";
System.out.println(s.toLowerCase());//bhaskar
}
}
10) public String toUpperCase();
Converts the all characters of the string to uppercase.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="bhaskar";
System.out.println(s.toUpperCase());//BHASKAR
}
}
11) public String trim()
We can use this method to remove blank spaces present at beginning and end of the
string but not blank spaces present at middle of the String.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s=" bha skar ";
System.out.println(s.trim());//bha skar
}
}
12) public int indexOf(char ch);
It returns index of 1st occurrence of the specified character if the specified character is
not available then return -1.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="vijayabhaskarreddy";
System.out.println(s.indexOf('a'));//3
System.out.println(s.indexOf('z'));-1
}
}
13) public int lastIndexOf(Char ch);
It returns index of last occurrence of the specified character if the specified character is
not available then return -1.
Example:
class StringInternDemo
{
public static void main(String[] args)
{
String s="vijayabhaskarreddy";
System.out.println(s.lastIndexOf('a'));//11
System.out.println(s.indexOf('z'));//-1
}
}
Note:
Because runtime operation if there is a change in content with those changes a new
object will be created only on the heap but not in SCP.
If there is no change in content no new object will be created the same object will be
reused.
Example 1:
class StringInternDemo
{
public static void main(String[] args)
{
String s1="bhaskar";
String s2=s1.toUpperCase();
String s3=s1.toLowerCase();
System.out.println(s1==s2);//false
System.out.println(s1==s3);//true
}
}
Diagram:
Example 2:
class StringInternDemo
{
public static void main(String[] args)
{
String s1="bhaskar";
String s2=s1.toString();
System.out.println(s1==s2);//true
}
}
Diagram:
Final vs immutability:
If we declare a variable as final then we can’t perform reassignment for that variable. It
doesn’t mean in the corresponding object we can’t perform any changes. That is
through final keyword we won’t get any immutability that is final and immutability
concepts are different.
Example:
class Test
{
public static void main(String[] args)
{
final StringBuffer sb=new StringBuffer("bhaskar");
sb.append("software");
System.out.println(sb);//bhaskarsoftware
sb=new StringBuffer("solutions");//C.E: cannot assign a value to final variable
sb
}
}
In the above example even though “sb” is final we can perform any type of change in
the corresponding object. That is through final keyword we are not getting any
immutability nature.
StringBuffer
If the content will change frequently then never recommended to go for String object
because for every change a new object will be created internally.
To handle this type of requirement we should go for StringBuffer concept.
The main advantage of StringBuffer over String is, all required changes will be
performed in the existing object only instead of creating new object.
Constructors:
1) StringBuffer sb=new StringBuffer();
Creates an empty StringBuffer object with default initialcapacity “16”.
Once StringBuffer object reaches its maximum capacity a new StringBuffer object will be
created with Newcapacity=(currentcapacity+1)*2.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer();
System.out.println(sb.capacity());//16
sb.append("abcdefghijklmnop");
System.out.println(sb.capacity());//16
sb.append("q");
System.out.println(sb.capacity());//34
}
}
2) StringBuffer sb=new StringBuffer(int initialcapacity);
Creates an empty StringBuffer object with the specified initial capacity.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer(19);
System.out.println(sb.capacity());//19
}
}
3) StringBuffer sb=new StringBuffer(String s);
Creates an equivalent StringBuffer object for the given String with
capacity=s.length()+16;
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer("bhaskar");
System.out.println(sb.capacity());//23
}
}
Important methods of StringBuffer:
1) public int length();
Return the no of characters present in the StringBuffer.
2) public int capacity();
Returns the total no of characters but a StringBuffer can accommodate(hold).
3) public char charAt(int index);
It returns the character located at specified index.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer("vijayabhaskarreddy");
System.out.println(sb.length());//18
System.out.println(sb.capacity());//34
System.out.println(sb.charAt(14));//e
}
}
4) public void setCharAt(int index,char ch);
To replace the character locating at specified index with the provided character.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer("vijayabhaskarreddy");
sb.setCharAt(6,'A');
System.out.println(sb);
}
}
5) public StringBuffer append(String s);
public StringBuffer append(int i);
public StringBuffer append(long l);
public StringBuffer append(boolean b); All these are overloaded methods.
public StringBuffer append(double d);
public StringBuffer append(float f);
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer();
sb.append("PI value is :");
sb.append(3.14);
sb.append(" this is exactly ");
sb.append(true);
System.out.println(sb);//PI value is :3.14 this is exactly true
}
}
6) public StringBuffer insert(int index,String s);
public StringBuffer insert(int index,int i);
public StringBuffer insert(int index,long l);
public StringBuffer insert(int index,double d); All are overloaded methods
public StringBuffer insert(int index,boolean b);
public StringBuffer insert(int index,float f);
To insert at the specified location.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer("vijaya");
sb.insert(6,"bhaskar");
sb.insert(13,"9");
System.out.println(sb);//vijayabhaskar9
}
}
7) public StringBuffer delete(int begin,int end);
To delete characters from begin index to end n-1 index.
8) public StringBuffer deleteCharAt(int index);
To delete the character locating at specified index.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer("vijayabhaskar");
System.out.println(sb);//vijayabhaskar
sb.delete(6,13);
System.out.println(sb);//vijaya
sb.deleteCharAt(5);
System.out.println(sb);//vijay
}
}
9) public StringBuffer reverse();
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer("vijayabhaskar");
System.out.println(sb);//vijayabhaskar
System.out.println(sb.reverse());//raksahbayajiv
}
}
10) public void setLength(int length);
Consider only specified no of characters and remove all the remaining characters.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer("vijayabhaskar");
sb.setLength(6);
System.out.println(sb);//vijaya
}
}
11) public void trimToSize();
To deallocate the extra free memory such that capacity and size are equal.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer(1000);
System.out.println(sb.capacity());//1000
sb.append("bhaskar");
System.out.println(sb.capacity());//1000
sb.trimToSize();
System.out.println(sb.capacity());//7
}
}
12) public void ensureCapacity(int initialcapacity);
To increase the capacity dynamically based on our requirement.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer();
System.out.println(sb.capacity());//16
sb.ensureCapacity(1000);
System.out.println(sb.capacity());//1000
}
}
StringBuilder (1.5)
Every method present in StringBuffer is declared as synchronized hence at a time only
one thread is allowed to operate on the StringBuffer object due to this, waiting time of
the threads will be increased and effects performance of the system.
To overcome this problem sun people introduced StringBuilder concept in 1.5v.
StringBuilder is exactly same as StringBuffer except the following differences.
StringBuffer StringBuilder
1) Every method present in StringBuffer is 1) No method present in StringBuilder is
synchronized. synchronized.
2) At a time only one thread is allow to 2) Multiple Threads are allowed to
operate on the StringBuffer object operate simultaneously on the
hence StringBuffer object is Thread StringBuilder object hence
safe. StringBuilder is not Thread safe.
3) It increases waiting time of the Thread 3) Threads are not required to wait and
and hence relatively performance is hence relatively performance is high.
low.
4) Introduced in 1.0 version. 4) Introduced in 1.5 versions.
String vs StringBuffer vs StringBuilder:
If the content is fixed and won’t change frequently then we should go for String.
If the content will change frequently but Thread safety is required then we should go for
StringBuffer.
If the content will change frequently and Thread safety is not required then we should
go for StringBuilder.
Method chaining:
For most of the methods in String, StringBuffer and StringBuilder the return type is same
type only. Hence after applying method on the result we can call another method which
forms method chaining.
Example:
s.m1().m2().m3()……………….
In method chaining all methods will be evaluated from left to right.
Example:
class StringBufferDemo
{
public static void main(String[] args)
{
StringBuffer sb=new StringBuffer();
sb.append("vijaya").insert(6,"bhaskarreddy").delete(13,17).reverse().append("solutions
").insert(22,"abcdf").reverse();
System.out.println(sb);//sfdcbanoitulosvijayabhaskary
}
}
Wrapper classes
The main objectives of wrapper classes are:
To wrap primitives into object form so that we can handle primitives also just like
objects.
To define several utility functions which are required for the primitives.
Constructors:
All most all wrapper classes define the following 2 constructors one can take
corresponding primitive as argument and the other can take String as argument.
Example:
1) Integer i=new Integer(10);
2) Integer i=new Integer(“10”);
If the String is not properly formatted then we will get runtime exception saying
“NumberFormatException”.
Example:
class WrapperClassDemo
{
public static void main(String[] args)throws Exception
{
Integer i=new Integer("ten");
System.out.println(i);//NumberFormatException
}
}
Float class defines 3 constructors with float, String and double arguments.
1) Float f=new Float (10.5f);
2) Float f=new Float (“10.5f”);
3) Float f=new Float(10.5);
4) Float f=new Float (“10.5”);
Character class defines only one constructor which can take char primitive as argument
there is no String argument constructor.
Character ch=new Character(‘a’);//valid
Character ch=new Character(“a”);//invalid
Boolean class defines 2 constructors with boolean primitive and String arguments.
If we want to pass boolean primitive the only allowed values are true, false where case
should be lower case.
Example:
Boolean b=new Boolean(true);
//Boolean b1=new Boolean(True);//C.E
//Boolean b=new Boolean(False);//C.E
If we are passing String argument then case is not important and content is not
important. If the content is case insensitive String of true then it is treated as true in all
other cases it is treated as false.
Example 1:
class WrapperClassDemo
{
public static void main(String[] args)throws Exception
{
Boolean b1=new Boolean("true");
Boolean b2=new Boolean("True");
Boolean b3=new Boolean("false");
Boolean b4=new Boolean("False");
Boolean b5=new Boolean("bhaskar");
System.out.println(b1);//true
System.out.println(b2);//true
System.out.println(b3);//false
System.out.println(b4);//false
System.out.println(b5);//false
}
}
Example 2(for exam purpose):
class WrapperClassDemo
{
public static void main(String[] args)throws Exception
{
Boolean b1=new Boolean("yes");
Boolean b2=new Boolean("no");
System.out.println(b1);//false
System.out.println(b2);//false
System.out.println(b1.equals(b2));//true
System.out.println(b1==b2);//false
}
}
Wrapper class Constructor summery
Byte byte, String
Short short, String
Integer Int, String
Long long, String
Float float, String, double
Double double, String
Character
Boolean boolean, String
Note:
1) In all wrapper classes toString() method is overridden to return its content.
2) In all wrapper classes .equals() method is overridden for content compression.
Utility methods:
1) valueOf() method.
2) XXXValue() method.
3) parseXxx() method.
4) toString() method.
valueOf() method: We can use valueOf() method to create wrapper object for the given
primitive or String this method is alternative to constructor.
Form 1: Every wrapper class except Character class contains a static valueOf() method to create
wrapper object for the given String.
public static wrapper valueOf(String s);
Example:
class WrapperClassDemo
{
public static void main(String[] args)throws Exception
{
Integer i=Integer.valueOf("10");
Double d=Double.valueOf("10.5");
Boolean b=Boolean.valueOf("bhaskar");
System.out.println(i);//10
System.out.println(d);//10.5
System.out.println(b);//false
}
}
Form 2: Every integral type wrapper class (Byte, Short, Integer, and Long) contains the following
valueOf() method to convert specified radix string to wrapper object.
Note: the allowed radix range is 2-36.
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
Integer i=Integer.valueOf("100",2);
System.out.println(i);//4
}
}
Analysis:
Form 3: Every wrapper class including Character class defines valueOf() method to convert
primitive to wrapper object.
public static wrapper valueOf(primitive p);
Example:
class WrapperClassDemo
{
public static void main(String[] args)throws Exception
{
Integer i=Integer.valueOf(10);
Double d=Double.valueOf(10.5);
Boolean b=Boolean.valueOf(true);
System.out.println(i);//10
System.out.println(d);//10.5
System.out.println(b);//true
}
}
Diagram:
xxxValue() method: We can use xxxValue() methods to convert wrapper object to primitive.
Every number type wrapper class (Byte, Short, Integer, Long, Float, Double) contains the
following 6 xxxValue() methods to convert wrapper object to primitives.
1) public byte byteValue()
2) public short shortValue()
3) public int intValue()
4) public long longValue()
5) public float floatValue()
6) pblic double doubleValue();
Example:
class WrapperClassDemo
{
public static void main(String[] args)throws Exception
{
Integer i=new Integer(130);
System.out.println(i.byteValue());//-126
System.out.println(i.shortValue());//130
System.out.println(i.intValue());//130
System.out.println(i.longValue());//130
System.out.println(i.floatValue());//130.0
System.out.println(i.doubleValue());//130.0
}
}
charValue() method: Character class contains charValue() method to convert Character object
to char primitive.
public char charValue();
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
Character ch=new Character('a');
char c=ch.charValue();
System.out.println(c);//a
}
}
booleanValue() method: Boolean class contains booleanValue() method to convert Boolean
object to boolean primitive.
public boolean booleanValue();
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
Boolean b=new Boolean("bhaskar");
boolean b1=b.booleanValue();
System.out.println(b1);//false
}
}
Diagram:
parseXxx() method: We can use this method to convert String to corresponding primitive.
Form1: Every wrapper class except Character class contains a static parseXxx() method to
convert String to corresponding primitive.
public static primitive parseXxx(String s);
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
int i=Integer.parseInt("10");
boolean b=Boolean.parseBoolean("bhaskar");
double d=Double.parseDouble("10.5");
System.out.println(i);//10
System.out.println(b);//false
System.out.println(d);//10.5
}
}
Form 2: integral type wrapper classes(Byte, Short, Integer, Long) contains the following
parseXxx() method to convert specified radix String form to corresponding primitive.
public static primitive parseXxx(String s,int radix);
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
int i=Integer.parseInt("100",2);
System.out.println(i);//4
}
}
Diagram:
toString() method: We can use toString() method to convert wrapper object (or) primitive to
String.
Form 1:
public String toString();
Every wrapper class including Character class contains the above toString() method to
convert wrapper object to String.
It is the overriding version of Object class toString() method.
Whenever we are trying to print wrapper object reference internally this toString()
method only executed.
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
Integer i=Integer.valueOf("10");
System.out.println(i);//10
System.out.println(i.toString());//10
}
}
Form 2: Every wrapper class contains a static toString() method to convert primitive to String.
public static String toString(primitive p);
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
String s1=Integer.toString(10);
String s2=Boolean.toString(true);
System.out.println(s1);//10
System.out.println(s2);//true
}
}
Form 3:
Integer and long classes contains the following static toString() method to convert the
primitive to specified radix String form.
public static String toString(primitive p,int radix);
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
String s1=Integer.toString(7,2);
String s2=Integer.toString(17,2);
System.out.println(s1);//111
System.out.println(s2);//10001
}
}
Form 4: Integer and Long classes contains the following toXxxString() methods.
public static String toBinaryString(primitive p);
public static String toOctalString(primitive p);
public static String toHexString(primitive p);
Example:
class WrapperClassDemo
{
public static void main(String[] args)
{
String s1=Integer.toBinaryString(7);
String s2=Integer.toOctalString(10);
String s3=Integer.toHexString(20);
System.out.println(s1);//111
System.out.println(s2);//12
System.out.println(s3);//14
}
}
Diagram:
String, StringBuffer, StringBuilder and all wrapper classes are final classes.
The wrapper classes which are not child class of Number of Boolean and Character.
The wrapper classes which are not direct class of Object of Byte, Short, Integer, Long,
Float, Double.
Sometimes we can consider Void is also as wrapper class.
In addition to String all wrapper objects also immutable in java.
Program 2:
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
Boolean b=new Boolean(true);
if(b)
{
System.out.println("hello");
}}}
Output:
Hello
Example 2:
Program 1:
Program 2:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
ArrayList l=new ArrayList();
Integer i=new Integer(10);
l.add(i);
}
}
But from 1.5 version onwards we can provide primitive value in the place of wrapper
and wrapper object in the place of primitive all required conversions will be performed
automatically by compiler. These automatic conversions are called Autoboxing and
Autounboxing.
Autoboxing: Automatic conversion of primitive to wrapper object by compiler is called
Autoboxing.
Example:
Integer i=10; [compiler converts “int” to “Integer” automatically by Autoboxing]
After compilation the above line will become.
Integer i=Integer.valueOf(10);
That is internally Autoboxing concept is implemented by using valueOf() method.
Autounboxing: automatic conversion of wrapper object to primitive by compiler is called
Autounboxing.
Example:
Integer i=new Integer(10);
Int i=I; [compiler converts “Integer” to “int” automatically by Autounboxing]
After compilation the above line will become.
Int i=I.intValue();
That is Autounboxing concept is internally implemented by using xxxValue() method.
Diagram:
Example:
Note: From 1.5 version onwards we can use primitives and wrapper objects interchangly the
required conversions will be performed automatically by compiler.
Example 1:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
static Integer I=0;
public static void main(String[] args)
{
int i=I;
System.out.println(i);//0
}
}
Example 2:
Example 3:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
Integer x=10;
Integer y=x;
++x;
System.out.println(x);//11
System.out.println(y);//10
System.out.println(x==y);//false
}
}
Diagram:
Note: All wrapper objects are immutable that is once we created a wrapper object we can’t
perform any changes in the existing object. If we are trying to perform any changes with those
changes a new object will be created.
Example 4:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
Integer x=new Integer(10);
Integer y=new Integer(10);
System.out.println(x==y);//false
}
}
Diagram:
Example 5:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
Integer x=new Integer(10);
Integer y=10;
System.out.println(x==y);//false
}
}
Diagram:
Example 6:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
Integer x=new Integer(10);
Integer y=x;
System.out.println(x==y);//true
}
}
Diagram:
Example 7:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
Integer x=10;
Integer y=10;
System.out.println(x==y);//true
}
}
Diagram:
Example 8:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
Integer x=100;
Integer y=100;
System.out.println(x==y);//true
}
}
Diagram:
Example 9:
import java.util.*;
class AutoBoxingAndUnboxingDemo
{
public static void main(String[] args)
{
Integer x=1000;
Integer y=1000;
System.out.println(x==y);//false
}
}
Diagram:
Diagram:
Conclusions:
To implement the Autoboxing concept in every wrapper class a buffer of objects will be
created at the time of class loading.
By Autoboxing if an object is required to create 1st JVM will check whether that object is
available in the buffer or not. If it is available then JVM will reuse that buffered object
instead of creating new object. If the object is not available in the buffer then only a
new object will be created. This approach improves performance and memory
utilization.
But this buffer concept is available only in the following cases.
Byte Always
Short -128 To 127
Integer -128 To 127
Long -128 To 127
Character 0 To 127
Boolean Always
In all the remaining cases compulsory a new object will be created.
Examples:
Note: When compared with constructors it is recommended to use valueOf() method to create
wrapper object.