UNIT 1
UNIT 1
In 1994, four authors Erich Gamma, Richard Helm, Ralph Johnson and
John Vlissides published a book titled Design Patterns - Elements of
Reusable Object-Oriented Software which initiated the concept of Design
Pattern in Software development.
Design patterns provide a standard terminology and are specific to particular scenario.
For example, a singleton design pattern signifies use of single object so all developers familiar
with single design pattern will make use of single object and they can tell each other that
program is following a singleton pattern.
Best Practices
Design patterns have been evolved over a long period of time and they
provide best solutions to certain problems faced during software
development. Learning these patterns helps unexperienced developers to
learn software design in an easy and faster way.
Advantage of design pattern
In core java, there are mainly three types of design patterns, which are
further divided into their sub-parts:
Singleton Pattern
Prototype Pattern
Builder Pattern
When the parent classes choose the creation of objects to its sub-
classes.
We are going to create a Plan abstract class and concrete classes that
extends the Plan abstract class. A factory class GetPlanFactory is
defined as a next step.
The clients can get new objects without knowing which type of object it
will be.
It lets you add or remove objects at runtime.
Usage of Prototype Pattern
File: EmployeeRecord.java
class EmployeeRecord implements Prototype{
private int id;
private String name, designation;
private double salary;
private String address;
public EmployeeRecord(){
System.out.println(" Employee Records of Oracle Corporation ");
System.out.println("---------------------------------------------");
System.out.println("Eid"+"\t"+"Ename"+"\t"+"Edesignation"+"\
t"+"Esalary"+"\t\t"+"Eaddress");
}
public EmployeeRecord(int id, String name, String designation, double s
alary, String address) {
this();
this.id = id;
this.name = name;
this.designation = designation;
this.salary = salary;
this.address = address; }
public void showRecord(){
System.out.println(id+"\t"+name+"\t"+designation+"\t"+salary+"\
t"+address); }
@Override
public Prototype getClone() {
return new EmployeeRecord(id,name,designation,salary,addre
ss);
}
}//End of EmployeeRecord class.
File: PrototypeDemo.java
Import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
Class PrototypeDemo{
public static void main(String[] args) throws IOException {
BufferedReader br =new BufferedReader(new InputStreamReader(System
.in)); System.out.print("Enter Employee Id: ");
int eid=Integer.parseInt(br.readLine());
System.out.print("\n");
System.out.print("Enter Employee Name: ");
String ename=br.readLine();
System.out.print("\n");
System.out.print("Enter Employee Designation: ");
String edesignation=br.readLine();
System.out.print("\n");
System.out.print("Enter Employee Address: ");
String eaddress=br.readLine();
System.out.print("\n");
System.out.print("Enter Employee Salary: ");
double esalary= Double.parseDouble(br.readLine());
System.out.print("\n");
EmployeeRecord e1=new EmployeeRecord(eid,ename,edesignation,esala
ry,eaddress);
e1.showRecord();
System.out.println("\n");
EmployeeRecord e2=(EmployeeRecord) e1.getClone();
e2.showRecord();
} }//End of the ProtoypeDemo class.
Output:
Static factory method: This provides the global point of access to the
Singleton object and returns the instance to the caller.
Understanding early Instantiation of Singleton Pattern
class A
{
private static A obj=new A();//Early, instance will be created at load time
private A(){}
public static A getA(){
return obj;
}
public void doSomething(){
//write your code
} }
Understanding lazy Instantiation of Singleton Pattern
{
private static A obj;
private A(){}
public static A getA(){
if (obj == null){
synchronized(Singleton.class){
if (obj == null){
obj = new Singleton();//instance will be created at request time
}
}
}
return obj;
}
public void doSomething(){
//write your code
} }
Significance of Serialization in Singleton Pattern
File: JDBCSingleton.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
class JDBCSingleton {
//Step 1
// create a JDBCSingleton class.
//static member holds only one instance of the JDBCSingleton class.
private static JDBCSingleton jdbc;
//JDBCSingleton prevents the instantiation from any other class.
private JDBCSingleton() { }
//Now we are providing gloabal point of access.
public static JDBCSingleton getInstance() {
if (jdbc==null)
{
jdbc=new JDBCSingleton();
}
return jdbc;
}
// to get the connection from methods like insert, view etc.
private static Connection getConnection()throws ClassNotFoundExcept
ion, SQLException
{
Connection con=null;
Class.forName("com.mysql.jdbc.Driver");
con= DriverManager.getConnection("jdbc:mysql://localhost:3306/
ashwanirajput", "root", "ashwani");
return con;
}
//to insert the record into the database
public int insert(String name, String pass) throws SQLException
{
Connection c=null;
PreparedStatement ps=null;
int recordCounter=0;
try {
c=this.getConnection();
ps=c.prepareStatement("insert into userdata(uname,upasswor
d)values(?,?)");
ps.setString(1, name);
ps.setString(2, pass);
recordCounter=ps.executeUpdate();
} catch (Exception e) { e.printStackTrace(); } finally{
if (ps!=null){
ps.close();
}if(c!=null){
c.close();
} }
return recordCounter;
}
//to view the data from the database
public void view(String name) throws SQLException
{ Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try { con=this.getConnection();
ps=con.prepareStatement("select * from userdata where una
me=?");
ps.setString(1, name);
rs=ps.executeQuery();
while (rs.next()) {
System.out.println("Name= "+rs.getString(2)+"\t"+"Paasword= "+rs.get
String(3)); }
} catch (Exception e) { System.out.println(e);}
finally{
if(rs!=null){
rs.close();
}if (ps!=null){
ps.close();
}if(con!=null){
con.close();
} } }
// to update the password for the given username
public int update(String name, String password) throws SQLException {
Connection c=null;
PreparedStatement ps=null;
int recordCounter=0;
try {
c=this.getConnection();
ps=c.prepareStatement(" update userdata set upassword=? w
here uname='"+name+"' ");
ps.setString(1, password);
recordCounter=ps.executeUpdate();
} catch (Exception e) { e.printStackTrace(); } finally{
if (ps!=null){
ps.close();
}if(c!=null){
c.close();
}
}
return recordCounter;
}
// to delete the data from the database
public int delete(int userid) throws SQLException{
Connection c=null;
PreparedStatement ps=null;
int recordCounter=0;
try {
c=this.getConnection();
ps=c.prepareStatement(" delete from userdata where uid='"+
userid+"' "); recordCounter=ps.executeUpdate();
} catch (Exception e) { e.printStackTrace(); }
finally{
if (ps!=null){
ps.close();
}if(c!=null){
c.close();
}
}
return recordCounter;
} }// End of JDBCSingleton class
File: JDBCSingletonDemo.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
class JDBCSingletonDemo{
static int count=1;
static int choice;
public static void main(String[] args) throws IOException {
JDBCSingleton jdbc= JDBCSingleton.getInstance();
BufferedReader br=new BufferedReader(new InputStreamReader(Syste
m.in));
do{
System.out.println("DATABASE OPERATIONS");
System.out.println(" --------------------- ");
System.out.println(" 1. Insertion ");
System.out.println(" 2. View ");
System.out.println(" 3. Delete ");
System.out.println(" 4. Update ");
System.out.println(" 5. Exit ");
System.out.print("\n");
System.out.print("Please enter the choice what you want to perform in t
he database: ");
choice=Integer.parseInt(br.readLine());
switch(choice) {
case 1:{
System.out.print("Enter the username you want to insert data in
to the database: ");
String username=br.readLine();
System.out.print("Enter the password you want to insert data int
o the database: ");
String password=br.readLine();
try {
int i= jdbc.insert(username, password);
if (i>0) {
System.out.println((count++) + " Data has been inserted suc
cessfully");
}else{
System.out.println("Data has not been inserted ");
}
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Press Enter key to continue...");
System.in.read();
}//End of case 1
break;
case 2:{
System.out.print("Enter the username : ");
String username=br.readLine();
try {
jdbc.view(username);
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Press Enter key to continue...");
System.in.read();
}//End of case 2
break;
case 3:{
System.out.print("Enter the userid, you want to delete: ");
int userid=Integer.parseInt(br.readLine());
try {
int i= jdbc.delete(userid);
if (i>0) {
System.out.println((count++) + " Data has been deleted su
ccessfully");
}else{
System.out.println("Data has not been deleted");
}
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Press Enter key to continue...");
System.in.read();
}//End of case 3
break;
case 4:{
System.out.print("Enter the username, you want to update: ");
String username=br.readLine();
System.out.print("Enter the new password ");
String password=br.readLine();
try {
int i= jdbc.update(username, password);
if (i>0) {
System.out.println((count++) + " Data has been updated suc
cessfully );
}
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Press Enter key to continue...");
System.in.read();
}// end of case 4
break;
default:
return;
}
} while (choice!=4); } }
output:
1.1.6 ADAPTER PATTERN
An Adapter Pattern says that just "converts the interface of a class into
another interface that a client wants".In other words, to provide the interface
according to client requirement while using the services of a class with a
different interface.The Adapter Pattern is also known as Wrapper.
Advantage of Adapter Pattern
It is used:
When an object needs to utilize an existing class with an incompatible
interface.
When you want to create a reusable class that cooperates with classes
which don't have compatible interfaces.
When you want to create a reusable class that cooperates with classes
which don't have compatible interfaces
Example of Adapter Pattern
It provides the protection to the original object from the outside world.
Usage of Proxy Pattern:
It is used:
It can be used in Virtual Proxy scenario---Consider a situation where
there is multiple database call to extract huge size image. Since this is
an expensive operation so here we can use the proxy pattern which
would create multiple proxies and point to the huge size memory
consuming object for further processing. The real object gets created
only when a client first requests/accesses the object and after that we
can just refer to the proxy to reuse the object. This avoids duplication
of the object and hence saving memory.
It can be used in Protective Proxy scenario---It acts as an
authorization layer to verify that whether the actual user has access
the appropriate content or not. For example, a proxy server which
provides restriction on internet access in office. Only the websites
and contents which are valid will be allowed and the remaining ones
will be blocked
It can be used in Remote Proxy scenario ---A remote proxy can be
thought about the stub in the RPC call. The remote proxy provides a
local representation of the object which is present in the different
address location. Another example can be providing interface for
remote resources such as web service or REST resources.
It can be used in Smart Proxy scenario---A smart proxy provides
additional layer of security by interposing specific actions when the
object is accessed. For example, to check whether the real object is
locked or not before accessing it so that no other objects can change it.
Example of Proxy Pattern
Let's understand the example of proxy design pattern by the below UML
diagram.
Now, Create a ProxyPatternClient class that can access the internet actually.
File: ProxyPatternClient.java
public class ProxyPatternClient {
public static void main(String[] args)
{
OfficeInternetAccess access = new ProxyInternetAccess("Ashwani Rajput");
access.grantInternetAccess();
} }
Output
It is used:
When you want to add responsibilities to an object that you may want
to change in future.
Create a VegFood class that will implements the Food interface and override
its all methods.
File: VegFood.java
public class VegFood implements Food {
public String prepareFood(){
return "Veg Food";
}
public double foodPrice(){
return 50.0;
}
}
Step 3:Create a FoodDecorator abstract class that will implements the Food
interface and override it's all methods and it has the ability to decorate some
more foods.
File: FoodDecorator.java
public abstract class FoodDecorator implements Food{
private Food newFood;
public FoodDecorator(Food newFood) {
this.newFood=newFood;
}
@Override
public String prepareFood(){
return newFood.prepareFood();
}
public double foodPrice(){
return newFood.foodPrice();
}
}
Step 4:Create a NonVegFood concrete class that will extend the
FoodDecorator class and override it's all methods.
File: NonVegFood.java
}while(choice!=4);
} }
________________________________________
download this Decorator Pattern Example
Output
========= Food Menu ============
1. Vegetarian Food.
2. Non-Vegetarian Food.
3. Chineese Food.
4. Exit
Enter your choice: 1
Veg Food
50.0
========= Food Menu ============
1. Vegetarian Food.
2. Non-Vegetarian Food.
3. Chineese Food.
4. Exit
Enter your choice: 2
Veg Food With Roasted Chiken and Chiken Curry
200.0
========= Food Menu ============
1. Vegetarian Food.
2. Non-Vegetarian Food.
3. Chineese Food.
4. Exit
Enter your choice: 3
Veg Food With Fried Rice and Manchurian
115.0
========= Food Menu ============
1. Vegetarian Food.
2. Non-Vegetarian Food.
3. Chineese Food.
4. Exit
Enter your choice: 4
Other than these no food available
1.1.9 TEMPLATE PATTERN
A Template Pattern says that "just define the skeleton of a function in
an operation, deferring some steps to its subclasses".
Benefits:
It is very common technique for reusing the code.This is only the main
benefit of it.
Usage:
void initialize() {
System.out.println("Chess Game Initialized! Start playing.");
}
@Override
void start() {
System.out.println("Game Started. Welcome to in the chess game!"
);
}
@Override
void end() {
System.out.println("Game Finished!");
}
}// End of the Chess class
Step 3:
Create a Soccer class that will extend Game abstract class for giving
the definition to its method.
//This is a class.
public class Soccer extends Game {
@Override
void initialize() {
System.out.println("Soccer Game Initialized! Start playing.");
}
@Override
void start() {
System.out.println("Game Started. Welcome to in the Soccer game!
");
}
@Override
void end() {
System.out.println("Game Finished!");
}
}// End of the Soccer class.
Step 4:
Create a TemplatePatternDemo class.
//This is a class.
public class TemplatePatternDemo {
public static void main(String[] args) throws InstantiationException, Illeg
alAccessException, ClassNotFoundException {
Class c=Class.forName(args[0]);
Game game=(Game) c.newInstance();
game.play();
}
}// End of the Soccer class
Output:
No Internet access granted. Your job level is below 5
It separates the object that invokes the operation from the object that
actually performs the operation.
It makes easy to add new commands, because existing classes remain
unchanged.
It is used:
When you need parameterize objects according to an action perform.
When you need to create and execute requests at different times.
When you need to support rollback, logging or transaction
functionality.
UML for command pattern:
These are the following participants of the Command Design pattern:
Command This is an interface for executing an operation.
ConcreteCommand This class extends the Command interface and
implements the execute method. This class creates a binding between
the action and the receiver.
Client This class creates the ConcreteCommand class and associates it
with the receiver.
Invoker This class asks the command to carry out the request.
Receiver This class knows to perform the operation.
menu.clickOpen();
menu.clickSave();
}}
Output
1. Document Opened
2. Document Saved
Mediator Pattern
Output:
1.2 COLLECTION FRAMEWORK
Collections in Java
There are many methods declared in the Collection interface. They are
as follows:
Method Description
public boolean add(E e) It is used to insert an element in this
collection.
publicboolean It is used to insert the specified collection
addAll(Collection<? elements in the invoking collection.
extends E> c)
public boolean It is used to delete an element from the
remove(Object collection.
element)
publicboolean It is used to delete all the elements of the
removeAll(Collection<? specified collection from the invoking
> c) collection.
default boolean It is used to delete all the elements of the
removeIf(Predicate<? collection that satisfy the specified
super E> filter) predicate.
publicboolean It is used to delete all the elements of
retainAll(Collection<?> invoking collection except the specified
c) collection.
public int size() It returns the total number of elements in
the collection.
public void clear() It removes the total number of elements
from the collection.
public boolean It is used to search an element.
contains(Object
element)
public boolean It is used to search the specified collection
containsAll(Collection<? in the collection.
> c)
public Iterator iterator() It returns an iterator.
public Object[] toArray() It converts collection into array.
public <T> T[] It converts collection into array. Here, the
toArray(T[] a) runtime type of the returned array is that
of the specified array.
public boolean It checks if collection is empty.
isEmpty()
default Stream<E> It returns a possibly parallel Stream with
parallelStream() the collection as its source.
default Stream<E> It returns a sequential Stream with the
stream() collection as its source.
default Spliterator<E> It generates a Spliterator over the
spliterator() specified elements in the collection.
public boolean It matches two collections.
equals(Object element)
public int hashCode() It returns the hash code number of the
collection.
Iterator interface
Iterator interface provides the facility of iterating the elements in a
forward direction only.
Methods of Iterator interface
There are only three methods in the Iterator interface. They are:
Method Description
public boolean It returns true if the iterator has more elements
hasNext() otherwise it returns false.
public Object next() It returns the element and moves the cursor pointer
to the next element.
public void It removes the last elements returned by the iterator.
remove() It is less used.
Iterable Interface
The Iterable interface is the root interface for all the collection classes.
The Collection interface extends the Iterable interface and therefore all the
subclasses of Collection interface also implement the Iterable interface.It
contains only one abstract method. i.e.,
Iterator<T> iterator()
Deque Interface
ArrayDeque
Set Interface
TreeSet
Java TreeSet class implements the Set interface that uses a tree for
storage. Like HashSet, TreeSet also contains unique elements. However, the
access and retrieval time of TreeSet is quite fast. The elements in TreeSet
stored in ascending order.Consider the following example:
import java.util.*;
public class TestJavaCollection9{
public static void main(String args[]){
//Creating and adding elements
TreeSet<String> set=new TreeSet<String>();
set.add("Ravi");
set.add("Vijay");
set.add("Ravi");
set.add("Ajay");
//traversing elements
Iterator<String> itr=set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
} } }
Output:
Ajay
Ravi
Vijay
Java ArrayList class uses a dynamic array for storing the elements. It is
like an array, but there is no size limit. We can add or remove elements
anytime. So, it is much more flexible than the traditional array. It is found in
the java.util package. It is like the Vector in C++.The ArrayList in Java can
have the duplicate elements also. It implements the List interface so we can
use all the methods of List interface here. The ArrayList maintains the insertion
order internally.It inherits the AbstractList class and implements List
interface.The important points about Java ArrayList class are:
Java ArrayList class can contain duplicate elements.
Java ArrayList class maintains insertion order.
Java ArrayList class is non synchronized.
Java ArrayList allows random access because array works at the index
basis.
In ArrayList, manipulation is little bit slower than the LinkedList in Java
because a lot of shifting needs to occur if any element is removed from
the array list.
Hierarchy of ArrayList class
Constructor Description
ArrayList() It is used to build an empty array list.
ArrayList(Collection<? It is used to build an array list that is
extends E> c) initialized with the elements of the collection
c.
ArrayList(int capacity) It is used to build an array list that has the
specified initial capacity.
Methods of ArrayList
void add(int index, E element) It is used to insert the specified
element at the specified position in a
list.
boolean add(E e) It is used to append the specified
element at the end of a list.
boolean addAll(Collection<? It is used to append all of the elements
extends E> c) in the specified collection to the end of
this list, in the order that they are
returned by the specified collection's
iterator.
boolean addAll(int index, It is used to append all the elements in
Collection<? extends E> c) the specified collection, starting at the
specified position of the list.
void clear() It is used to remove all of the elements
from this list.
void ensureCapacity(int It is used to enhance the capacity of
requiredCapacity) an ArrayList instance.
E get(int index) It is used to fetch the element from the
particular position of the list.
boolean isEmpty() It returns true if the list is empty,
otherwise false.
int lastIndexOf(Object o) It is used to return the index in this list
of the last occurrence of the specified
element, or -1 if the list does not
contain this element.
Object[] toArray() It is used to return an array containing
all of the elements in this list in the
correct order.
<T> T[] toArray(T[] a) It is used to return an array containing
all of the elements in this list in the
correct order.
Object clone() It is used to return a shallow copy of
an ArrayList.
boolean contains(Object o) It returns true if the list contains the
specified element
int indexOf(Object o) It is used to return the index in this list
of the first occurrence of the specified
element, or -1 if the List does not
contain this element.
E remove(int index) It is used to remove the element
present at the specified position in the
list.
boolean remove(Object o) It is used to remove the first
occurrence of the specified element.
boolean removeAll(Collection<?> It is used to remove all the elements
c) from the list.
boolean removeIf(Predicate<? It is used to remove all the elements
super E> filter) from the list that satisfies the given
predicate.
protected void removeRange(int It is used to remove all the elements
fromIndex, int toIndex) lies within the given range.
void It is used to replace all the elements
replaceAll(UnaryOperator<E> from the list with the specified
operator) element.
void retainAll(Collection<?> c) It is used to retain all the elements in
the list that are present in the
specified collection.
E set(int index, E element) It is used to replace the specified
element in the list, present at the
specified position.
void sort(Comparator<? super E> It is used to sort the elements of the
c) list on the basis of specified
comparator.
Spliterator<E> spliterator() It is used to create spliterator over the
elements in a list.
List<E> subList(int fromIndex, int It is used to fetch all the elements lies
toIndex) within the given range.
int size() It is used to return the number of
elements present in the list.
void trimToSize() It is used to trim the capacity of this
ArrayList instance to be the list's
current size.
Java collection framework was non-generic before JDK 1.5. Since 1.5, it
is generic.Java new generic collection allows you to have only one type of
object in a collection. Now it is type safe so typecasting is not required at
runtime.Let's see the old non-generic example of creating java collection.
ArrayList list=new ArrayList();
ArrayList list=new ArrayList();//creating old non-generic arraylist
Let's see the new generic example of creating java collection.
ArrayList<String> list=new ArrayList<String>();
ArrayList list=new ArrayList();//creating new generic arraylist
In a generic collection, we specify the type in angular braces. Now
ArrayList is forced to have the only specified type of objects in it. If you try to
add another type of object, it gives compile time error.
Java ArrayList Example
import java.util.*;
public class ArrayListExample1{
public static void main(String args[]){
ArrayList<String> list=new ArrayList<String>();
list.add("Mango");
list.add("Apple");
list.add("Banana");
list.add("Grapes");
System.out.println(list);
} }
output
[Mango, Apple, Banana, Grapes]
Iterating ArrayList using Iterator
Apple
Banana
Grapes
Get and Set ArrayList
The get() method returns the element at the specified index, whereas
the set() method changes the element.
import java.util.*;
public class ArrayListExample4{
public static void main(String args[]){
ArrayList<String> al=new ArrayList<String>();
al.add("Mango");
al.add("Apple");
al.add("Banana");
al.add("Grapes");
System.out.println("Returning element: "+al.get(1));
al.set(1,"Dates");
for(String fruit:al)
System.out.println(fruit);
}}
Output:
Mango
Dates
Banana
Grapes
How to Sort ArrayList
The java.util package provides a utility class Collections which has the
static method sort(). Using the Collections.sort() method, we can easily
sort the ArrayList.
import java.util.*;
class SortArrayList{
public static void main(String args[]){
List<String> list1=new ArrayList<String>();
list1.add("Mango");
list1.add("Apple");
list1.add("Banana");
list1.add("Grapes");
Collections.sort(list1);
for(String fruit:list1)
System.out.println(fruit);
System.out.println("Sorting numbers...");
List<Integer> list2=new ArrayList<Integer>();
list2.add(21);
list2.add(11);
list2.add(51);
list2.add(1);
Collections.sort(list2);
for(Integer number:list2)
System.out.println(number);
} }
Output:
Apple
Banana
Grapes
Mango
Sorting numbers...
1
11
21
51
Ways to iterate the elements of the collection in Java
Java LinkedList class uses a doubly linked list to store the elements. It
provides a linked-list data structure. It inherits the AbstractList class and
implements List and Deque interfaces.
The important points about Java LinkedList are:
import java.util.*;
public class LinkedList1{
public static void main(String args[]){
LinkedList<String> al=new LinkedList<String>();
al.add("Ravi");
al.add("Vijay");
al.add("Ravi");
al.add("Ajay");
Iterator<String> itr=al.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
} } }
Output: Ravi
Vijay
Ravi
Ajay
1.5 ARRAYLIST VS. LINKEDLIST
ArrayList and LinkedList both implements List interface and maintains
insertion order. Both are non synchronized classes.However, there are many
differences between ArrayList and LinkedList classes that are given below.
ArrayList LinkedList
1) ArrayList internally uses a dynamic LinkedList internally uses
array to store the elements. a doubly linked list to
store the elements.
2) Manipulation with ArrayList Manipulation with LinkedList
is slow because it internally uses an array. is faster than ArrayList
If any element is removed from the array, because it uses a doubly
all the bits are shifted in memory. linked list, so no bit shifting
is required in memory.
3) An ArrayList class can act as a list only LinkedList class can act as a
because it implements List only. list and queue both
because it implements List
and Deque interfaces.
4) ArrayList is better for storing and LinkedList is better for
accessing data. manipulating data.
.import java.util.*;
class TestArrayLinked{
public static void main(String args[]){
List<String> al=new ArrayList<String>();//creating arraylist
al.add("Ravi");//adding object in arraylist
al.add("Vijay");
al.add("Ravi");
al.add("Ajay");
List<String> al2=new LinkedList<String>();//creating linkedlist
al2.add("James");//adding object in linkedlist
al2.add("Serena");
al2.add("Swati");
al2.add("Junaid");
System.out.println("arraylist: "+al);
System.out.println("linkedlist: "+al2);
} }
Output:
arraylist: [Ravi,Vijay,Ravi,Ajay]
linkedlist: [James,Serena,Swati,Junaid]
1.6 LISTITERATOR INTERFACE
ListIterator Interface is used to traverse the element in a backward and
forward direction.
ListIterator Interface declaration
public interface ListIterator<E> extends Iterator<E>
Methods of Java ListIterator Interface:
Method Description
void add(E e) This method inserts the specified element into the
list.
boolean hasNext() This method returns true if the list iterator has more
elements while traversing the list in the forward
direction.
E next() This method returns the next element in the list and
advances the cursor position.
int nextIndex() This method returns the index of the element that
would be returned by a subsequent call to next()
boolean This method returns true if this list iterator has more
hasPrevious() elements while traversing the list in the reverse
direction.
E previous() This method returns the previous element in the list
and moves the cursor position backward.
E previousIndex() This method returns the index of the element that
would be returned by a subsequent call to previous().
void remove() This method removes the last element from the list
that was returned by next() or previous() methods
void set(E e) This method replaces the last element returned by
next() or previous() methods with the specified
element.
Example of ListIterator Interface
import java.util.*;
public class ListIteratorExample1{
public static void main(String args[]){
List<String> al=new ArrayList<String>();
al.add("Amit");
al.add("Vijay");
al.add("Kumar");
al.add(1,"Sachin");
ListIterator<String> itr=al.listIterator();
System.out.println("Traversing elements in forward direction");
while(itr.hasNext()){
System.out.println("index:"+itr.nextIndex()+" value:
"+itr.next());
}
System.out.println("Traversing elements in backward direction");
while(itr.hasPrevious()){
System.out.println("index:"+itr.previousIndex()+" value:"+itr.previous());
}
} }
Output:
Traversing elements in forward direction
index:0 value:Amit
index:1 value:Sachin
index:2 value:Vijay
index:3 value:Kumar
Traversing elements in backward direction
index:3 value:Kumar
index:2 value:Vijay
index:1 value:Sachin
index:0 value:Amit
1.7 HASHSET CLASS
Java HashSet class is used to create a collection that uses a hash table
for storage. It inherits the AbstractSet class and implements Set
interface.The important points about Java HashSet class are:
HashSet stores the elements by using a mechanism called hashing.
HashSet contains unique elements only.
HashSet allows null value.
HashSet class is non synchronized.
HashSet doesn't maintain the insertion order. Here, elements are
inserted on the basis of their hashcode.
HashSet is the best approach for search operations.
The initial default capacity of HashSet is 16, and the load factor is 0.75.
Difference between List and Set
Constructor Description
HashSet() It is used to construct a default
HashSet.
HashSet(int capacity) It is used to initialize the
capacity of the hash set to the
given integer value capacity.
The capacity grows
automatically as elements are
added to the HashSet.
HashSet(int capacity, float loadFactor) It is used to initialize the
capacity of the hash set to the
given integer value capacity
and the specified load factor.
HashSet(Collection<? extends E> c) It is used to initialize the hash
set by using the elements of
the collection c.
Let's see a HashSet example where we are adding books to set and
printing all the books.
import java.util.*;
class Book {
int id;
String name,author,publisher;
int quantity;
public Book(int id, String name, String author, String publisher, int quant
ity) {
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
}
public class HashSetExample {
public static void main(String[] args) {
HashSet<Book> set=new HashSet<Book>();
//Creating Books
Book b1=new Book(101,"Let us C","Yashwant Kanetkar","BPB",8);
Book b2=new Book(102,"Data Communications & Networking","Forouz
an","Mc Graw Hill",4);
Book b3=new Book(103,"Operating System","Galvin","Wiley",6);
//Adding Books to HashSet
set.add(b1);
set.add(b2);
set.add(b3);
//Traversing HashSet
for(Book b:set){
System.out.println(b.id+" "+b.name+" "+b.author+" "+b.publisher+" "
+b.quantity);
} } }
Output:
101 Let us C Yashwant Kanetkar BPB 8
102 Data Communications & Networking Forouzan Mc Graw Hill 4
103 Operating System Galvin Wiley 6
Constructor Description
HashSet() It is used to construct a default
HashSet.
HashSet(Collection c) It is used to initialize the hash set by
using the elements of the collection
c.
LinkedHashSet(int capacity) It is used initialize the capacity of the
linked hash set to the given integer
value capacity.
LinkedHashSet(int capacity, float It is used to initialize both the
fillRatio) capacity and the fill ratio (also called
load capacity) of the hash set from
its argument.
Java LinkedHashSet Example: Book
import java.util.*;
class Book {
int id;
String name,author,publisher;
int quantity;
public Book(int id, String name, String author, String publisher, int quant
ity) {
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
}
public class LinkedHashSetExample {
public static void main(String[] args) {
LinkedHashSet<Book> hs=new LinkedHashSet<Book>();
//Creating Books
Book b1=new Book(101,"Let us C","Yashwant Kanetkar","BPB",8);
Book b2=new Book(102,"Data Communications & Networking","Forouz
an","Mc Graw Hill",4);
Book b3=new Book(103,"Operating System","Galvin","Wiley",6);
//Adding Books to hash table
hs.add(b1);
hs.add(b2);
hs.add(b3);
//Traversing hash table
for(Book b:hs){
System.out.println(b.id+" "+b.name+" "+b.author+" "+b.publisher+" "
+b.quantity);
} } }
Output:
101 Let us C Yashwant Kanetkar BPB 8
Java TreeSet class implements the Set interface that uses a tree for
storage. It inherits AbstractSet class and implements the NavigableSet
interface. The objects of the TreeSet class are stored in ascending order.The
important points about Java TreeSet class are:
Constructor Description
It is used to construct an empty tree set
that will be sorted in ascending order
TreeSet()
according to the natural order of the tree
set.
TreeSet(Collection<? extends It is used to build a new tree set that
E> c) contains the elements of the collection c.
It is used to construct an empty tree set
TreeSet(Comparator<? super
that will be sorted according to given
E> comparator)
comparator.
It is used to build a TreeSet that contains
TreeSet(SortedSet<E> s)
the elements of the given SortedSet.
Methods of Java TreeSet class
Method Description
boolean add(E e) It is used to add the specified
element to this set if it is not
already present.
boolean addAll(Collection<? extends E> It is used to add all of the
c) elements in the specified
collection to this set.
E ceiling(E e) It returns the equal or closest
greatest element of the
specified element from the set,
or null there is no such
element.
Comparator<? super E> comparator() It returns comparator that
arranged elements in order.
Iterator descendingIterator() It is used iterate the elements
in descending order.
NavigableSet descendingSet() It returns the elements in
reverse order.
E floor(E e) It returns the equal or closest
least element of the specified
element from the set, or null
there is no such element.
SortedSet headSet(E toElement) It returns the group of elements
that are less than the specified
element.
NavigableSet headSet(E toElement, It returns the group of elements
boolean inclusive) that are less than or equal to(if,
inclusive is true) the specified
element.
E higher(E e) It returns the closest greatest
element of the specified
element from the set, or null
there is no such element.
Iterator iterator() It is used to iterate the
elements in ascending order.
E lower(E e) It returns the closest least
element of the specified
element from the set, or null
there is no such element.
E pollFirst() It is used to retrieve and
remove the lowest(first)
element.
E pollLast() It is used to retrieve and
remove the highest(last)
element.
Spliterator spliterator() It is used to create a late-
binding and fail-fast spliterator
over the elements.
NavigableSet subSet(E fromElement, It returns a set of elements that
boolean fromInclusive, E toElement, lie between the given range.
boolean toInclusive)
SortedSet subSet(E fromElement, E It returns a set of elements that
toElement)) lie between the given range
which includes fromElement
and excludes toElement.
SortedSet tailSet(E fromElement) It returns a set of elements that
are greater than or equal to the
specified element.
NavigableSet tailSet(E fromElement, It returns a set of elements that
boolean inclusive) are greater than or equal to (if,
inclusive is true) the specified
element.
boolean contains(Object o) It returns true if this set
contains the specified element.
boolean isEmpty() It returns true if this set
contains no elements.
boolean remove(Object o) It is used to remove the
specified element from this set
if it is present.
void clear() It is used to remove all of the
elements from this set.
Object clone() It returns a shallow copy of this
TreeSet instance.
E first() It returns the first (lowest)
element currently in this sorted
set.
E last() It returns the last (highest)
element currently in this sorted
set.
int size() It returns the number of
elements in this set.
Java TreeSet Example: Book
Let's see a TreeSet example where we are adding books to set and
printing all the books. The elements in TreeSet must be of a Comparable
type. String and Wrapper classes are Comparable by default. To add user-
defined objects in TreeSet, you need to implement the Comparable interface.
import java.util.*;
class Book implements Comparable<Book>{
int id;
String name,author,publisher;
int quantity;
public Book(int id, String name, String author, String publisher, int quant
ity) {
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
public int compareTo(Book b) {
if(id>b.id){
return 1;
}else if(id<b.id){
return -1;
}else{
return 0;
}
}
}
public class TreeSetExample {
public static void main(String[] args) {
Set<Book> set=new TreeSet<Book>();
//Creating Books
Book b1=new Book(121,"Let us C","Yashwant Kanetkar","BPB",8);
Book b2=new Book(233,"Operating System","Galvin","Wiley",6);
Book b3=new Book(101,"Data Communications & Networking","Forouz
an","Mc Graw Hill",4);
//Adding Books to TreeSet
set.add(b1);
set.add(b2);
set.add(b3);
//Traversing TreeSet
for(Book b:set){
System.out.println(b.id+" "+b.name+" "+b.author+" "+b.publisher+" "
+b.quantity);
} } }
Output:
101 Data Communications & Networking Forouzan Mc Graw Hill 4
head:Amit
iterating the queue elements:
Amit
Jai
Karan
Vijay
Rahul
after removing two elements:
Karan
Rahul
Vijay
A Map doesn't allow duplicate keys, but you can have duplicate values.
HashMap and LinkedHashMap allow null keys and values, but TreeMap
doesn't allow any null key or value.A Map can't be traversed, so you need to
convert it into Set using keySet() or entrySet() method.
Class Description
HashMap HashMap is the implementation of Map,
but it doesn't maintain any order.
LinkedHashMap LinkedHashMap is the implementation of
Map. It inherits HashMap class. It maintains
insertion order.
TreeMap TreeMap is the implementation of Map and
SortedMap. It maintains ascending order.
Useful methods of Map interface
Method Description
V put(Object key, Object value) It is used to insert an entry
in the map.
void putAll(Map map) It is used to insert the
specified map in the map.
V putIfAbsent(K key, V value) It inserts the specified
value with the specified
key in the map only if it is
not already specified.
V remove(Object key) It is used to delete an
entry for the specified key.
boolean remove(Object key, Object value) It removes the specified
values with the associated
specified keys from the
map.
Set keySet() It returns the Set view
containing all the keys.
Set<Map.Entry<K,V>> entrySet() It returns the Set view
containing all the keys and
values.
void clear() It is used to reset the map.
V compute(K key, BiFunction<? super K,? It is used to compute a
super V,? extends V> remappingFunction) mapping for the specified
key and its current
mapped value (or null if
there is no current
mapping).
V computeIfAbsent(K key, Function<? super It is used to compute its
K,? extends V> mappingFunction) value using the given
mapping function, if the
specified key is not already
associated with a value (or
is mapped to null), and
enters it into this map
unless null.
V computeIfPresent(K key, BiFunction<? super It is used to compute a
K,? super V,? extends V> remappingFunction) new mapping given the
key and its current
mapped value if the value
for the specified key is
present and non-null.
boolean containsValue(Object value) This method returns true if
some value equal to the
value exists within the
map, else return false.
boolean containsKey(Object key) This method returns true if
some key equal to the key
exists within the map, else
return false.
boolean equals(Object o) It is used to compare the
specified Object with the
Map.
void forEach(BiConsumer<? super K,? super It performs the given
V> action) action for each entry in the
map until all entries have
been processed or the
action throws an
exception.
V get(Object key) This method returns the
object that contains the
value associated with the
key.
V getOrDefault(Object key, V defaultValue) It returns the value to
which the specified key is
mapped, or defaultValue if
the map contains no
mapping for the key.
int hashCode() It returns the hash code
value for the Map
boolean isEmpty() This method returns true if
the map is empty; returns
false if it contains at least
one key.
V merge(K key, V value, BiFunction<? super If the specified key is not
V,? super V,? extends V> remappingFunction) already associated with a
value or is associated with
null, associates it with the
given non-null value.
V replace(K key, V value) It replaces the specified
value for a specified key.
boolean replace(K key, V oldValue, V It replaces the old value
newValue) with the new value for a
specified key.
void replaceAll(BiFunction<? super K,? super It replaces each entry's
V,? extends V> function) value with the result of
invoking the given function
on that entry until all
entries have been
processed or the function
throws an exception.
Collection values() It returns a collection view
of the values contained in
the map.
int size() This method returns the
number of entries in the
map.
MapEntry Interface
Entry is the subinterface of Map. So we will be accessed it by
Map.Entry name. It returns a collection-view of the map, whose elements are
of this class. It provides methods to get key and value.
Methods of Map.Entry interface
Method Description
K getKey() It is used to obtain a key.
V getValue() It is used to obtain value.
int hashCode() It is used to obtain hashCode.
V setValue(V value) It is used to replace the value
corresponding to this entry with the
specified value.
boolean equals(Object o) It is used to compare the specified
object with the other existing objects.
static <K extends It returns a comparator that compare
Comparable<? super K>,V> the objects in natural order on key.
Comparator<Map.Entry<K,V>>
comparingByKey()
static <K,V> It returns a comparator that compare
Comparator<Map.Entry<K,V>> the objects by key using the given
comparingByKey(Comparator<? Comparator.
super K> cmp)
static <K,V extends It returns a comparator that compare
Comparable<? superV>> the objects in natural order on value.
Comparator<Map.Entry<K,V>>
comparingByValue()
static<K,V> It returns a comparator that compare
Comparator<Map.Entry<K,V>> the objects by value using the given
comparingByValue(Comparator< Comparator.
? super V> cmp)
Java Map Example: Non-Generic (Old Style)
//Non-generic
import java.util.*;
public class MapExample1 {
public static void main(String[] args) {
Map map=new HashMap();
//Adding elements to map
map.put(1,"Amit");
map.put(5,"Rahul");
map.put(2,"Jai");
map.put(6,"Amit");
//Traversing Map
Set set=map.entrySet();//Converting to Set so that we can traverse
Iterator itr=set.iterator();
while(itr.hasNext()){
//Converting to Map.Entry so that we can get key and value separately
Map.Entry entry=(Map.Entry)itr.next();
System.out.println(entry.getKey()+" "+entry.getValue());
} } }
Output:
1 Amit
2 Jai
5 Rahul
6 Amit
Java Map Example: Generic (New Style)
import java.util.*;
class MapExample2{
public static void main(String args[]){
Map<Integer,String> map=new HashMap<Integer,String>();
map.put(100,"Amit");
map.put(101,"Vijay");
map.put(102,"Rahul");
//Elements can traverse in any order
for(Map.Entry m:map.entrySet()){
System.out.println(m.getKey()+" "+m.getValue());
} } }
Output:
102 Rahul
100 Amit
101 Vijay
1.12 HASHMAP
Hashing
We use put() method to insert the Key and Value pair in the HashMap.
The default size of HashMap is 16 (0 to 15).
Example
In the following example, we want to insert three (Key, Value) pair in the
HashMap.
HashMap<String, Integer> map = new HashMap<>();
map.put("Aman", 19);
map.put("Sunny", 29);
map.put("Ritesh", 39);
Let's see at which index the Key, value pair will be saved into
HashMap. When we call the put() method, then it calculates the hash code
of the Key "Aman." Suppose the hash code of "Aman" is 2657860. To
store the Key in memory, we have to calculate the index.
Calculating Index
Index minimizes the size of the array. The Formula for calculating the
index is:
Index = hashcode(Key) & (n-1)
Where n is the size of the array. Hence the index value for "Aman" is:
Index = 2657860 & (16-1) = 4
The value 4 is the computed index value where the Key and value will
store in HashMap.
Hash Collision
This is the case when the calculated index value is the same for two or
more Keys. Let's calculate the hash code for another Key "Sunny."
Suppose the hash code for "Sunny" is 63281940. To store the Key in the
memory, we have to calculate index by using the index formula.
Index=63281940 & (16-1) = 4
The value 4 is the computed index value where the Key will be stored
in HashMap. In this case, equals() method check that both Keys are equal
or not. If Keys are same, replace the value with the current value.
Otherwise, connect this node object to the existing node object through
the LinkedList. Hence both Keys will be stored at index 4.
Similarly, we will store the Key "Ritesh." Suppose hash code for the Key
is 2349873. The index value will be 1. Hence this Key will be stored at
index 1.
101 Vijay
102 Ravi
103 Rahul
1.14 COMPARABLE INTERFACE
Java Comparable interface is used to order the objects of the user-
defined class. This interface is found in java.lang package and contains only
one method named compareTo(Object). It provides a single sorting sequence
only, i.e., you can sort the elements on the basis of single data member only.
For example, it may be rollno, name, age or anything else.
compareTo(Object obj) method
public int compareTo(Object obj): It is used to compare the current
object with the specified object. It returns
positive integer, if the current object is greater than the specified
object.
negative integer, if the current object is less than the specified object.
zero, if the current object is equal to the specified object.
We can sort the elements of:
String objects
Wrapper class objects
User-defined class objects
Collections class
public void sort(List list): It is used to sort the elements of List. List elements must be of the
Comparable type.
Java Comparable Example
Let's see the example of the Comparable interface that sorts the list
elements on the basis of age.
File: Student.java
class Student implements Comparable<Student>{
int rollno;
String name;
int age;
Student(int rollno,String name,int age){
this.rollno=rollno;
this.name=name;
this.age=age;
}
public int compareTo(Student st){
if(age==st.age)
return 0;
else if(age>st.age)
return 1;
else
return -1;
}
}
File: TestSort1.java
import java.util.*;
public class TestSort1{
public static void main(String args[]){
ArrayList<Student> al=new ArrayList<Student>();
al.add(new Student(101,"Vijay",23));
al.add(new Student(106,"Ajay",27));
al.add(new Student(105,"Jai",21));
Collections.sort(al);
for(Student st:al){
System.out.println(st.rollno+" "+st.name+" "+st.age);
} } }
Output:
105 Jai 21
101 Vijay 23
106 Ajay 27
1.15 COMPARATOR INTERFACE
Java Comparator interface is used to order the objects of a user-
defined class.This interface is found in java.util package and contains 2
methods compare(Object obj1,Object obj2) and equals(Object element).It
provides multiple sorting sequences, i.e., you can sort the elements on the
basis of any data member, for example, rollno, name, age or anything else.
Methods of Java Comparator Interface
Method Description
public int compare(Object obj1, It compares the first object with the
Object obj2) second object.
public boolean equals(Object obj) It is used to compare the current
object with the specified object.
public boolean equals(Object obj) It is used to compare the current
object with the specified object.
Collections class
Collections class provides static methods for sorting the elements of
a collection. If collection elements are of Set or Map, we can use TreeSet or
TreeMap. However, we cannot sort the elements of List. Collections class
provides methods for sorting the elements of List type elements also.
Let's see the example of sorting the elements of List on the basis of
age and name. In this example, we have created 4 java classes:
Student.java
AgeComparator.java
NameComparator.java
Simple.java
Student.java
This class contains three fields rollno, name and age and a parameterized
constructor.
class Student{
int rollno;
String name;
int age;
Student(int rollno,String name,int age){
this.rollno=rollno;
this.name=name;
this.age=age;
} }
AgeComparator.java
This class defines comparison logic based on the age. If the age of the
first object is greater than the second, we are returning a positive value. It
can be anyone such as 1, 2, 10. If the age of the first object is less than the
second object, we are returning a negative value, it can be any negative
value, and if the age of both objects is equal, we are returning 0.
import java.util.*;
class AgeComparator implements Comparator{
public int compare(Object o1,Object o2){
Student s1=(Student)o1;
Student s2=(Student)o2;
if(s1.age==s2.age)
return 0;
else if(s1.age>s2.age)
return 1;
else
return -1;
} }
NameComparator.java
This class provides comparison logic based on the name. In such case,
we are using the compareTo() method of String class, which internally
provides the comparison logic.
import java.util.*;
class NameComparator implements Comparator{
public int compare(Object o1,Object o2){
Student s1=(Student)o1;
Student s2=(Student)o2;
return s1.name.compareTo(s2.name);
} }
Simple.java
In this class, we are printing the values of the object by sorting on the
basis of name and age.
import java.util.*;
import java.io.*;
class Simple{
public static void main(String args[]){
ArrayList al=new ArrayList();
al.add(new Student(101,"Vijay",23));
al.add(new Student(106,"Ajay",27));
al.add(new Student(105,"Jai",21));
System.out.println("Sorting by Name");
Collections.sort(al,new NameComparator());
Iterator itr=al.iterator();
while(itr.hasNext()){
Student st=(Student)itr.next();
System.out.println(st.rollno+" "+st.name+" "+st.age);
}
System.out.println("Sorting by age");
Collections.sort(al,new AgeComparator());
Iterator itr2=al.iterator();
while(itr2.hasNext()){
Student st=(Student)itr2.next();
System.out.println(st.rollno+" "+st.name+" "+st.age);
} } }
Output:
Sorting by Name
106 Ajay 27
105 Jai 21
101 Vijay 23
Sorting by age
105 Jai 21
101 Vijay 23
106 Ajay 27
1.16 COMPARABLE VS COMPARATOR
Comparable and Comparator both are interfaces and can be used to
sort collection elements.However, there are many differences between
Comparable and Comparator interfaces that are given below.