You are on page 1of 87

Java.

lang package
1. Introduction
2. Object class
3. String class
4. StringBuffer class
5. StringBuilder class
6. wrapper class
7. Autoboxing and Autounboxing
Introduction:
1. For writing any java program whether it is simple or complex, the
most commonly require classes and interfaces are grouped into a
separate package which is nothing but java.lang package.
2. We are not required to import java.lang package explicitly
because all classes and interfaces present in lang package by
default available to every java program.

Java.lang.Object:

1. The most commonly required methods for every java class (whether it
pre-define class or customized class) are define in a separate class
which is nothing but Object class.
2. Every class is the child class of object either directly or indirectly.
So that, object class methods by default available to every java class.
Hence Object class is considered as root of all java classes.

Note:

 If our class doesn’t extends any other class then only our class is the
direct child class of Object class.
package langpack;

public class A {

A--------> Object

 If our class extends any other class then our class is indirect child
class of Object class.

package langpack;

public class A {

}
package langpack;

public class B extends A{

}
A---------->B--------->Object----multi-level inheritance

 Either directly or indirectly, java won’t provide support for multiple


inheritance with respect to classes.

3. Object class defines the following 11 methods:


 public String toString();
 public native int hashCode();
 public boolean equals(Object o);
 protected native Object clone() throws
CloneNotSupportedException;
 protected native finalize() throws Throwable;
 public final Class getClass();
 protected final void wait() throws InterruptedException;
 protected final native void wait(long ms) throws
InterruptedException;
 protected final native void wait(long ms, int ns ) throws
InterruptedException;
 public native final void notify();
 public native final void notifyAll();

Note:
Strictly speaking object class contains 12 methods. The extra method
registerNatives().

Private static native void registerNatives();

This method is internally required for object class and not available
to the child classes. Hence we are not required to consider this
method.
toString() method:
1. we can use toString() method to get String representation of an object.
Sting s = Obj.toString();
Syso(s);
2. whenever we are trying object reference internally toString() method
will be called.

Example;

Student s = new Student();

Syso(s)-----> syso(s.toString());

3. If our class doesn’t contain toString() method then object class


toString() method will be executed.

package langpack;

public class Student{


String name;
int rollNo;

public Student(String name,int rollNo ) {


this.name = name;
this.rollNo = rollNo;
}

public static void main(String[] args) {


Student s = new Student("lalit", 100);
Student s1 = new Student("durga", 101);

System.out.println(s);
System.out.println(s.toString());
System.out.println(s1);
}

}
Output:
langpack.Student@15db9742
langpack.Student@15db9742
langpack.Student@6d06d69c
In the above example Object class toString() method got executed which is
implemented as follows:

public String toString() {


return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

className@hashCode_in_hexaDecimal_form

Based on requirement we can override toString() method to provide our


own string representation.

Example:

Whenever we are trying to print student object reference to print his name
and roll no. we have to override toString() method as follows:

package langpack;

public class Student{


String name;
int rollNo;

public Student(String name,int rollNo ) {


this.name = name;
this.rollNo = rollNo;
}

public String toString() {


return name + " " + rollNo;
}

public static void main(String[] args) {


Student s = new Student("lalit", 100);
Student s1 = new Student("durga", 101);

System.out.println(s);
System.out.println(s.toString());
System.out.println(s1);
}

}
Output:

lalit 100
lalit 100
durga 101

4. In all wrapper classes, all collection classes, String class,


StringBuffer and StringBuilder classes toString() method is overridden
for meaningful string representation. Hence it is highly recommended to
override toString() method in our class also.

package langpack;

import java.util.ArrayList;

public class Test{

public String toString() {


return "test";
}

public static void main(String[] args) {


String s = new String("Lalit");
System.out.println(s);

Integer i = new Integer(10);


System.out.println(i);

ArrayList l = new ArrayList();


l.add("A");
l.add("B");
System.out.println(l);

Test t = new Test();


System.out.println(t);
}

}
Output:

Lalit

10
[A, B]
test
hashCode() method:
1. For every object a unique number is generated by JVM which is nothing
but hashCode.
2. hashCode won’t represent address of object.
3. JVM will use hashCode while saving objects into hashing related data
structures like hashTable,hashMap,HashSet etc.
4. The main advantage of saving objects based on hashCode is searching
operation will become easy (the most powerful search algorithm up to
today is hashing.)
5. If you are giving the chance to object class hashCode() method, it will
generate hash code based on address of the object. It doesn’t mean hash
code represents address of the object.
6. Based on our requirement we can override hashCode() method in our class
to generate our own hash code.
7. Overriding hashCode() method is said to be proper if and only if for
every object we have to generate a unique number as hash code.

package langpack;

public class Student{

public int hashCode() {


return 100;
}

This is improper way of overriding hashCode() method because for all student
objects we are generating same number as hash code.

package langpack;

public class Student{

int rollNo;

public Student(int rollNo) {


this.rollNo = rollNo;
}
public int hashCode() {
return rollNo;
}

public static void main(String[] args) {


Student s1 = new Student(101);

This is proper way of overriding hashCode() method because we are


generating a different hash code for every object.

toString() VS hashCode():
1. If we are giving are object class toString() method, it will
intwrnally calls hashCode() method.
2. If we are overriding toString() method then our toString() method
may not call hashCode() method.

package langpack;

public class Test{

int rollNo;

public Test(int rollNo) {


this.rollNo = rollNo;
}

public static void main(String[] args) {


Test t1 = new Test(101);
Test t2 = new Test(102);

System.out.println(t1);
System.out.println(t2);
}
}

Output:
langpack.Test@15db9742
langpack.Test@6d06d69c

JVM--->toString() method of object class----->in toString() method JVM call


internally hashCode() method of object class.

package langpack;

public class Test{

int rollNo;

public Test(int rollNo) {


this.rollNo = rollNo;
}

@Override
public int hashCode() {
// TODO Auto-generated method stub
return rollNo;
}
public static void main(String[] args) {
Test t1 = new Test(101);
Test t2 = new Test(102);

System.out.println(t1);
System.out.println(t2);
}
}

Output:

langpack.Test@65
langpack.Test@66

JVM--->toString() method of object class----->in toString() method JVM call


our own overrided hashCode() method of Test (our class) class.

package langpack;

public class Test{


int rollNo;

public Test(int rollNo) {


this.rollNo = rollNo;
}

@Override
public String toString() {
return rollNo + "";
// TODO Auto-generated method stub
}

@Override
public int hashCode() {
// TODO Auto-generated method stub
return rollNo;
}
public static void main(String[] args) {
Test t1 = new Test(101);
Test t2 = new Test(102);

System.out.println(t1);
System.out.println(t2);
}
}

Output:

101
102

JVM---> call overrided toString() method of our class so in overrided method


we didn’t call any hashCode() method. So hashCode will not execute.

Equals() method:
1. We can equals() method to check equality of two objects.

Obj1.equals(obj2)

2. If our class doesn’t contain equals() method then object class equals()
method will be executed.
package langpack;

public class Student{

String name;
int rollNo;

public Student(String name,int rollNo) {


this.name = name;
this.rollNo = rollNo;
}

public static void main(String[] args) {


Student s1 = new Student("Lalit",101);
Student s2 = new Student("Bizlain",102);
Student s3 = new Student("Lalit", 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

In the above example object class equals() method got executed which is meant
for reference comparison (address comparison) i.e if two references pointing
to the same object then only that equals() method returns true.

 Based on our requirement we can override equals() method for content


comparison.
package langpack;

public class Student{

String name;
int rollNo;

public Student(String name,int rollNo) {


this.name = name;
this.rollNo = rollNo;
}

public boolean equals(Object obj) {


String name1 = this.name;
int rollNo1 = this.rollNo;

Student s = (Student)obj;

String name2 = s.name;


int rollNo2 = s.rollNo;

if(name1.equals(name2) && rollNo1==rollNo2) {


return true;
}else {
return false;
}
}

public static void main(String[] args) {


Student s1 = new Student("Lalit",101);
Student s2 = new Student("Bizlain",102);
Student s3 = new Student("Lalit", 101);
Student s4 = s1;

System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println(s1.equals(s4));
}
}

Output:

false
true
true

3. While overriding equals() method for content comparison we have to take


care about the following:
 What is the meaning of equality (whether we have to check only names or
only rollNo or both)
 If we are passing different type of object then our equals() method
should not rise classCastException i.e we have to handle
classCastException to return false.
 If we are passing null argument then our equals() method should not
rise nullPointerException i.e we have to handle nullPointerException to
return false.
 The following is the proper of overriding equals() method for student
class content comparison.

package langpack;

public class Student{

String name;
int rollNo;

public 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 s = (Student)obj;

String name2 = s.name;


int rollNo2 = s.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("Lalit",101);
Student s2 = new Student("Bizlain",102);
Student s3 = new Student("Lalit", 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("lalit"));
System.out.println(s1.equals(null));
}
}

Output:

false
true
true
false
false

simpliefied version of equals() method:

package langpack;

public class Student{

String name;
int rollNo;

public Student(String name,int rollNo) {


this.name = name;
this.rollNo = rollNo;
}

public boolean equals(Object obj) {


try {
Student s = (Student)obj;
if(name.equals(s.name) && rollNo==s.rollNo) {
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("Lalit",101);
Student s2 = new Student("Bizlain",102);
Student s3 = new Student("Lalit", 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("lalit"));
System.out.println(s1.equals(null));
}
}

Output:

false
true
true
false
false

More simpliefied version of equals() method:

package langpack;
public class Student{

String name;
int rollNo;

public Student(String name,int rollNo) {


this.name = name;
this.rollNo = rollNo;
}

public boolean equals(Object obj) {


if(obj instanceof Student) {
Student s = (Student)obj;

if(name.equals(s.name) && rollNo==s.rollNo) {


return true;
}else {
return false;
}
} else {
return false;
}

}
public static void main(String[] args) {
Student s1 = new Student("Lalit",101);
Student s2 = new Student("Bizlain",102);
Student s3 = new Student("Lalit", 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("lalit"));
System.out.println(s1.equals(null));
}
}

Output:

false
true
true
false
false

note:

To make above equals() method more efficient we have to write the following
code: at the beginning inside equals method.

package langpack;

public class Student{

String name;
int rollNo;

public Student(String name,int rollNo) {


this.name = name;
this.rollNo = rollNo;
}

public boolean equals(Object obj) {


if(obj==this) {
return true;
}
if(obj instanceof Student) {
Student s = (Student)obj;

if(name.equals(s.name) && rollNo==s.rollNo) {


return true;
}else {
return false;
}
} else {
return false;
}

}
public static void main(String[] args) {
Student s1 = new Student("Lalit",101);
Student s2 = new Student("Bizlain",102);
Student s3 = new Student("Lalit", 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("lalit"));
System.out.println(s1.equals(null));
}
}

Output:

false
true
true
false
false

package langpack;

public class Student{

public static void main(String[] args) {


String s1 = new String("lalit");
String s2 = new String("lalit");

System.out.println(s1==s2);
System.out.println(s1.equals(s2));
}
}

Output:

false
true

In String class .equals() method is overridden for content comparison.


Hence, even though objects are different if content is same
then .equals() method returns true.
package langpack;

public class Student{

public static void main(String[] args) {


StringBuffer s1 = new StringBuffer("lalit");
StringBuffer s2 = new StringBuffer("lalit");

System.out.println(s1==s2);
System.out.println(s1.equals(s2));
}
}

Output:

false
false

In StringBuffered class .equals() method is not overridden for content


comparison. Hence, if objects are different then .equals() method
returns false even though content is same.

getClass() method:

1. We can use getClass() method to get run time class definition of an


object.

Public final class getClass();

2. By using this ‘Class’ class object we can access class level properties
like fully qualified name of the class, methods information,
constructors information etc.

package langpack;

import java.lang.reflect.Method;

public class Test{

public static void main(String[] args) {


int count = 0;
Object o = new String("lalit");
Class c = o.getClass();
System.out.println("fully qualified name of class:" +
c.getName());

Method[] m = c.getDeclaredMethods();
System.out.println("methods information");

for(Method m1 : m) {
count++;
System.out.println(m1.getName());
}
System.out.println("The number of methods :" + count);
}
}

Example2:

To display database vendor specific connection interface implemented class


name

Connection con = new DriverManager.getConnection();

Syso(con.getClass.getName());

Note:

 After loading every .class file JVM will create an object of the type
java.lang.class in the heap area. Programmer can use this class object
to get Class level information.
 We can use getClass() method very frequently in reflections API.

Finalize() method:

1. Just before destroying an object garbage collector calls finalize()


method to perform cleanup activities.
2. Once finalize() method completes automatically garbage collector
destroyed that object.
Java.lang.String:
Case1:

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String("Lalit");
s.concat("Bizlain");
System.out.println(s);
}

}
Output:

Lalit

Once we create 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 object will be created. This non-changeable behavior is
nothing immutability of string.

package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb = new StringBuffer("Lalit");
sb.append("Bizlain");
System.out.println(sb);
}

LalitBizlain

Once we create StringBuffere object, we can perform any change in the


existing object. This changeable behavior is nothing but mutability of
StringBuffered object.
Case2:
package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb1 = new StringBuffer("Lalit");
StringBuffer sb2 = new StringBuffer("Lalit");
System.out.println(sb1==sb2);
System.out.println(sb1.equals(sb2));
}

Output:

false
false

In StringBuffered class .equals() method is not overridden for content


comparison. Hence, if objects are different then .equals() method
returns false even though content is same, which is meant for
reference comparison (address comparison).

package langpack;

public class Test{

public static void main(String[] args) {


String sb1 = new String("Lalit");
String sb2 = new String("Lalit");
System.out.println(sb1==sb2);
System.out.println(sb1.equals(sb2));
}

Output:

false
true
In String class .equals() method is overridden for content comparison.
Hence even though objects are different if content is same .equals()
method returns true.

Case3:

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String("Lalit");

}}

In this case two objects will be created one in the heap area and the
other is in String constant pool (SCP) and s is always pointing to
heap object.

Heap SCP

S Lalit Lalit for future use

package langpack;

public class Test{

public static void main(String[] args) {


String s = "Lalit";

}}

In this only one object will be created in SCP and s is always pointing to
that object.

Heap SCP

S Lalit

Note1:
 Object creation in SCP is optional, 1st it will check is there any
object already present in SCP with the required content.
 If object already present then existing object will be reused.
 If object not already available then only a new object will be created.
But this rule is applicable only for SCP but not for the heap.

Note2:
 Garbage collector is not allowed to access SCP area. Hence even
though object doesn’t contain reference variable, it is not
available for Garbage collector if it is present in SCP area.
 All SCP objects will be destroyed automatically at the time JVM
shut down.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("Lalit");
String s2 = new String("Lalit");
String s3 = "Lalit";
String s4 = "Lalit";

}}

Heap SCP

S1 Lalit Lalit

S2 Lalit S3 s4

Note:

1. Whenever we are using new keyword/operator, compulsory a new object


will be created in the heap area. Hence there may be a chance of
existing two objects with same content in the heap area but not in SCP
i.e duplicate objects are possible in the heap area but not in SCP.
package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("Lalit");
s1.concat("Bizlain");
String s2 = s1.concat("Lallit");
s1 = s1.concat("soft");

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

}}

Output:

Lalitsoft
LalitLallit

heap SCP

S1 Lalit Lalit

LalitBizlain Bizlain

S2 LalitLallit Lallit

Lalitsoft soft

For every string constant one object will be placed in SCP area.

Because of some run time operation, if an object is required to create that


object will be placed only in the heap area but not in SCP area.
Constructors of String class:
1. String s = new String();

Create an empty String object.

2. String s = new String(String literal);

Create a string object and the heap for the give string literal.

3. String s = new String(StringBuffer sb);

Create an equivalent string object for the given StringBuffer.

4. String s = new String(char[] ch);

Create an equivalent string object for the given char[] ch.

package langpack;

public class Test{

public static void main(String[] args) {


char[] ch = {'a', 'b', 'c', 'd'};
String s = new String(ch);
System.out.println(s);
}}

Output:
abcd

5. String s = new String(byte[] b);


Create an equivalent string object for the given byte[] b.

package langpack;

public class Test{


public static void main(String[] args) {
byte[] b = {101,102,103,104};
String s = new String(b);
System.out.println(s);
}}

Output:
efgh

Important methods of String class:


1. public char charAT(int index);

Return the character locating at specified index.

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String("Lalit");
System.out.println(s.charAt(3));
System.out.println(s.charAt(20));
}}

Output:

i
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 20
at java.lang.String.charAt(String.java:658)
at langpack.Test.main(Test.java:9)

2. public void concat();

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String("Lalit");
s = s.concat(" Bizlain");
s = s + " Kumar";
s += " Biz";

System.out.println(s );
}}

Output:
Lalit Bizlain Kumar Biz

The overloaded + and += operators meant for concatenation purpose


only.

3. public boolean equals(Object o);


 To perform content comparison where case is important.
 This is overriding version of object class equals() method.

4. public boolean equalsIgnoreCase(Object o);


 To perform content comparison where case is not important.

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String("Lalit");

System.out.println(s.equals("lalit"));
System.out.println(s.equalsIgnoreCase("lalit"));
}}

Output:

false
true

Note:

In general we can use equalsIgnoreCase() method to validate usernames


where case is not important, whereas we can use equals() method to
validate password where case is important.

5. public String substring(int begin);


return substring from begin index to the end index of String.

6. public String substring(int begin, int end);

return substring from begin index to the end-1 index of String.

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String("LalitBizlain");
System.out.println(s.substring(3));
System.out.println(s.substring(3, 8));
}}

Output:

itBizlain
itBiz

7. public int length();


return number of characters present in the string

package langpack;

public class Test{


public int length();
public static void main(String[] args) {
String s = new String("LalitBizlain");

System.out.println(s.length);

Exception in thread "main" java.lang.Error: Unresolved compilation


problem: length cannot be resolved or is not a field at
langpack.Test.main(Test.java:8)

System.out.println(s.length());

12
}}
Length variable applicable for arrays but not for string objects.
Whereas length() method applicable for string objects but not for
arrays.

8. public String replace(char oldCh, char newCh)

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String("ababab");

System.out.println(s.replace('a', 'b'));
}}
Output:
bbbbbb

9. public String toLowerCase();


10. public String toUpperCase();
11. public String trim();

To remove the blank spaces present at beginning and end of the string
but not middle blank spaces.

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String(" ababab ");

System.out.println(s.trim());
}}

Output:
ababab

1. public int indexOf(char ch);


return index of first occurrence of specified character.
2. public int lastIndexOf(char ch);

package langpack;

public class Test{

public static void main(String[] args) {


String s = new String(" ababab ");

System.out.println(s.indexOf('b'));
System.out.println(s.lastIndexOf('a'));

}}

Output:
2
5

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String(" durga ");
String s2 = s1.toUpperCase();
String s3 = s1.toLowerCase();

System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));

}}

Output:
false
true
false
true

Note:
Because of run time operation if there is any change in the content
then with those changes a new object will be created in the heap.
If there is no change in the content existing object will be reused
and new object won’t be created.

heap SCP
S1
durga durga
S3

S2 DURGA

Whether the object present in heap or SCP the rule is same.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String(" durga ");
String s2 = s1.toUpperCase();
String s3 = s1.toLowerCase();
String s4 = s2.toLowerCase();
String s5 = s2.toUpperCase();

}}

heap SCP
S1
durga durga
S3

S2 DURGA

S4 durga

S5 DURGA

package langpack;
public class Test{

public static void main(String[] args) {


String s1 = " durga ";
String s2 = s1.toString();
System.out.println(s1==s2);
String s3 = s1.toLowerCase();
String s4 = s1.toUpperCase();
String s5 = s1.toLowerCase();

}}

heap SCP
S1
durga
S2

S3

S4 DURGA

S5 durga

How to create our own immutable class?

Once we create an object we can’t perform any changes in that object. If we


are trying to perform any change and if there is a change in the content then
with those changes a new object will be created. If there is no change in the
content then existing object will be reused. This behavior is nothing but
immutability.

We can create our own immutable class.

package langpack;

final public class Test{


private int i;

public Test(int i) {
this.i = i;
}

public Test modify(int i) {


if(this.i==i) {
return this;
} else {
return (new Test(i));
}

public static void main(String[] args) {


Test t1 = new Test(10);
Test t2 = t1.modify(100);
Test t3 = t1.modify(10);

System.out.println(t1==t2);
System.out.println(t1==t3);
}
}

Output:

false
true

Once we create a Test object we can’t perform any change in the existing
object. If we are trying to perform any change and if there is a change in
the content then with those changes a new object will be created and if there
is no change in the content then existing object will be reused.

Final VS immutability:
1. Final applicable for variables but not for objects whereas
immutability applicable for objects but not for variables.
2. By declaring a reference variable as final we won’t get any
immutability nature. Even though reference variable is final, we
can perform any type of change in the corresponding object but we
can’t perform re-assignment for that variable.
3. Hence final and immutable both are different concepts.

package langpack;

public class Test{

public static void main(String[] args) {


final StringBuffer sb = new StringBuffer("Lalit");
sb.append(" Bizlain");
System.out.println(sb);

sb = new StringBuffer("lalit");-----error
}
}

Output:

Lalit Bizlain

Java.lang.StringBuffer:
1. If the content is fixed and won’t change frequently then it is
recommended to go for String.
2. If the content is not fixed and keep on changing then it is not
recommended to use string because for every change a new object
will be created which effects performance of the system.
3. To handle this requirement we should go for StringBuffer.
4. The main advantage of stringbuffer over string is all required
changes will be performed in the existing object only.

Constructors of StringBuffer:
1. StringBuffer sb = new StringBuffer();

Create an empty StringBuffer object with default initial capacity 16. Once
StringBuffer reaches its max capacity, a new StringBuffer object will be
created with new capacity = (current capacity) + 1 * 2

package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb = new StringBuffer();
System.out.println(sb.capacity());
// new capacity = (old capacity + 1) * 2
sb.append("abcdefghijklop");
System.out.println(sb.capacity());
sb.append(" Bizlain");
System.out.println(sb.capacity());
sb.append(" Kumar");
System.out.println(sb.capacity());
sb.append(" Lalit lalli");
System.out.println(sb.capacity());

}
}

Output:

16
16
34
34
70

2. StringBuffer sb = new StringBuffer(int intialCapacity);

Create an empty StringBuffer object with specified intial capacity.

3. StringBuffer sb = new StringBuffer(String s);


Create an equivalent stringBuffer for the given string with

Capacity = s.legth() + 16

package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb = new StringBuffer("Lalit Bizlain");
System.out.println(sb.capacity());
// capacity = s.length() + 16
sb.append("abcdefghijklop");
System.out.println(sb.capacity());
sb.append("Bizlain");
System.out.println(sb.capacity());
sb.append("Kumar");
System.out.println(sb.capacity());
sb.append("Lalit lalli");
System.out.println(sb.capacity());

}
}

Output:

29
29
60
60
60

Important methods of StringBuffer:


1. public int length();
2. public int capacity();
3. public char charAt(int index);

package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb = new StringBuffer("Lalit Bizlain");
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.charAt(7));
System.out.println(sb.charAt(30));
}
}

Output:

13
29
i
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 30 at
java.lang.StringBuffer.charAt(StringBuffer.java:202) at
langpack.Test.main(Test.java:11)

4. public void setCharAt(int index, char ch);


To replace the character located at specified index with provided
character.

package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb = new StringBuffer("Lalit Bizlain");
sb.setCharAt(6, 'b');
System.out.println(sb);
}
}

Output:
Lalit bizlain

5. public StringBuffer append(String s);


6. public StringBuffer append(int i);
7. public StringBuffer append(char c);
8. public StringBuffer append(boolean b);
9. public StringBuffer append(long l); overloaded methods
10. public StringBuffer append(float f);
11. public StringBuffer append(double d);
12. public StringBuffer append(char[] str);
13. public StringBuffer append(StringBuffer sb);
14. public StringBuffer append(Object o);

this method always add at the end of the content.

package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb = new StringBuffer("lalit ");
sb.append("Pie value is: ");
sb.append(3.14);
sb.append(", It is: ");
sb.append(true);

System.out.println(sb);
}
}

Output:
lalit Pie value is: 3.14, It is: true

15. public StringBuffer insert(int Index, String s);


16. public StringBuffer insert(int Index, int i);
17. public StringBuffer insert(int Index, char c);
18. public StringBuffer insert(int Index, boolean b);
19. public StringBuffer insert(int Index, long l);
20. public StringBuffer insert(int Index, float f);
21. public StringBuffer insert(int Index, double d);
22. public StringBuffer insert(int Index, char[] str);
23. public StringBuffer insert(int Index, StringBuffer sb);
24. public StringBuffer insert(int Index, Object o);

package langpack;
public class Test{

public static void main(String[] args) {


StringBuffer sb = new StringBuffer("lalit bizlain ");
sb.insert(5, 123);

System.out.println(sb);
}
}

Output:

lalit123 bizlain

1. public StringBuffer delete(int begin, int end);


To delete the characters located from begin index to end-1 index.

2. public StringBuffer deleteCharAt(int index);


To delete the characters located at specified index.

3. public void reverse();

package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb = new StringBuffer("lalit bizlain ");
sb.reverse();

System.out.println(sb);
}
}

Output:

nialzib tilal

4. public void setLength(int length);

package langpack;
public class Test{
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("lalit bizlain ");
sb.setLength(8);

System.out.println(sb);
}
}

Output:
lalit bi

5. public void ensureCapacity(int capacity);


To increase capacity on fly based on our requirement.

package langpack;

public class Test{


public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
System.out.println(sb.capacity());
sb.ensureCapacity(1000);
System.out.println(sb.capacity());
}
}

Output:
16
1000

6. public void trimSize();


To deallocate extra allocated free memory.

package langpack;

public class Test{


public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
System.out.println(sb.capacity());
sb.ensureCapacity(1000);
System.out.println(sb.capacity());
sb.append("lalit");
sb.trimToSize();
System.out.println(sb.capacity());
}
}

Output:
16
1000
5

StringBuilder:

1. Every method present in StringBuffer is synchronized and


hence only one Thread is allowed to operate on StringBuffer
object at a time which may creates performance problems. To
handle this requirement SUN people introduced StringBuilder
concept in java 1.5 version.
2. StringBuilder is exactly same as StringBuffer except the
following differences:
 StringBuffer------> StringBuilder
 Synchronized------> non-snychronized

StringBuffer StringBuilder

 Every method present in  Every method present in


StringBuffer is synchronized. StringBuilder is non-
synchronized.
 At a time only one Thread is  At a time multiple Threads
allowed to operate on are allowed to operate on
StringBuffer object and hence StringBuilder object and
StringBuffer object is Thread hence StringBuilder is not
safe. Thread safe.
 Threads are required to wait  Threads are not required to
to operate on StringBuffer wait to operate on
object and hence relatively StringBuilder object and
performance is low. hence relatively performance
is high.
 StrinBuffer concept  StrinBuilder concept
introduced in java 1.0 introduced in java 1.0
version. version.

Note:
Except above differences everything is same in StringBuffer and
StringBuilder (including methods and constructors).

String v/s StringBuffer v/s StringBuilder:


1. If the content is fixed and won’t change frequently
then we should go for String.
2. If the content is not fixed and keep on changing but
Thread safety required then we should go for
StringBuffer.
3. If the content is not fixed and keep on changing but
Thread safety is not required then we should go for
StringBuilder.

Method chaining:
1. For most of the methods in String, StringBuffer and
StringBuilder return types are same type. Hence after
applying a method and result we can call another method
which forms method chaining.
2. In method chaining all method calls will be execute always
from left to right.

Sb.m1().m2().m3().m4()………………

package langpack;

public class Test{


public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("Lalit ").append("Bizlain ").append("is ").insert(2,
123).reverse().delete(2, 8);

System.out.println(sb);
}
}
Output:
sziB til321aL

Wrapper classes:
1. The main objective of wrapper classes are:
 To wrapped primitive into Object form so that we can
handle primitive also just like objects.
 To define several utility methods which are required for
the primitives.

Constructors of wrapper class:


Almost all wrapper classes contain two constructors, one can take
corresponding primitive as argument and the other can take string as
argument.

Example1:

Integer I = new Integer(10);


Integer I = new Integer("10");

Integer I = new Integer("ten");

If String argument not representing a number then we will get


RunTimeException saying NumberFormatException.

Example2:

Double d = new Double(10.5);


Double d = new Double("10.5");

Wrapper class Corresponding constructors arguments

 Byte byte or string


 Short short or string
 Integer int or string
 Long long or string
 Double double or string
 Float float or string or double
 Character char
 Boolean boolean(true,flase) 0r string
Example3:

Float class contains three constructors one can take float, double as
primitive argument and other can take string argument.

Float f = new Float (10.5f);


Float f = new Float ("10.5f");

Float f = new Float (10.5);


Float f = new Float ("10.5");

Example4:

Character class contains only one constructor which can take char argument.

Character c = new Character (‘a’);

Example5:

If we are passing string type as argument then case and content both
are not important.

If the content is case insensitive string of ‘true’ then it is treated


as true otherwise it is treated as false.

package langpack;

public class Test{


public static void main(String[] args) {
Boolean b1 = new Boolean("yes");
Boolean b2 = new Boolean("no");
Boolean b3 = new Boolean("true");
Boolean b4 = new Boolean("True");
Boolean b5 = new Boolean("TRUE");
Boolean b6 = new Boolean("false");
Boolean b7 = new Boolean("False");
Boolean b8 = new Boolean("FALSE");
Boolean b9 = new Boolean(true);
Boolean b10 = new Boolean(false);
Boolean b11 = new Boolean("Lalit");
Boolean b12 = new Boolean("Bizlain");

System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(b4);
System.out.println(b5);
System.out.println(b6);
System.out.println(b7);
System.out.println(b8);
System.out.println(b9);
System.out.println(b10);
System.out.println(b11);
System.out.println(b12);
System.out.println(b1.equals(b2));
}
}

Output:

false
false
true
true
true
false
false
false
true
false
false
false
true

Note:

 In all wrapper classes toString() method is overridden to return


content directly.
 In all wrapper classes .equals() method is overridden for content
comparison.
Utility methods of wrapper class:
 valueOf();
 xxxValue();
 parseXXX();
 toString();

1. valueOf() methods:
 We can use valueOf() methods to create wrapper object for the given
primitive or string.

a) Form1:
Every wrapper class except character class contains a
static value of method to create wrapper object for the
given string.

public static Wrapper valueOf(String s);

package langpack;

public class Test{

public static void main(String[] args) {


Integer I = Integer.valueOf("10");
Double d = Double.valueOf("10.5");
Boolean b = Boolean.valueOf("lalit");

System.out.println(I);
System.out.println(d);
System.out.println(b);
}
}

Output:

10
10.5
False
b) Form2:

Every integral type wrapper class (Byte, Short, Integer, Long) contains the
following valueOf() method to create wrapper object for the given specified
radix string.

public static Wrapper valueOf(String s, int radix);

The allowed range of radix is 2 to 36.

Radix value or base value range


 2 0 to 1
 3 0 to 2
 10 0 to 9
 11 0 to 9, a
 16 0 to 9, a to f
 36 0 to 9, a to z

package langpack;

public class Test{


public static void main(String[] args) {
Integer I1 = Integer.valueOf("100", 2);
Integer I2 = Integer.valueOf("100", 16);
Integer I3 = Integer.valueOf("100", 36);
System.out.println(I1);
System.out.println(I2);
System.out.println(I3);
}
}

Output:

4
256
1296
c) Form3:
Every wrapper class including character class contains a
static valueOf() method to create wrapper object for the
given primitive.

public static Wrapper valueOf(primitive p);

package langpack;

public class Test{


public static void main(String[] args) {
Integer i = Integer.valueOf(10);
Character c = Character.valueOf('a');
Boolean b = Boolean.valueOf(true);
System.out.println(i);
System.out.println(c);
System.out.println(b);
}
}

Output:

10
a
true

2. xxxValue() method:

 We can use xxxValue() methods to get primitive for the given


wrapper object.
 Every number type wrapper class (Byte, Short, Integer, Long,
Double, Float) contains the fill 6 methods to get primitive for
the given wrapper object.

 public byte byteValue();


 public short shortValue();
 public int intValue();
 public long longValue();
 public float floatValue();
 public double doubleValue();
package langpack;

public class Test{


public static void main(String[] args) {
Integer i = new Integer(130);
System.out.println(i.byteValue());
System.out.println(i.shortValue());
System.out.println(i.intValue());
System.out.println(i.longValue());
System.out.println(i.floatValue());
System.out.println(i.doubleValue());

}
}

Output:
-126
130
130
130
130.0
130.0

 character class contains charValue() method to get char primitive


for the given character object.

 public char charValue();

package langpack;

public class Test{


public static void main(String[] args) {
Character ch = new Character('a');
System.out.println(ch.charValue());

}
}

Output:
a
 Boolean class contains booleanValue() method to get boolean
primitive for the given Boolean object.

 public boolean booleanValue();

package langpack;

public class Test{


public static void main(String[] args) {
Boolean b = new Boolean("lalit");
System.out.println(b.booleanValue());

}
}

Output:

false

3. parseXXX() method:
 we can use parseXXX() methods to covert string to primitive.

a) Form1:
Every wrapper class except character class contains the following
parseXXX() method to find primitive for the given String object.

public static primitive parseXXX(String s);

package langpack;

public class Test{

public static void main(String[] args) {


int i = Integer.parseInt("10");
double d = Double.parseDouble("10.5");
boolean b = Boolean.parseBoolean("true");

System.out.println(i);
System.out.println(d);
System.out.println(b);

}
}
Output:
10
10.5
true

b) Forme2:
Every integral type wrapper class (Byte, Short, Integer, Long)
contains the following parseXXX() method to convert specified radix
string to primitive.

public static primitive parseXXX(String s, int radix);

package langpack;

public class Test{

public static void main(String[] args) {


int i = Integer.parseInt("100", 25);

System.out.println(i);

}
}

Output:

625

4. toString() method:
 we can use toString() method to convert wrapper object or primitive to
String.
1. Form1:

Every wrapper class contains the following toString() method to convert


wrapper object to string type.

public String toString();

 It is the overriding version object class toString() method.


 Whenever we are trying wrapper object reference internally this
toString() method will be called.
package langpack;

public class Test{

public static void main(String[] args) {


Integer I = new Integer(10);
String s = I.toString();
System.out.println(s);
System.out.println(I); //syso(I.toString());

}
}

Output:

10
10

2. Form2:

Every wrapper class including character class the following static


toString() method to convert primitive to string.

public static String toString(primitive p);

package langpack;

public class Test{

public static void main(String[] args) {

String s1 = Integer.toString(10);
String s2 = Double.toString(10.5);
String s3 = Boolean.toString(true);
String s4 = Character.toString('a');

System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);

}
}
Output:

10
10.5
true
a

3. Form3:

Integer and Long classes contains the following toString() method to convert
primitive to specified radix string.

public static String toString(primitive p, int radix);

package langpack;

public class Test{

public static void main(String[] args) {

String s1 = Integer.toString(15, 2);


System.out.println(s1);

}
}

Output:

1111

4. Form4: toXXXString() method:

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);

package langpack;
public class Test{

public static void main(String[] args) {

String s1 = Integer.toBinaryString(15);
String s2 = Integer.toOctalString(15);
String s3 = Integer.toHexString(15);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);

}
}

Output:

1111
17
f

String

toString() valueOf() parseXXX()

toSting()

valueOf()

Wrapper object primitve value


xxxValueOf()

partial hierarchy of java.lang package:


y
I
L
F
D
m
N
l
a
h
C
d
o
v
c
j
b
O
S
e
f
u
B
g
n
i
r
t
Conclusion:

 The wrapper classes which are not child class of Number are Boolean and
character.
 The wrapper classes which are direct child class of Object are Byte,
Short, Integer, Long, Float, Double.
 String, StringBuffer, StringBuilder and all wrapper classes are final
classes.
 In addition string to objects all wrapper class objects also immutable.
 Sometimes void class is also considered as wrapper class.

Void class:

1. It is a final class and it is the direct child class of


object class.
2. It doesn’t contain any methods and it contains only one
variable Void.Type.
3. In general we can use Void class in reflections to check
whether the method return type is void or not.

If(getMethod(m1).getReturnType()==Void.Type)
Autoboxing:
1. Automatic conversion primitive to wrapper object by compiler is called
autoboxing.

Example: Integer I = 10;----compiler converts int to Integer automatically by


autoboxing.

2. After compilation the above line become Integer I =


Integer.valueOf(10);---internally autoboxing concept is implemented by
using valueOf() methods.

Autounboxing:
1. Automatic conversion wrapper object to primitive by compiler is called
autounboxing.

Integer I = new Integer(10);


Int i = I;----compiler convert Integer to int automatically by
autounboxing.
2. After compilation the above line will become

Int i = I.intValue();---internally autounboxing concept is implemented


by using xxxValue() methods.

Autoboxing[valueOf()]

Primitive value wrapper object

Autounboxing[xxxValue()]

package langpack;
public class Test{

static Integer I = 10; // int to Integer object (primitive type


to wrapper object) autoboxing

public static void m1(Integer k) {// int to Integer object


(primitive type to wrapper object) autoboxing
int m = k; // Integer object to int (wrapper object to
primitive type) autounboxing
System.out.println(m);
}
public static void main(String[] args) {
int i = I; // Integer object to int (wrapper object to
primitive type) autounboxing
m1(i);

}
}

Output:
10

package langpack;

public class Test{

static Integer I = 0;

public static void main(String[] args) {


int i = I;
System.out.println(i);

}
}
Output:
0

package langpack;
public class Test{

static Integer I; //null

public static void main(String[] args) {


int i = I;
System.out.println(i);

}
}

Output:

Exception in thread "main" java.lang.NullPointerException


at langpack.Test.main(Test.java:8)

package langpack;

public class Test{

public static void main(String[] args) {


Integer x = 10;
Integer y = x;

x++;

System.out.println(x);
System.out.println(y);
System.out.println(x==y);

}
}

Output:
11
10
false

All wrapper class objects are immutable i.e once we create wrapper
class object we can’t perform any changes that object. If we are
trying to perform any changes with those changes a new object will be
created.
10
x
10
y
11

package langpack;

public class Test{

public static void main(String[] args) {


Integer x = new Integer(10);---x = 10(object created by new)
Integer y = new Integer(10);---y = 10(object created by new)
Integer x1 = new Integer(10);---x1 = 10(object created by new)
Integer y1 = 10;---y1 = 10(object created by autoboxing)
Integer x2 = 10;--x2 = 10(object created by autoboxing)
Integer y2 = 10;--y2 = 10(object created by autoboxing)
Integer x3 = 100;-x3 = 100(object created by autoboxing)
Integer y3 = 100;-y3 = 100(object created by autoboxing)
Integer x4 = 1000;-x4 = 10(object created by autoboxing)
Integer y4 = 1000;-y4 = 10(object created by autoboxing)

System.out.println(x==y);
System.out.println(x1==y1);
System.out.println(x2==y2);
System.out.println(x3==y3);
System.out.println(x4==y4);

}
}

Output:

false
false
true
true
false

conclusion:
1. Internally to provide support for autoboxing a buffer of wrapper
objects will be created at the time of wrapper class loading.
2. By autoboxing if an object is required to create, 1 st JVM will check
whether this object already present in buufer or not.
3. If it is already present in buffer then existing buffer object will be
used.
4. If it is not already available in the buffer then JVM will create a new
object.

Class integer{

Static{

-128 -127 -126 -10 1 10 100 110 126 127

X y x1 y1
}
}

But buffer concept is available only in the following ranges:


 Byte always
 Short -128 to 127
 Integer -128 to 127
 Long -128 to 127
 Character 0 to 127
 Boolean always

Except this range in all remaining cases a new object will be created.

package langpack;

public class Test{

public static void main(String[] args) {


Integer x1 = 127;
Integer y1 = 127;
Integer x2 = 128;
Integer y2 = 128;
Boolean x3 = false;
Boolean y3 = false;
Double x4 = 10.0;
Double y4 = 10.0;

System.out.println(x1==y1);
System.out.println(x2==y2);
System.out.println(x3==y3);
System.out.println(x4==y4);

}
}

Output:

true
false
true
false

Internally autoboxing concept is implemented by using valueOf() methods.


Hence buffer concept is applicable valueOf() methods also.

package langpack;

public class Test{

public static void main(String[] args) {


Integer x1 = new Integer(10);
Integer y1 = new Integer(10);
Integer x2 = 10;
Integer y2 = 10;
Integer x3 = Integer.valueOf(10);
Integer y3 = Integer.valueOf(10);
Integer x4 = 10;
Integer y4 = Integer.valueOf(10);

System.out.println(x1==y1);
System.out.println(x2==y2);
System.out.println(x3==y3);
System.out.println(x4==y4);

}
}

Output:
false
true
true
true
Overloading with respect to Autoboxing,
widening and var-arg methods:
Case1: autoboxing v/s widening:

package langpack;

public class Test{

public static void m1(Integer I) {


System.out.println("Autoboxing");
}

public static void m1(long l) {


System.out.println("widening");
}

public static void main(String[] args) {


int i =10;
m1(i);
}
}

Output:
Widening

Widening dominates autoboxing because widening concept(primitive to primitive


conversion) came in java 1.0 version but autoboxing concept came in java 1.5
version.

Case2: widening v/s var-arg method:

package langpack;

public class Test{

public static void m1(int...x) {


System.out.println("var-arg method");
}

public static void m1(long l) {


System.out.println("widening");
}

public static void main(String[] args) {


int i =10;
m1(i);
}
}

Output:
Widening

Widening dominates var-arg method because widening concept(primitive to


primitive conversion) came in java 1.0 version but var-arg method concept
came in java 1.5 version.

Case3: autoboxing v/s var-arg method:

package langpack;

public class Test{

public static void m1(int...x) {


System.out.println("var-arg method");
}

public static void m1(Integer I) {


System.out.println("Autoboxing");
}

public static void main(String[] args) {


int i =10;
m1(i);
}
}

Output:
Autoboxing

Autoboxing dominates var-arg method.


In general var-arg method will get least priority i.e if no other method
matched then only var-arg method will get the chance. It is exactly same as
default case inside switch.

Note:

While resolving overloaded methods, compiler always gives the priority in the
following order:
1. Widening
2. Autoboxing
3. Var-arg methods

Case4:
package langpack;

public class Test{

public static void m1(Long l) {


System.out.println("Long");
}

public static void main(String[] args) {


int i =10;
m1(i);----------------------error
}
}

Output:

Compile time error: Exception in thread "main" java.lang.Error:


Unresolved compilation problem: The method m1(Long) in the type Test
is not applicable for the arguments (int) at
langpack.Test.main(Test.java:12)

(Autoboxing) Integer (no widening in java for wrapper object to


wrapper object)
Int Long
(Widening) (autoboxing)
long

 Widening followed by autoboxing is not allowed in java. But Autoboxing


followed by widening is allowed in java.

Case5:

package langpack;

public class Test{

public static void m1(Long l) {


System.out.println("Long");
}

public static void main(String[] args) {


Long L =10;------------error
m1(i);-----------------error
}
}

Output:

Compile time error:

Exception in thread "main" java.lang.Error: Unresolved compilation


problems: Type mismatch: cannot convert from int to Long i cannot be
resolved to a variable
at langpack.Test.main(Test.java:11)

 Int type primitive is only allowed to Integer type wrapper object in


autoboxing concept but not in Long type wrapper object.

Case6:

package langpack;

public class Test{

public static void m1(Long l) {


System.out.println("Long");
}

public static void main(String[] args) {


long l =10;
m1(l);
}
}

Output:

Long

 Int type primitive is allowed to convert internally in long type


primitive in widening concept.

Case7:
package langpack;

public class Test{

public static void m1(Object o) {


System.out.println("Object version");
}

public static void main(String[] args) {


int i =10;
long l = 10;
m1(i);
m1(l);
}
}

Output:
Object version
Object version

Autoboxing widening

Int Integer Object

Case8:

package langpack;

public class Test{

public static void m1(Number n) {


System.out.println("Number version");
}

public static void main(String[] args) {


int i =10;
long l = 10;
m1(i);
m1(l);
}
}
Output:
Number version
Number version

Autoboxing widening

Int Number Object

Relation between (==) operator and .equals() method:


1. If two objects are by (==) operator then these objects are always equal
by .equals() method.
Example:

If r1==r2 is true then r1.equals(r2) is always true.

r1

lalit

r2

 (==) operator comparison based on reference type, i.e if two different


reference pointing towards same object then it gives true.
 If we compare both those references which are pointing towards same
object on the based of .equals() method then it will give true
because .equals() overridden method compare on the based of content.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
String s2 = s1;

System.out.println(s1==s2);
System.out.println(s1.equals(s2));
}
} outpue:
true
true
2. If two objects are not equal by (==) operator then we can’t conclude
anything about .equals() method. It may returns true or false, i.e

If r1==r2 is false then r1.equals(r2) may returns or false and we can’t


expect exactly.

 (==) operator comparison based on reference type, i.e if two different


reference pointing towards different object and then we are comparing
both object then it gives us false, even though content is same of both
object.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
String s2 = new String ("lalit");

System.out.println(s1==s2);
}
}
Output:
False

 If we compare both those references which are pointing towards


different object on the based of .equals() method then it will give
true if content is same because .equals() overridden method compare on
the based of content and it will give false if content is different.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
String s2 = new String ("lalit");

System.out.println(s1==s2);
System.out.println(s1.equals(s2));
}
}

Output:
false
true

3. If two objects are equal by .equals() method then we can’t conclude


anything about (==) operator. It may returns true or false, i.e

If r1.equals(r2) is true then we can’t conclude anything about r1==r2.


It may returns true or false.

 If both references pointing towards different objects but content in


both objects are same then r1.equals(r2) method gives us true and if
content is different in both object then r1.equals(r2) gives us false
because .equals() overridden method compare on the based of content. In
this case if we compare r1 and r2 on the based of (==) operator then it
gives us false because (==) operator compare the objects based on
reference type not content type.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
String s2 = new String("lalit");

System.out.println(s1.equals(s2));
System.out.println(s1==s2);

}
}

Output:

True
False

 If both references pointing towards same object then r1.equals(r2)


method gives us true because .equals() overridden method compare on the
based of content. In this case if we compare r1 and r2 on the based of
(==) operator then it gives us true because (==) operator compare the
objects based on reference type not content type.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
String s2 = s1;

System.out.println(s1.equals(s2));
System.out.println(s1==s2);

}
}

Output:

True
True

4. If two objects are not equal by .equals() method then these objects are
always not equal by (==) operator.
If r1.equals(r2) is false then r1==r2 is always false.

 If both references pointing towards different objects but content in


both objects are different then r1.equals(r2) method gives us true and
if content is different in both object then r1.equals(r2) gives us
false because .equals() overridden method compare on the based of
content. In this case if we compare r1 and r2 on the based of (==)
operator then it gives us false because (==) operator compare the
objects based on reference type not content type.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
String s2 = new String("bizlain");

System.out.println(s1.equals(s2));
System.out.println(s1==s2);
}
}

Output:

False
False

 To use (==) operator, compulsory there should be some relation between


argument types (either child to parent or parent to child or same
type), otherwise we will get compile time error saying incomparable
types.
 If there is no relation between argument types then .equals() method
won’t raise any compile time or run time errors. Simply it returns
false.

 If argument type is different and content is same then .equals() method


gives false.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
StringBuffer s2 = new StringBuffer("bizlain");

System.out.println(s1.equals(s2));
// System.out.println(s1==s2);

}
}

Output:

False
 If argument type is different and content is different then .equals()
method gives false.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
StringBuffer s2 = new StringBuffer("lalit");

System.out.println(s1.equals(s2));
// System.out.println(s1==s2);

}
}

Output:

False

 If argument type is different and content is different/same then (==)


operator always give compile time or run time error.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("lalit");
StringBuffer s2 = new StringBuffer("lalit");

// System.out.println(s1.equals(s2));
System.out.println(s1==s2);

}
}

Output: Exception in thread "main" java.lang.Error: Unresolved


compilation problem: Incompatible operand types String and
StringBuffer
at langpack.Test.main(Test.java:11)

(==) operator .equals() method


 It is an operator in java  It is a method applicable only for object
applicable for both primitive types.
and object types.
package langpack;
package langpack;
public class Test{
public class Test{

public static void main(String[] args) {


public static void main(String[] String s1 = new String("lalit");
args) { String s2 = new String("bizlain");
String s1 = new String("lalit");
String s2 = new String("bizlain"); String s3 = new String("lalit");

String s3 = new String("lalit");


System.out.println(s1.equals(s2));
int i1 = 10; System.out.println(s1.equals(s3));
int i2 = 20; System.out.println(s2.equals(s3));
int i3 = 10;
}
}
System.out.println(s1==s2);
System.out.println(i1==i2); Output:
System.out.println(s1==s3);
System.out.println(i1==i3); false
true
} false
}

Output:

false
false
false
true

 In the case of object  By default .equals() method present in


references (==) operator meant object class also meant for reference
for reference comparison comparison.
(address comparison).
 We can’t override (==) operator  We can override .equals() method for
for content comparison. content comparison.
 To use (==) operator compulsory  If there is no relation between argument
there should be some relation types then .equals() method won’t raise
between argument types (either any compile time or run time errors and
child to parent or parent to simply returns false.
child or same type), otherwise
we will get compile time error
saying incomparable types.

Answer in one line for interview:

In general we can use (==) operator for reference comparison and .equals()
method for content comparison.

Note:

For any object reference or (r==null, r.equals(null)) always returns false.

Example:

package langpack;

public class Test{

public static void main(String[] args) {


Thread t = new Thread();
System.out.println(t==null);
System.out.println(t.equals(null));

}
}

Output:

false
false

hashCode() method:
Hashing related data structure follows the following fundamental rule:

 To equivalent objects should be placed in same bucket but all objects


present in the same bucket need not be equal.

Contract between .equals() method and


hashCode() method:
 If two objects are equal by .equals() method then there hash code must
be equal, i.e two equivalent objects should have same hash code,
i.e If r1.equals(r2) is true the r1.hashCode()==r2.hashCode() is always
true.
 Object class .equals() method and hashCode() method follows above
contract. Hence whenever we are overriding .equals() method, compulsory
we should override hashCode() method to satisfy above contract (i.e two
equivalent objects should have same hash code).
 If two objects are not equal by .equals() method then there is no
restriction on hash codes may be equal or may not be equal.
 If hash codes of two objects are equal then we can’t conclude anything
about .equals() method. It may returns true or false.
 If hash codes of two objects are not equal then these objects are
always not equal by .equals() method.
 To satisfy contract between equals() and hashCode() method, whenever we
are overriding .equals() method, compulsory we have to override
hashCode() method, otherwise we won’t get any compile time or run time
errors but it is not a good programming practice.
 In String class .equals() method is overridden for content comparison
and hence hashCode() method is also overridden to generate hash code
based on content.

package langpack;

public class Test{

public static void main(String[] args) {


String s1 = new String("Lalit");
String s2 = new String("Lalit");

System.out.println(s1.equals(s2));
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
}
}

Output:

true
73184482
73184482

 In StringBuffer class .equals() method is not overridden for content


comparison and hence hashCode() method is not also overridden.
package langpack;

public class Test{

public static void main(String[] args) {


StringBuffer sb1 = new StringBuffer("Lalit");
StringBuffer sb2 = new StringBuffer("Lalit");

System.out.println(sb1.equals(sb2));
System.out.println(sb1.hashCode());
System.out.println(sb2.hashCode());
}
}

Output:

false
366712642
1829164700

Consider the following Person class:

package langpack;

public class Person{


String name;
int age;

public Person(String name, int age){


this.name = name;
this.age = age;
}

public boolean equals(Object obj) {


if(obj instanceof Person) {
Person p = (Person)obj;

if(name.equals(p.name) && age==p.age) {


return true;
} else {
return false;
}
} else {
return false;
}
}

public int hashCode() {


return name.hashCode() + age;
}

public static void main(String[] args) {


Person p1 = new Person("lalit", 27);
Person p2 = new Person("lalit", 27);
System.out.println( p1.equals(p2));
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());

}
}

Output:

true
102737181
102737181

What could be hashCode() method for Person class:


 public int hashCode() {
return 100;
}

 public int hashCode() {


return age + security number;
}

 public int hashCode() {


return name.hashCode() + age;
}

Clone() method:
1. The process of creating exactly duplicate object is called cloning.
2. The main purpose of cloning is to maintain backup copy and to preserve
state of an object.
3. We can perform cloning bys using clone() method of object class.

protected native Object clone() throws CloneNotSupportedException

package langpack;

public class Test implements Cloneable {

int i = 20;
int j = 10;

public static void main(String[] args) throws


CloneNotSupportedException {
Test t1 = new Test();
Test t2 = (Test) t1.clone();

t2.i = 222;
t2.j = 333;

System.out.println(t1.i + " " + t1.j);


System.out.println(t2.i + " " + t2.j);
}

Output:

20 10
222 333

 We can perform cloning only for cloneable objects. An object is said to


be cloneable if and if only corresponding class implement cloneable
interface.
 Cloneable interface present in java.lang package and it doesn’t contain
any methods. It is a marker interface.
 If we are trying to perform cloning for non-cloneable objects then we
will get run time exception saying cloneNotSupportedException.

Shallow cloning Deep cloning


i = 20; i = 20;
i = 20;

c c
j = 10 ; j = 10;
c c
j = 10 ; j = 10;

d1 d2

d1 d2

Dog d2 = (Dog)d1.clone(); Dog d2 = (Dog)d1.clone();

 The process of creating Bit-wise copy of  The process of creatin


an object is called shallow cloning. exactly duplicate
independent property
including contained object
is called deep cloning.
 If the main object contain primitive  In deep cloning if the main
variables then exactly duplicate copies object contained any
will be created in the cloned object. primitive variables then in
the cloned object duplicate
copies will be created.
 If the main object any reference  If the main object contain
variable then corresponding object won’t any reference variable then
be created just duplicate reference the corresponding contained
variable will be created pointing old objects also will be created
content object. in the cloned copy.
 Object class clone() method meant for  By default object class
shallow cloning. clone method meant for
shallow cloning. But we can
implement deep cloning
explicitly by overriding
clone() method in our class.
package langpack; package langpack;

public class Cat { public class Cat {


int i; int i;
public Cat(int i) { public Cat(int i) {
this.i = i; this.i = i;
} }
} }
package langpack;
package langpack;
public class Dog {
public class Dog { Cat c;
Cat c; int j;
int j;
public Dog(Cat c, int j) {
public Dog(Cat c, int j) { this.c = c;
this.c = c; this.j = j;
this.j = j; }
}
public Object clone() throws
public Object clone() throws CloneNotSupportedException{
CloneNotSupportedException{ Cat c1 = new Cat(c.i);
return super.clone(); Dog d2 = new Dog(c1, j);
}
} return d2;

package langpack; }
}
public class ShallowCloning {
package langpack;
public static void main(String[] args)
throws CloneNotSupportedException { public class DeepCloning {
Cat c = new Cat(10);
Dog d1 = new Dog(c, 20); public static void
main(String[] args) throws
System.out.println(d1.j + " " + d1.c.i); CloneNotSupportedException {
Cat c = new Cat(10);
Dog d2 = (Dog)d1.clone(); Dog d1 = new Dog(c,
20);
d2.j = 888;
d2.c.i = 999; System.out.println(d1.j +
" " + d1.c.i);
System.out.println(d1.j + " " + d1.c.i); Dog d2 =
(Dog)d1.clone();
System.out.println(d2.j + " " + d2.c.i); d2.j = 888;
} d2.c.i = 999;
} System.out.println(d1.j +
" " + d1.c.i);

System.out.println(d2.j +
" " + d2.c.i);
}
Output:
}
20 10
Exception in thread "main" Output:
java.lang.CloneNotSupportedException:
langpack.Dog 20 10
at java.lang.Object.clone(Native Method) 20 10
at langpack.Dog.clone(Dog.java:13) 888 999
at
langpack.ShallowCloning.main(ShallowClonin
g.java:9)

 In shallow cloning by using cloned  By using cloned object


object reference if we perform any reference if we perform any
change to the contented object then change to the contained
those changes will be reflected to the object then those changes
main object. won’t be reflected to the
 To overcome this problem we should go main object.
for deep cloning.

Note: which cloning is best?

 If object contains only primitive variables then shallow cloning is the


best choice.
 If object contains reference variables then deep cloning is the best
choice.

package langpack;

public class Test {

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);

String s3 = "you cannot change me";


System.out.println(s1==s3);

String s4 = "you cannot change me";


System.out.println(s3==s4);

String s5 = "you cannot " + "change me";


System.out.println(s3==s5);
// this operation will be performed at compile time because both
arguments are compile time constant

String s6 = "you cannot ";


String s7 = s6 + "change me";
System.out.println(s3==s7);
//if at least one variable is adding in constant value then at run
time object will create in heap are not in SCP area

final String s8 = "you cannot ";


String s9 = s8 + "change me";
System.out.println(s3==s9);
// if String any variable is final then it treated as constant. if we
are adding it with constant value then both constant value add and
become one constant value and object will create in SCP area at
compile time but not in heap area at run time

System.out.println(s6==s8);
}
}

Output:

false
false
true
true
false
true
true

heap SCP
S3 You cannot change me
S1 You cannot change me S4
S5 s9

S2 You cannot change me Change me

Constant value without reference

S3 You cannot change me You cannot

S6 s8

Interning of String ojects:


 We can use intern() method to get corresponding SCP object reference by
using heap object reference.
 By using heap object reference if we want to get corresponding SCP
object reference then we should go for intern() method.

package langpack;

public class Test {

public static void main(String[] args) {

String s1 = new String("lalit");


String s2 = s1.intern();
System.out.println(s1==s2);

String s3 = "lalit";
System.out.println(s2==s3);

}
}

Output:

false
true

heap SCP

S1 lalit S2 lalit
S3

 If the corresponding SCP object is not available then intern() method


itself will create the corresponding SCP object.

package langpack;

public class Test {

public static void main(String[] args) {

String s1 = new String("lalit");


String s2 = s1.concat("bizlain");
String s3 = s2.intern();
System.out.println(s2);
System.out.println(s3);
System.out.println(s1==s2);

String s4 = "lalitbizlain";
System.out.println(s3==s4);

System.out.println(s2==s3);

String s5 = new String("lalitbizlain");


System.out.println(s2==s5);

}
}

Output:

lalitbizlain
lalitbizlain
false
true
true (false aana chahiye)
false

Heap SCP

S1 lalit lalit

S2 lalitbizlain bizlain

S3 lalitbizlain

S4

S5 lalitbizlain

Importance of string constant pool (SCP):


 In our program if a string object repeatedly required then it not
recommended to create a separate object because creates performance and
memory problems.
 Instead of creating a separate object for every requirement we have to
create only one object and we can reuse the same object for every
requirement. So that performance and memory utilization will be
improved.
 This thing is possible because of SCP. Hence the main advantages of SCP
are memory utilization and performance will be improved.
 But the main problem with SCP is, as several references pointing to the
same object, by using one reference if we are trying to change the
content then remaining references will be effected.
 To overcome this problem SUN People implemented string objects as
immutable, i.e once we create a string object we can’t perfrom any
changes in the existing object. If we are trying to perfrom any changes
with those changes a new object will be created.
 Hence SCP is the only reason for immutability of string objects.

Questions:

1. What is the difference between String and StringBuffer?


2. Explain about immutability and mutability with an example.
3. What is difference between
 String s1 = new String(“durga”);
 String s1 = “durga”;
4. Other than immutability and mutability, is any other difference between
String and StringBuffer?
In String .equals() method compare based on content but in StringBuffer based
on reference.
5. What is SCP?
6. What is advantage of SCP?
7. What is the disadvantage of SCP?
8. Why SCP like concept is available only for String but not for
StringBuffer?

Answer:
String is the most commonly object and hence SUN People provided
special memory management for String objects but strinBuffer is not commonly
used object and hence special memory management is not required for
StringBuffer.

9. Why String objects are immutable where as StringBuffer objects are


mutable?
Answer:
 In the case of string because SCP a single object can be
referenced by multiple references.
 By suing one reference if we are allowed to change the content in
the existing object then remaining references will be effected.
 To overcome this problem SUN People implemented String objects as
immutable.
 According to this once we create a string object we can’t perform
any changes in the existing object. If we are trying to perfrom
any changes with those changes a new object will be created.

 But in StringBuffer there is no concept like SCP. Hence for every


requirement a separate object will be created.

 By using one reference if we are trying to change in the content


then there is no effect on remaining references. Hence
immutability concept not required for the StringBuffer.

10. In addition to String objects, any other objects are immutable in


java?
Answer:
All wrapper class objects also immutable.

11. Is it possible to create our own immutable class?


12. How to create our own immutable class? Explain with an example.
13. Immutable means non-changeable where as final means also non-
changeable. Then what is the difference between immutable and final?

You might also like