Java and Data Structures - Book - III Semester - BSC (CS) - TS
Java and Data Structures - Book - III Semester - BSC (CS) - TS
OUTCOMES:
• Students will be able to develop Java Standalone applications and Applets.
• Choose the appropriate data structure for modeling a given problem.
UNIT - I
History and Evolution of Java - Features of Java - Object Oriented Concepts - Bytecode - Lexical
Issues - Data Types – Variables - Type Conversion and Casting - Operators - Arithmetic Operators
- Bitwise - Relational Operators - Assignment Operator - The conditional Operator - Operator
Precedence - Control Statements - Arrays.
UNIT - II
Classes - Objects - Constructors - Overloading method - Static and fixed methods - Inner Classes -
String Class - Overriding methods - Using super - Abstract class - this keyword - finalize() method
- Garbage Collection.
UNIT - III
UNIT - IV
Abstract Data Types(ADTs) - List ADT - Array based implementation - linked list implementation
- singly linked list - doubly linked list - circular linked list - Stack ADT operations – Applications -
Evaluating arithmetic expressions - Conversion of infix to postfix expression - Queue ADT-
operations - Applications of Queues.
UNIT - V
Trees - Binary Trees - representation - Operations on Binary Trees - Traversal of a Binary Tree -
Binary Search Trees, Graphs - Representation of Graphs - Traversal in Graph - Dijkstra’s Algorithm,
Depth-First vs Breadth-First Search.
1
TEXT BOOKS:
1. E.Balagurusamy,” Programming with Java: A Primer”, Tata McGraw Hill 2014, 5th Edition.
2. Mark Allen Weiss, “Data Structures and Algorithms Analysis in C++”, Person Education 2014,
4th Edition.
REFERENCES:
1. Herbert Schildt, “JAVA 2: The Complete Reference”, McGraw Hill 2018, 11th Edition.
2. Aho, Hopcroft and Ullman, “Data Structures and Algorithms “, Pearson Education 2003.
3. S. Sahni, “Data Structures, Algorithms and Applications in JAVA”, Universities Press 2005, 2nd
Edition
WEB REFERENCES:
2
JAVA AND DATA STRUCTURES
UNIT - I
*******************************************************************************
Chapter 1 The History and Evolution of Java
*******************************************************************************
1.1 Introduction
❖ Java is a General-Purpose, High-Level Object-Oriented Programming language developed by
Sun Microsystems of USA in 1991.
❖ It is a simple programming language. Java makes writing, compiling, and debugging
programming easy. It helps to create reusable code and modular programs.
❖ Java code can run on all platforms that support Java. Java applications are compiled to byte
code that can run on any Java Virtual Machine. The syntax of Java is similar to C/C++.
❖ Java is currently one of the most popular programming languages in use, particularly for client-
server web applications.
1.2 History of Java
❖ Java is invented by James Gosling, Patrick Naughton, Chris Warth, Ed Frank, and Mike
Sheridan at Sun Microsystems, Inc. in 1991. Java is related to C++, which is inherited from the
language C. The character of Java is inherited from C and C++ language. It took approx.
Eighteen months to develop the first working version. It was first named as “Oak” but was
renamed as “Java” in 1995.
❖ The basic idea behind creating this language is to create a platform-independent language that
is used to develop software for consumer electronic devices such as microwave ovens, remote
controls, etc. Initially, it was not designed for Internet applications.
❖ Java had an extreme effect on the Internet by the innovation of a new type of networked program
called the Applet. An Applet is a Java program that is designed to be transmitted over the
internet and executed by the web browser that is Java-compatible. Applets are the small program
that is used to display data provided by the server, handle user input, provide a simple function
such as calculator etc.
❖ Java solves the Security and the portability issue of the other language that is being used. The
key that allows doing so is the Bytecode. Bytecode is a highly optimized set of instruction that is
designed to be executed by the Java Virtual Machine (JVM). Java programs are executed by the
JVM also helps to make Java a secure programming g language because the JVM contains the
application and prevents it from affecting the external systems.
3
1.3 Evolution of Java
4
Includes update to standard Java Features text blocks,
Java SE 15 September 2020 hidden classes, the Z Garbage Collector, and previews of
pattern matching and records.
Upgrade of standard Java include primitive classes,
Java SE 16 March 2021 sealed classes, records, a vector API, and ports for
Windows on ARM64 and Alpine Linux.
6
❖ Java is an interpreted language.
❖ Java programs can be executed directly on any machine, which has the Java interpreter known
as the Java Virtual Machine and where the run-time environment has been ported.
9. High Performance
❖ Java provides high performance with the use of “JIT – Just In Time compiler”, in which the
compiler compiles the code on-demand basis, that is, it compiles only that method which is being
called. This saves time and makes it more efficient.
❖ Bytecodes generated by the Java compiler are highly optimized, so Java Virtual Machine can
execute them much faster.
10. Distributed
❖ Java is a true object-oriented language while C++ is basically C with object-oriented extension.
❖ Some major C++ features that were intentionally omitted from Java or significantly modified
are:
• Java does not support Operator Overloading.
• Java does not have template classes as in C++.
• Java does not support multiple inheritance of classes. This is accomplished using a new
feature called “interface”.
• Java does not support global variables. Every variable and method is declared within a class
and forms part of that class.
• Java does not use Pointers.
• Java has replaced the destructor function with a finalize() function.
• There are no header files in Java.
❖ Java is strongly associated with the Internet because of the fact that the first application program
7
written in Java was HotJava, a Web browser to run applets on Internet.
❖ Internet users can use Java to create applet programs and run them locally using a “Java-enabled
browser” such as HotJava.
❖ They can also use a Java-enabled browser to download an applet located on a computer
anywhere in the Internet and run it on his local computer.
1.8 Java and World Wide Web
❖ World Wide Web (WWW) is an open-ended information retrieval system designed to be used
in the Internet’s distributed environment. This system contains what are known as Web pages
that provide both information and controls.
❖ Java was meant to be used in distributed environments such as Internet. Since, both the Web
and Java share the same philosophy, Java could be easily incorporated into the Web system.
❖ With the support of Java, the Web has become more interactive and dynamic. Java
communicates with a Web page through a special tag called <APPLET>.
Exercises:
1. What is Java?
2. Write short notes on History of Java.
3. Discuss briefly about the Evolution of Java.
4. What do you mean by Java “Applets” and “Applications”?
5. Explain the Features of Java.
6. Distinguish between Java and C++.
7. Write short notes on Java and Internet.
8. Write a brief note on Java and WWW.
**************************
*******************************************************************************
Chapter 2 An Overview of Java
*******************************************************************************
2.1 Definition of OOP
❖ Object-Oriented Programming is an approach that provides a way of modularizing
programs by creating partitioned memory area for both data and functions that can be
used as templates for creating copies of such modules on demand.
8
2.2 Object-Oriented Paradigm
❖ OOP allows us to decompose a problem into a number of smaller entities called Objects and
then build dataand functions (known as methods in Java) around these entities.
❖ The combination of data and functions make up an object.The data of an object can be accessed
only by the methods associated with that object. However, methods of one object can access
the methods of other objects.
2.3 Basic Concepts of Object-Oriented Programming
❖ Object Oriented Programming is a method of implementation in which programs are
organized as cooperative collection of objects, each of which represents an instance of a class,
and whose classes are all members of a hierarchy of classes united via inheritance relationships.
❖ The general concepts of OOP are as follows:
1. Classes
❖ Collection of objects is called class. It is a logical entity.
❖ A class can also be defined as a blueprint from which we can create an individual object. Class
doesn't consume any space.
2. Objects
❖ An Object can be defined as an instance of a class. An object contains an address and takes up
some space in memory.
❖ Any entity that has state and behavior is known as an object. For example, a chair, pen, table,
keyboard, bike, etc.
❖ In other terms, objects are the runtime entities of a class. For example, the object for Student
class can be created as follows:
Student st1;
st1 is the runtime entity of Student and it will have the data members Name, DOB and marks
and the functions Total, Average and Display can be used by st1 to calculate.
3. Abstraction
❖ Abstraction refers to the act of representing essential features without including the
explanations. Since the classes use the concept of data abstraction, they are known as Abstract
Data Types.
4. Encapsulation
❖ The wrapping up of data and functions into a single unit is called as encapsulation.
❖ A java class is the example of encapsulation.
5. Inheritance
❖ Inheritance is the process by which objects of one class acquire the properties of another class.
9
❖ For example, a student as well as a staff is a Person. Both have some common properties.
Inheritance allows the programmer to reuse defined properties.
6. Polymorphism
❖ Polymorphism means the ability to take more than one form. For example, consider the
operation of addition.
• For two numbers, the operation will generate a sum.
• If the operands are strings, then the operation would produce a third string by concatenation.
7. Dynamic Binding
• Real-time Systems
• Simulation and Modeling
• Object-Oriented Databases
• Hypertext, Hypermedia and Expertext
• AI and Expert Systems
• Neural Networks and Parallel Programming
• Decision Support and Office Automation Systems
• CIM/CAD/CAM Systems
2.6 The Bytecode
❖ The output of a Java compiler is called a bytecode.
❖ Bytecode is a highly optimized set of instructions designed to be executed by the Java run-time
system, which is called the Java Virtual Machine (JVM). That is, in its standard form, the JVM
is an interpreter for bytecode.
❖ Translating a Java program into bytecode helps makes it much easier to run a program in a wide
variety of environments. The interpretation of bytecode is the easiest way to create truly portable
programs.
2.7 Java Environment
❖ Java environment includes a large number of development tools and hundreds of classes and
methods. The development tools are part of the system known as Java Development Kit (JDK)
and the classes and methods are part of the Java Standard Library (JSL), also known as the
Application Programming Interface (API).
Java Development Kit
❖ The Java Development Kit comes with a collection of tools that are used for developing and
running Java programs. They include:
• appletviewer (for viewing Java applets)
• javac (Java compiler)
• java (Java Interpreter)
• javap (Java disassemble)
• javah (for C header files)
• javadoc (for creating HTML documents)
• jdb (Java debugger)
❖ Table 1.1 lists these tools and their descriptions.
Tool Description
appletviewer Enables us to run Java applets (without actually using a Java-compatible
11
browser).
Java interpreter, which runs applets and applications by reading and
java interpreting bytecode files.
The Java compiler, which translates Java source code to bytecode files that
javac
the interpreter can understand.
javadoc Creates HTML format documentation from Java source code files.
javah Produces header for use with native methods.
Java disassembler, which enables us to convert bytecode files into a
javap
program description.
jdb Java debugger, which helps us to find errors in our programs.
Table 1.1: Java Development Tools
Application Programming Interface
❖ The Java Standard Library (or API) includes hundreds of classes and methods grouped into
several functional packages.
• Language Support Package: A collection of classes and methods required for
implementing basic features of Java.
• Utilities Package: A collection of classes to provide utility functions such as date and time
functions.
• Input / Output Package: A collection of classes required for input / output manipulation.
• Networking Package: A collection of classes for communicating with other computers via
Internet.
• AWT package: The Abstract Window Tool Kit package contains classes that implements
platform-independent graphical user interface.
• Applet Package: This includes a set of classes that allows us to create Java applets.
2.8 Structure of a Java Program
❖ Every Java program is written as a collection of one or more classes. Each class contains data
members and methods that act upon data members.
❖ The methods contain executable statements. Even though a Java program contain many classes,
only one of them should contain the main() method.
❖ The execution of a Java program starts with the main() method.
❖ A Java program can contain one or more sections as shown below.
Documentation Section
Package Statement
Import Statements
Interface Statements
Class Definitions
<---------- Essential
Documentation Section
❖ The documentation section contains a set of comment lines. Java supports three types of
comments.
1. Single-line Comment
2. Multiline Comment
3. Documentation Comment
❖ A single line comment starts with // and ends in the single line.
Example:
// The following program will calculate the bonus
❖ A multiline comment spreads over several lines. Such a comment begins with /* and ends with
*/
Example:
14
one of them must include a main method to initiate the execution.
This line contains a number of keywords, public, static and void.
-----------------------------------------------------------------------------------------------------------------------
public The keyword public is an access specifier that declares the main method as unprotected
and therefore making it accessible to all other classes. This is similar to the C++ public
modifier.
Static Next appears the keyword static, which declares this method as one that belongs to the
entire class and not a part of any object of the class. The main must always be declared
as static since the interpreter uses this method before any objects are created.
void The type modifier void states that the main method does not return any value.
-----------------------------------------------------------------------------------------------------------------------
All parameters to a method are declared inside a pair of parentheses. Hence, String args[] declares
a parameter named args, which contains an array of objects of the class type String.
The Output Line
The only executable statement in the program is
System.out.println(“Welcome to Java Programming.”);
This is similar to the printf() statement of C or cout<<construct of C++. Since Java is a true object
oriented language, every method must be part of an object. The println method is a member of the
out object, which is a static data member of System class This line prints the string
Welcome to Java Programming.
on the screen. The method always appends a newline character to the end of the string. This means
that any subsequent output will start on a new line. Every Java statement must end with a semicolon.
2.10 Java Character Set
❖ The set of characters allowed in Java constitutes its character set. All the constituents of a
Java program, such as identifiers, literals, keywords, expression and statements are written only
by using the characters in the following character set:
Numerals : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Alphabets : a, b, c, d, e, f, g, h, I, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
: A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z
15
Whitespace
❖ A space, tab, or newline is called a whitespace in Java.
❖ Java is a free-form language. This means that we do not follow any special indentation rules.
There must be at least one whitespace character between each token that was not already
delineated by an operator or separator.
Identifiers
❖ Identifiers are names given to classes, methods, variables, objects, arrays, packages and
interfaces in a program. These are user defined names.
Rules:
• Identifiers are formed with alphabets, digits, underscore and dollar sign characters.
• The first character must be an alphabet.
• Uppercase and lowercase letters are distinct.
• They can be of any length.
• They are case sensitive.
Literals
Operators
❖ An operator is a symbol which represents some operation that can be performed on data. There
are eight operators in Java. They are Arithmetic operators, Relational operators, Logical
operators, Shorthand assignment operators, Increment and decrement operators, Conditional
operator, Bitwise operators, Special operators.
Separators
❖ A symbol that is used to separate one group from another group is called a separator.
16
❖ The most commonly used separator in Java is the semicolon.It is used to terminate statements.
❖ The separators are shown in the following table:
Java Keywords
❖ Java Keywords are also known as as reserved words.
❖ Java Keywords are predefined in JAVA and they are used to represent some predefined actions.
❖ We cannot use them as names for variables, classes, methods and so on.
❖ All keywords are to be written in lower-case letters.
❖ In addition to the keywords, Java reserves the following: true, false, and null. These are values
defined by Java.
❖ There are 61 keywords currently defined in the Java language (Table 2.1)
17
this throw throws to transient transitive
try uses void volatile while with
Table 2.1: Java Keywords
2.12 Java Statements
❖ A statement is an executable combination of tokens ending with a semicolon (;) mark. Java
statements are instructions that tell the programming language what to do. Java implements
several types of statements described in table below.
18
Figure 2.1: Classification of Java Statements
2.13 Implementing a Java Program
❖ Implementation of a Java application program involves a series of steps. They include:
• Creating the program
• Compiling the program
• Running the program
Creating the Program
❖ To enter the program, we can use any word processor, such as MS-Word or the Windows
Notepad editor or the DOS editor. Assume that we have entered the following program:
Note: All Java source files will have the extension java. If a program contains multiple classes,
the file name must be the classname of the class containing the main method.
❖ To compile the Example program, execute the compiler, javac, specifying the name of the source
file on the command line as shown here:
C:\JDK1.6.0_01\BIN>javac Example.java
19
❖ The javac compiler creates a file called Example.class that contains the bytecode version of the
program. The Java bytecode is the intermediate representation of our program that contains the
instructions the Java interpreter will execute. Thus, the output of javac is not code that can be
directly executed.
Running the Program
❖ To actually run the program, we must use the Java interpreter called java. To do so, pass the
class name Example as a command-line argument as shown here:
C:\JDK1.6.0_01\BIN>java Example
When the program is run, the following output is displayed:
Welcome to Java Programming.
❖ When Java source code is compiled, each individual class is put into its own output file named
after the class and using the .class extension.
2.14 Java Virtual Machine
❖ The JVM (Java Virtual Machine) is the environment in which Java programs execute.
❖ It is software that is implemented on top of real hardware and operating system.
❖ JVM is Write Once-Run Anywhere (WORA) software.
❖ JVM forms part of large system JRE.
❖ JVM's main job is interpreting java byte code and translating this into actions or OS calls.
❖ JVM is OS dependent which makes java source code as machine independent.
2.15 Command Line Arguments
❖ Command line arguments are parameters that are supplied to the application program at
the time of invoking it for execution.
❖ We can write Java programs that can receive and use the arguments provided in the command
line. The signature of the main() method used in our earlier programs:
public static void main(String args[])
args is declared as an array of strings. Any arguments provided in the command line (at the
time of execution) are passed to the array args as its elements. We can simply access the array
elements and use them in the program as we wish.
The individual elements of an array are accessed by using an index or subscript like args[i].
The value of i denotes the position of the elements inside the array.
Example:
21
*******************************************************************
Chapter 3 Data Types and Variables
*******************************************************************
3.1 Data Types
❖ Data Types specify the size and type of values that can be stored.
❖ Java language is rich in its data types. Java has four main primitive data types built into the
language.
• Integers: This group includes byte, short, int, and long, which are for whole-valued signed
numbers.
• Floating Point numbers: This group includes float and double, which represent numbers with
fractional precision.
• Characters: This group includes char, which represents symbols in a character set, like letters
and numbers.
• Boolean: This group includes boolean, which is a special type for representing true/false values.
❖ Data Types in Java under various categories are shown in Figure 3.1
Integer Types
❖ Java defines four integer types: byte, short, int, and long. All of these are signed, positive and
negative values. Java does not support unsigned, positive-only integers.
❖ The width and ranges of these integer types vary widely, as shown in this table:
------------------------------------------------------------------------------------------------------
Type Size Range
------------------------------------------------------------------------------------------------------
byte 1 byte -128 to 127
short 2 bytes -32,768 to 32,767
int 4 bytes -2,147,483,648 to 2,147,483,647
long 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
-----------------------------------------------------------------------------------------------------------
22
Figure 3.2: Integer Data Types
byte
❖ The smallest integer type is byte. This is a signed 8-bit type that has a range from -128 to 127.
❖ Variables of type byte are especially useful when we are working with a stream of data from a
network or file.
❖ Byte variables are declared by use of the byte keyword.
Example:
byte b,c;
short
❖ short is a signed 16-bit type. It has a range from -32,768 to 32,767.
❖ It is probably the least-used Java type. This type is mostly applicable to 16-bit computers.
Example:
short S;
short t;
int
❖ The most commonly used integer type is int. It is a signed 32-bit type that has a range from -
2,147,483,648 to 2,147,483,647.
❖ In addition to other uses, variables of type int are commonly employed to control loops and to
index arrays.
Example:
int a,b,c;
long
❖ long is a signed 64-bit type and is useful for those occasions where an int type is not large
enough to hold the desired value.
❖ The range of a long is quite large. This makes it useful when big, whole numbers are needed.
Example:
long distance;
Floating-Point Types
❖ Floating-point numbers, also known as real numbers, are used when evaluating expressions that
require fractional precision.
❖ Floating point types are used to hold numbers containing fractional parts such as 27.59 and -
23
1.375.
❖ There are two kinds of floating-point types, float and double, which represent single- and
double-precision numbers, respectively.
24
Example:
char ch;
ch=’X’;
Boolean Type
❖ Boolean type is used when we want to test a particular condition during the execution of the
program.
❖ There are only two values that a Boolean type can take: true or false. Boolean type is denoted by
the keyword boolean and uses only one bit of storage.
❖ Boolean values are often used in selection and iteration statements.
Example:
boolean flag;
flag=true;
3.2 Constants (Literals)
❖ Constant refers tofixed values that do not change during the execution of a program.
❖ Constants are declared using the final keyword.
❖ Java support several types of constants as follows:
Integer Constants
❖ An integer constant refers to a sequence of digits. There are three types of integers, namely,
decimal integer, octal integer, and hexadecimal integer.
❖ Decimal integers consist of a set of digits, 0 through 9, preceded by an optional minus sign.
❖ Valid examples of decimal integer constants are:
123 -321 0 654321
❖ Embedded spaces, commas, and non-digit character are not permitted between digits. For
example,
15 750 20,000 $1000
are illegal numbers.
❖ An octal integer constant consists of any combination of digits from the set 0 through 7,
with a leading 0.
❖ Some examples of octal integer are:
037 0 0435 0551
❖ A sequence of digits preceded by 0x or 0X is considered as hexadecimal integer. They may
also include alphabets A through F or a through f. A letter A through F represents the numbers
10 through 15.
❖ Following are the examples of valid hex integers.
0x2 0x9F 0xbcd 0x
25
Real Constants
❖ A number with a decimal point is called a real constant or a floating point constant.
❖ Some examples of real constants are:
0.0083 -0.75 435.36
❖ A real number may also be expressed in exponential (or scientific) notation.
❖ For example, the value 215.65 may be written as 2.1565e2 in exponential notation.e2 means
multiply by 102. The general form is:
mantissa e exponent
3.3 Variables
❖ A variable is an identifier that denotes a storage location used to store a data value.
❖ A variable may take different values at different times during the execution of the program.
❖ A variable name can be chosen by the programmer in a meaningful way so as to reflect what it
represents in the program.
❖ Some examples of variable names are:
i) average
ii) height
iii) total_height
iv) classStrength
Rules:
• A variable name may consist of alphabets, digits, the underscore (_) and the dollar character.
27
3.4 Giving Values to Variables
❖ A variable must be given a value after it has been declared before it is used in an expression.
❖ This can be declared in two ways:
• By using an assignment statement
The assignment statement is used to assign a value to a variable.
variableName=value;
type variableName=value;
• By using a read Statement
The readLine() method is used to read a line of text from the keyboard.
int n=Integer.parseInt(br.readLine());
3.5 Scope of Variables
❖ The area of the program where the variable is accessible (i.e., usable) is called its scope.
❖ Java allows variables to be declared within any block. A block defines the scope.
❖ Java variables are classified into three parts:
• Instance Variables
❖ A variable declared outside the method/block/constructor but inside the body is called an
instance variable.
❖ When an object of the class is created then the object also creates one copy of the instance
variable and destroyed when the object is destroyed.
❖ We can specify the access specifier for instance variables. By default, the default access
specifier will be used.
❖ Initialization of Instance Variable is not Mandatory. Its default value is depending on the data
type of variable.
❖ These variables can be accessed by creating objects.
• Class Variables
❖ Class Variables are declared inside a class.
❖ Class variables are global to a class and belong to the entire set of objects that class creates.
❖ Only one memory location is created for each class variable.
• Local Variables
❖ A variable declared inside the body of a method or block or constructor is called a local
variable.
❖ We can’t access these variable outside the method. These variables are created in memory
when the function/block/constructor is called. After completing the execution of
function/block/constructor these variables are destroyed by JVM.
❖ We can access these variables only within that block because the scope of these variables exists
only within the block.
28
❖ The initialization of the local variables is mandatory. If we don’t initialize the variable compiler
will throw run time exception.
3.6 Symbolic Constants
❖ Memory locations whose values cannot be changed within a program are called Constants
or Symbolic Constants.
❖ A constant is declared as follows:
final type symbolic-name=value;
Examples:
final int PASS_MARK=50;
final float PI=3.14159;
Note:
• Symbolic names take the same form as variable names. But, they are written in CAPITALS
because they are distinguished them from normal variable names.
• After declaration, they should not be assigned any other value within the program.
• They can't be declared inside of a class. They should be declared as beginning of the class.
3.7 Type Conversion and Type Casting
❖ The two terms Type Conversion and the Type Casting are used in a program to convert one
data type to another data type.
Type Conversion
❖ Type Conversion allows a compiler to convert one data type to another data type at the
compile time of a program or code.
❖ Converting a lower data type to a higher data type is known as widening.
❖ In this case the conversion is done automatically therefore, it is known as implicit type
casting.
❖ In this case both data types should be compatible with each other.
Example 1:
int x = 20;
long y = x; // Automatic Conversion
Example 2:
30
Differences Between Type Casting and Type Conversion
Sl. No. Type Casting Type Conversion
1 Type Casting is a mechanism in which Type Conversion allows a compiler to
one data type is converted to another data convert one data type to another data type at
type by a programmer. the compile time of a program or code.
2 It can be used both compatible data type Type Conversion is only used with
and incompatible data type. compatible data types.
3 It requires a programmer to manually The compiler automatically converts it at the
casting one data into another type. run time of a program.
4 It is used while designing a program by the It is used or take place at the compile time of
programmer. a program.
5 When casting one data type to another, the When converting one data type to another,
destination data type must be smaller than the destination type should be greater than
the source data. the source data type.
6 It is also known as narrowing conversion It is also known as widening conversion
because one larger data type converts to a because one smaller data type converts to a
smaller data type. larger data type.
7 It is more reliable and efficient. It is less efficient and less reliable.
8 There is a possibility of data loss in type Possibility of data loss is very less
casting.
9 float b = 3.0; int x = 5, y = 2, c;
int a = (int) b float q = 12.5, p;
p = q/x;
Exercises:
1. Define Data Type.
2. Explain the various Data Types available in Java.
3. What are Constants?
4. Explain the various Constants available in Java.
5. Define Variable.
6. How will you declare a Variable?
7. Discuss briefly about the Scope of Variables.
8. Define Symbolic Constants.
9. Define Type Conversion.
10. What is Type Casting?
11. Distinguish between Type Casting and Type Conversion.
**************************
31
*******************************************************************************
Chapter 4 Operators
*******************************************************************************
4.1 Java Operators
❖ Operators are used to perform operations on variables and values.
❖ Java provides a rich set of operators to manipulate variables.
❖ Java Operators can be classified into a number of related categories as below:
• Arithmetic Operators
• Relational Operators
• Logical Operators
• Assignment Operators
• Conditional Operators
• Bitwise Operators
• Special Operators
Arithmetic Operators
❖ Arithmetic Operators are used to perform common mathematical operations.
❖ The following table lists the Arithmetic Operators:
Operator Meaning
+ Addition or Unary Plus
- Subtraction or Unary Minus
* Multiplication
/ Division
% Modulus
++ Increment
-- Decrement
Relational Operators
❖ Relational Operators in Java are used to compare two or more objects.
❖ Java supports six relational operators.
❖ The following table lists the relational operators:
Operator Meaning
== Equal to
!= Not Equal to
> Greater than
< Less than
>= Greater than or equal to
32
<= Less than or equal to
Logical Operators
❖ Logical Operators return a true or false value based on the state of the variables.
❖ Java has three Logical or Boolean Operators.
❖ The following table lists the logical operators:
Operator Meaning
36
❖ Table 4.1 shows the order of precedence for Java operators, from highest to lowest.
37
max(a,b) Returns the maximum of a and b.
min(a,b) Returns the minimum of a and b.
Note: x and y are double type parameters, a and b may be ints, longs, floats and doubles.
Simple Java Programs
//Java program to find the Area of the Circle
//area.java
import java.io.*;
class area
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
float r,a;
final float pi=3.14f;
System.out.println("Enter the radius");
r=Float.parseFloat(br.readLine());
a=pi*r*r;
System.out.println("Area of the Circle="+a);
}
}
Output:
Enter the radius
10
Area of the Circle=314
-----------------------------------------------------------------------------------------------------------------------
//Java program to add two numbers
//addnos.java
import java.io.*;
class addnos
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int a,b,c;
System.out.println("Enter the first number");
a=Integer.parseInt(br.readLine());
System.out.println("Enter the second number");
b=Integer.parseInt(br.readLine());
c=a+b;
System.out.println("Sum="+c);
}
}
Output:
38
Enter the first number
25
Enter the second number
35
Sum=60
Exercises:
1. Explain the various Operators available in Java.
2. Define Conditional Operator.
3. What are Logical Operators?
4. What is an instanceOf operator?
5. List out the Bitwise Operators.
6. Discuss briefly about operator precedence in Java.
7. Explain the various methods of the Math class with suitable example.
8. Write a Java program to perform arithmetic operations.
**************************
39
************************************************************
Chapter 5 Control Statements
*********************************************************
5.1 Introduction
❖ The Control Statements are used for controlling the execution of the program.
❖ There are three main categories of control statements;
• Selection Statements: if and switch.
• Looping Statements: while, do-while and for.
• Transfer Statements: break, continue and return.
5.2 Selection Statements
❖ Java supports two selection statements - if and switch. These statements allow us to control the
flow of the program.
❖ Depending upon the expressions or values, the corresponding blocks/statements of code will be
executed or by passed.
❖ The two statements are
• if statement is a conditional branch statement. This is a two way branch statement.
Depending upon the whether a condition is true or false, the corresponding code is executed.
• switch statement is a multiway branch statement. Depending upon the value used for
switching, the corresponding code is executed.
❖ These two statements are very powerful and are used widely across any application. They
provide effective solutions for branching problems.
1. The if Statement
❖ The if statement is a powerful decision making statement and is used to control the flow of
execution of statements.
❖ It is basically a two-way decision statement and is used in conjunction with an expression.
❖ The if statement may be implemented in different forms depending on the complexity of
conditions to be tested.
i) Simple if statement
ii) if…else statement
iii) Nested if…else statement
iv) if-else-if Ladder
i) Simple if Statement
❖ The if statement executes a block of code only if the specified condition is true.
❖ If the condition is false, then the if block is skipped and execution continues with the rest of the
program.
Syntax:
40
if (Condition)
{
//Statements;
}
41
{
//Statements;
}
Here, Condition is a boolean expression. It returns either true or false.
Example :
//Java program to check whether the given number is odd or even
//oddeven.java
import java.io.*;
class oddeven
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n,r;
System.out.println("Enter the number");
n=Integer.parseInt(br.readLine());
r=n%2;
if (r==0)
System.out.println("The given number is even");
else
System.out.println("The given number is odd");
}
}
Output:
Enter the number
5
The given number is odd
iii) Nested if…else Statement
❖ An if…else statement within another if…else statement is called nested if…else statement.
❖ When a series of decisions are involved, we may have to use more than one if…else statement
in nested form as follows:
if (Condition-1)
{
if (Condition-2)
{
//Statement-1;
}
else
{
//Statement-2;
}
}
else
{
//Statement-3;
42
}
//Statement-x;
❖ If the Condition-1 is false, Statement-3 will be executed; otherwise, it continues to perform the
second test. If the condition-2 is true, the Statement-1 will be evaluated; otherwise the
Statement-2 will be evaluated and then the control is transferred to the Statement-x.
Example:
//Java program to find the biggest among three numbers using nested if statement
//big3.java
import java.io.*;
class big3
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int a,b,c;
System.out.println("Enter the first number");
a=Integer.parseInt(br.readLine());
System.out.println("Enter the second number");
b=Integer.parseInt(br.readLine());
System.out.println("Enter the third number");
c=Integer.parseInt(br.readLine());
if ((a>b) && (a>c))
{
System.out.println("Biggest="+a);
}
if ((b>a) && (b>c))
{
System.out.println("Biggest="+b);
}
else
{
System.out.println("Biggest="+c);
}
}
}
Output:
Enter the first number
50
Enter the second number
40
Enter the third number
43
30
Biggest=50
iv) if…else…if Ladder
❖ An if...else...if ladder can be used to execute one block of code among multiple blocks.
Syntax:
if(Condition1)
{
//Statements
}
else if(Condition2)
{
//Statements
}
.
.
.
else
{
//Statements
}
❖ This construct is known as the else if ladder.
❖ The conditions are evaluated from top (of the ladder) to bottom.
❖ When the test condition is true, code inside the body of that if block is executed. And,
program control jumps outside the if...else...if ladder.
❖ If all test expressions are false, code inside the body of else are executed.
Example:
❖ The value of the expression is evaluated and compared with each of the values in the case
statements.
❖ If a match is found, the code sequence following that case statement is executed. If none of the
constants matches the value of the expression, then the default statement is executed. However,
the default statement is optional.
❖ The break statement is used inside the switch to terminate a statement sequence.
Example:
//Java program to print the days of the week using switch statement
45
//days_of_week.java
import java.io.*;
class days_of_week
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int d;
System.out.println("Enter the day code");
d=Integer.parseInt(br.readLine());
switch(d)
{
case 1 : System.out.println("Sunday");
break;
case 2 : System.out.println("Monday");
break;
case 3 : System.out.println("Tuesday");
break;
case 4 : System.out.println("Wednesday");
break;
case 5 : System.out.println("Thursday");
break;
case 6 : System.out.println("Friday");
break;
case 7 : System.out.println("Saturday");
break;
default : System.out.println("Wrong day code");
}
}
}
Output:
Enter the day code
2
Monday
Nested switch Statement
❖ A switch statement inside another switch statement is known as nested switch statement.
❖ The inner switch statement will be part of any case of an outer switch.
❖ The inner switch statement will be executed only if the outer switch statement condition is true.
Example:
//Java Program to implement Nested Switch Statement
import java.io.*;
public class ExampleOfNestedSwitch
{
public static void main(String args[]) throws IOException
{
int year, marks;
BufferedReader br=new BufferedReader(New InputStreamReader(System.in));
46
System.out.println(“Enter the year”);
year=Integer.parseInt(br.readLine());
System.out.println(“Enter the marks”);
marks=Integer.parseInt(br.readLine());
switch(year)
{
case 1:
System.out.println("First year students are not eligible for scholarship ");
break;
case 2:
System.out.println("Second year students are not eligible for scholarship");
break;
case 3:
switch(marks)
{
case 50:
System.out.println("You are not eligible for scholarship");
break;
case 80:
System.out.println("Congrats! You are eligible for scholarship");
break;
}
break;
default:
System.out.println("Please enter valid year");
}
}
}
Output:
Enter the year
3
Enter the marks
80
Congrats! You are eligible for scholarship
if…else switch
If statement is used to select among two The switch statement is used to select among
alternatives multiple alternatives.
It contains either logical or equality It contains a single expression which can be either a
expression. character or integer variable.
It evaluates all types of data, such as integer, It evaluates either an integer, or character.
floating-point, character or Boolean.
First, the condition is checked. If the condition It executes one case after another till the break
is true then 'if' block is executed otherwise keyword is not found, or the default statement is
'else' block executed.
47
If the condition is not true, then by default, else If the value does not match with any case, then by
block will be executed. default, default statement is executed.
It is difficult to edit the if-else statement, if the It is easy to edit switch cases as, they are recognized
nested if-else statement is used. easily.
If there are multiple choices implemented If we have multiple choices then the switch
through 'if-else', then the speed of the statement is the best option as the speed of the
execution will be slow. execution will be much higher than 'if-else'.
❖ The while loop executes a block of code as long as a specified condition is true.
❖ If the number of iterations is not fixed, it is recommended to use a while loop.
❖ It is also known as an Entry-Controlled loop.
Syntax:
while(Condition)
{
//Body of while loop
}
❖ The Condition can be any Boolean expression.
❖ The body of while loop will be executed as long as the conditionl expression is true.
❖ When the Condition becomes false, control passes to the next line of code immediately
following the while loop.
Example:
48
while(n>0)
{
r=n%10;
s=s+r;
n=n/10;
}
System.out.println("Sum of all digits="+s);
}
}
Output:
Enter the number
125
Sum of all digits=8
2. The do…while Statement
❖ The do...while loop executes a block of code repeatedly until the specified condition is true.
❖ The do…while loop is executed at least once because the condition is checked after the loop
body.
❖ The do…while loop is similar to the while loop, however there is a difference between them.
In while loop, the condition is evaluated before the execution of loop’s body but in do…while
loop the condition is evaluated after the execution of loop’s body.
Syntax:
do
{
//Body of the loop
}
while(Condition);
❖ The Condition can be any Boolean expression.
❖ Each iteration of the do…while loop first executes the body of the loop and then evaluates the
conditional expression. If this expression is true, the loop will repeat. Otherwise, the loop
terminates.
Example:
//Java program to print the positive integers from 1 to n
//print_digits.java
import java.io.*;
class print_digits
{
public static void main(String args[]) throws IOException
{
49
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n,i=1;
System.out.println("Enter the number");
n=Integer.parseInt(br.readLine());
do
{
System.out.println(i);
i++;
}
while(i<=n);
}
}
Output:
Enter the number
5
1
2
3
4
5
3. The for Statement
❖ The for loop is used to execute a set of statements repeatedly for a specified number of
times.
❖ It is commonly used for simple iteration.
Syntax:
for (initialization; condition; increment/decrement)
{
//Body of for loop
}
If only one statement is being repeated, there is no need for the curly braces.
1. Initialization: The initialization portion of the loop is executed first. Generally, this is an
expression that sets the value of the loop control variable, which acts as a counter that controls
the loop. The initialization expression is executed only once.
2. Condition: The condition must be a Boolean expression. If this expression is true, then the
body of the loop is executed. If it is false, the loop terminates.
3. Body of for loop: It contains a block of code that executes each time after evaluating the
condition true.
4. Increment/decrement: This is usually an expression that increments or decrements the loop
control variable.
Example:
//Java program to find the factorial value of a given number
50
//fact.java
import java.io.*;
class fact
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n;
long f=1;
System.out.println("Enter the number");
n=Integer.parseInt(br.readLine());
for(int i=1;i<=n;i++)
{
f=f*i;
}
System.out.println("Factorial Value="+f);
}
}
Output:
Enter the number
5
Factorial Value=120
5.4 Jump (Transfer) Statements
❖ Java supports three jump statements: break, continue, and return. These statements transfer
control to another part of the program.
1. The break statement
❖ The break statement is used to terminate the loop.
❖ When a break statement is encountered inside a loop, the loop is immediately terminated and the
program control resumes at the next statement following the loop.
❖ The break statement can be used in all types of loops such as for loop, while loop and do-while
loop.
Syntax:
break; // The unlabeled form
break label; // The labeled form
❖ In Java, the break statement has three uses. First, as we have seen, it terminates a statement
sequence in a switch statement. Second, it can be used to exit a loop. Third, it can be used as a
“civilized” form of goto.
i) Using break to Exit a Loop
❖ By using break, we can force immediate termination of a loop, bypassing the conditional
expression and any remaining code in the body of the loop.
51
Example:
//Java program to illustrate the break statement
//BreakExample.java
class BreakExample
{
public static void main(String args[])
{
System.out.println("Numbers 1 - 10");
for (int i = 1;i<=100;i++)
{
if (i == 5) break; // Terminate loop if i is 5
System.out.println(i);
}
}
}
Output:
Numbers 1 - 10
1
2
3
4
ii) Using break as a Form of goto
❖ The break statement can also be employed by itself to provide a “civilized” form of the goto
statement.
❖ Java does not have a goto statement. By using this form of break, we can break out of one or
more blocks of code.
Syntax:
break label;
Here, label is the name of the label that identifies a block of code. When this form of break
executes, control is transferred out of the named block of code.
To name a block, put a label at the start of it. A label is any valid Java identifier followed by
a colon. Once we have labeled the block, we can then use this label as the target of a break
statement.
Example:
//Java program to find the sum of 1 to n numbers using the break label statement
//BreakLoop.java
import java.io.*;
class BreakLoop
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n,i,s=0;
System.out.println("Enter the number");
52
n=Integer.parseInt(br.readLine());
s=s+i;
i++;
start:
if (i<=n) break start;
System.out.println(“Sum=”+s);
}
}
Output:
Enter the number
5
Sum=15
2. The continue Statement
❖ The continue statement is used to continue the loop.
❖ When a continue statement is encountered the control directly jumps to the beginning of the
loop for the next iteration instead of executing the statements of the current iteration.
❖ The continue statement is used when we do not want to execute the remaining statements in the
loop, but we do not want to exit the loop itself.
Syntax:
continue; // The unlabeled form
continue label; // The labeled form
The label name is optional, and is usually only used when we wish to return to the outermost
loop in a series of nested loops.
Example 1:
//Java program to print the odd numbers between 1 to 10
//ContinueExample.java
class ContinueExample
{
public static void main(String args[])
{
System.out.println("Odd Numbers");
for (int i = 1; i <= 10; ++i)
{
if (i % 2 == 0)
continue;
// Rest of loop body skipped when i is even
System.out.println(i);
}
}
}
Output:
Odd Numbers
1
53
3
5
7
9
Example 2:
//Using continue with a label
//ContinueLabel.java
class ContinueLabel
{
public static void main(String args[])
{
outer: for (int i=0;i<5;i++)
{
for (int j=0;j<5;j++)
{
if (j>i)
{
System.out.println();
continue outer;
}
System.out.print(“ “+(i*j));
}
}
System.out.println();
}
}
Output:
0
01
02 4
03 6 9
0 4 8 12 16
Differences Between break and continue Statements
54
return expression;
Example:
//Java Program to demonstrate continue statement
import java.io.*;
public class Test
{
int square(int s)
{
return s * s; // Return a square value.
}
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
Test t = new Test();
int n;
System.out.println(“Enter the value of n”);
n = Integer.parseInt(br.readLine());
int sq = t.square(n);
// Displaying the result.
System.out.println("Square of “ + n +”= " +sq);
}
}
Output:
Enter the value of n
10
Square of 10 = 100
Nested Loops
❖ Nested loop means a loop statement inside another loop statement.
❖ When we "nest" two loops, the outer loop takes control of the number of complete repetitions
of the inner loop.
1. Nested for loop
❖ Placing one for loop within the body of another for is called nested for loop.
Syntax:
for ( initialization; condition; increment/decrement )
{
for ( initialization; condition; increment/decrement )
{
// Statement of inner loop
}
// Statement of outer loop
}
Example:
//Demonstrate Nested for loop
55
//NestedForLoop.java
public class NestedForLoop
{
public static void main(String[] args)
{
for(int i=1;i<=5;i++)
{
for(int j=1;j<=i;j++)
{
System.out.print(i);
}
System.out.println();
}
}
}
Output:
1
22
333
4444
55555
2. Nested while loop
❖ A nested while loop is a while statement inside another while statement
Syntax:
while(condition)
{
while(condition)
{
// Statement of inner loop
}
// Statement of outer loop
}
Example:
//Java program to demonstrate nested while loop
class NestedWhileExample
{
public static void main(String args[])
{
int outer = 1;
while(outer < 3)
{
int inner = 5;
while(inner < 8)
{
System.out.println(outer + " " + inner);
56
inner++;
}
outer++;
}
}
}
Output:
15
16
17
25
26
27
**************************
58
************************************************************
Chapter 6 Arrays
************************************************************
6.1 Definition
❖ An Array is a group of contiguous or related data items that share a common name.
❖ Arrays are used to store multiple values in a single variable.
❖ The individual items in an array are called elements.
❖ Array in Java is index based, first element of the array is stored at 0 index.
Advantages of Arrays in Java
• Java arrays enable us to access any element randomly with the help of indexes.
• It is easy to store and manipulate large data sets.
Disadvantages of Arrays in Java
• The size of the array cannot be increased or decreased once it is declared—arrays have a fixed
size.
• Java cannot store heterogeneous data. It can only store a single type of primitives.
6.2 Types of Arrays
❖ There are two types of arrays.
1. One-Dimensional Arrays
2. Multidimensional Arrays
1. One-Dimensional Arrays
❖ A list of items can be given one variable name using only one subscript and such a variable
is called a single-subscripted variable or a one-dimensional array.
❖ For example, if we want to represent a set of five numbers, say (35, 40, 20, 57, 19), by an array
variable number, then we may create the variable number as follows:
int number[]=new int[3];
❖ The values to the array elements can be assigned as follows:
number[0]=35;
number[1]=40;
number[2]=20;
❖ These elements may be used in programs just like any other Java variable.
❖ The subscript of an array can be integer constants, integer variables like i, or expressions that
yield integers.
Creating an Array
❖ Creation of an array involves three steps:
1. Declare the array.
2. Create memory locations.
59
3. Put values into the memory locations.
Declaration of Arrays
❖ One-Dimensional Arrays in Java can be declared as follows:
DataType[]ArrayName;
DataType ArrayName[];
DataType []ArrayName;
Here,
• DataType can be a primitive data type (int, char, Double, byte etc.) or Non-primitive
data (Objects).
• ArrayName is the name of an array
• [ ] is called subscript.
Examples:
int number[];
int[] number;
int []number;
float average[];
float[] average;
float []average;
Creation of Arrays
❖ Java allows us to create arrays using the new operator only, as shown below:
ArrayName = new DataType[Size];
where:
ArrayName is the name of the array to be created.
Size Specifies the size of the array. The size should be an integer value or a variable that contains
an integer value.
Examples:
number=new int[5];
average=new float[10];
These lines create necessary memory locations and designate them as int and float respectively.
Now, the variable number refers to an array of 5 integers and average refers to an array of 10
floating point values.
❖ It is also possible to combine the two steps – declaration and creation into one as shown below:
int number[]=new int[5];
Initialization of Arrays
❖ To initialize the Array we have to put the values at each index of array.
❖ This is done using the array subscripts as shown below:
arrayname[subscript]=value;
60
Example:
number[0]=35;
number[1]=40;
number[2]=20;
number[3]=57;
number[4]=19;
❖ Java creates arrays starting with a subscript of 0 and ends with a value one less than the size
specified.
❖ We can also initialize arrays automatically in the same way as ordinary variables when they are
declared, as shown below:
datatype arrayName[] = {value1, value2, …valueN}
• If we choose datatype of an array is int then values should be int type. It means a type of
value is totally dependent on datatype of an array.
• Value1 will be store at 0 indexes, value2 in 1 index and so on.
• The size of the array depends upon how many values we are providing at the time of
initialization.\
Example:
int number[]={35,40,20,57,19};
Accessing Java Array Elements using for Loop
❖ Each element in the array is accessed via its index.
❖ The index begins with 0 and ends at (total array size)-1.
❖ All the elements of array can be accessed using Java for Loop.
Example:
for (int i=0;i<10;i++)
{
sum=sum+a[i];
}
Array Length
❖ The length property is used to find the length of the array.
Example:
int size=a.length;
Example:
2. Multidimensional Arrays
❖ Multidimensional Arrays are actually arrays of arrays.
❖ Each element of a multidimensional array is an array itself.
❖ Data in multidimensional arrays are stored in tabular form.
❖ The representation of the elements is in rows and columns. Thus, we can get a total number of
elements in a Multidimensional array by multiplying row size with column size.
62
❖ The simplest of the multidimensional array is a two-dimensional array. A simple definition of
2D arrays is: A 2D array is an array of one-dimensional arrays.
❖ In Java, a two-dimensional array is stored in the form of rows and columns and is represented
in the form of a matrix.
❖ The general declaration of a two-dimensional array is,
DataType [][] ArrayName;
Here,
DataType = Data Type of elements that will be stored in an array.
ArrayName = Name of the two-dimensional array.
❖ We can create a 2D array using new as follows:
DataType [] [] ArrayName = new DataType[Row_Size][Column_Size];
Here,
Initializing a 2D Array
❖ There are various ways of initializing the 2d array with values. The first method is the
traditional method of assigning values to each element.
ArrayName[Row_Index][Column_Index] = Value;
Example:
int[][] MyArray = new int[2][2];
MyArray[0][0] = 1;
MyArray[0][1] = MyArray[1][0] = 0;
MyArray[1][1] = 1;
63
The above statements initialize all the elements of the given 2d array.
Example:
//Java Program to add two matrices
import java.util.*;
public class Add_Matrix
{
public static void main(String args[]) throws IOException
{
int m, n;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the number of rows:");
m = sc.nextInt();
System.out.print("Enter the number of columns:");
n = sc.nextInt();
int a[][] = new int[m][n];
int b[][] = new int[m][n];
int c[][] = new int[m][n];
System.out.println("Enter the elements of first matrix:");
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
a[i][j] = sc.nextInt();
}
}
System.out.println("Enter the elements of second matrix:");
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
b[i][j] = sc.nextInt();
}
}
System.out.println("First Matrix:");
for (int i = 0; i < m; i++)
{
for (int j = 0; j <n; j++)
{
System.out.print(a[i][j]+" ");
}
System.out.println("");
}
System.out.println("Second Matrix:");
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
64
{
System.out.print(b[i][j]+" ");
}
System.out.println("");
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
c[i][j] = a[i][j] + b[i][j];
}
}
System.out.println("Matrix after addition:");
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
System.out.print(c[i][j]+" ");
}
System.out.println("");
}
}
}
Output:
Enter the number of rows: 2
Enter the number of columns: 3
Enter the elements of first matrix:
1
2
3
4
5
6
Enter the elements of second matrix:
7
8
9
4
3
2
First Matrix:
123
456
Second Matrix:
789
65
432
Matrix after addition:
8 10 12
8 8 8
Exercises:
1. Define Array.
2. How to create an Array?
3. Write the syntax for declaring one dimensional array.
4. How will you initialize the array elements?
5. Discuss in detail about Multidimensional Array.
6. Write a Java program to implement Two Dimensional Arrays.
**************************
66
UNIT- II
*******************************************************************************
7. Classes, Objects and Methods
*******************************************************************************
7.1 Introduction
❖ The class is the logical construct upon which the entire Java language is built because it defines
the shape and nature of the object. The class forms the basis for object-oriented programming
in Java. Any concept we wish to implement in a Java program must be encapsulated in a class.
❖ Classes provide a convenient method for packing together a group of logically related data
items and functions that work on them. In Java, the data items are called fields and the
functions are called methods. Classes create objects and objects use methods to communicate
between them.
❖ The most important thing to know about a class is that it defines a new data type. Once defined,
this new type can be used to create objects of that type. Thus, a class is a template for an object,
and an object is an instance of a class.
7.2 Defining a Class
❖ A class is a user-defined data type which has data members and member functions.
❖ A class is a template or blueprint from which objects are created.
❖ A class is declared by using the class keyword.
❖ The general form of a class definition is:
class classname
{
type variable1;
type variable2;
............
type variableN;
type methodname1(parameter-list)
{
// body of method
}
type methodname2(parameter-list)
{
// body of method
}
….
type methodnameN(parameter-list)
{
// body of method
}
}
❖ The data, or variables, defined within a class are called instance variables. The code is
contained within methods. Collectively, the methods and variables defined within a class are
called members of the class.
67
❖ Variables defined within a class are called instance variables because each instance of the class
(i.e. each object of the class) contains its own copy of these variables. Thus, the data for one
object is separate and unique from the data for another.
Example:
class Rectangle
{
int length;
int width;
void getData(int x, int y)
{
length=x;
width=y;
}
}
The class Rectangle contains two integer type instance variables. These variables are only declared
and therefore no storage space has been created in the memory. Instance variables are also known
as member variables.
The method has a return type of void because it does not return any value. We pass two integer
values to the method, which are then assigned to the instance variables length and width. The
getData() method is basically added to provide values to the instance variables.
7.3 Creating Objects
❖ An Object is an instance of a Class. When a class is defined, no memory is allocated but
when it is instantiated (i.e. an object is created) memory is allocated.
❖ Objects in Java are created using the new operator. The new operator is used to allocate
memory at runtime.
❖ It has this general form:
classname class-var=new classname();
Here, class-var is a variable of the class type being created. The classname is the name of the
class that is being instantiated. The class name followed by parentheses specifies the
constructor for the class. A constructor defines what occurs when an object of a class is created.
Example:
Rectangle rect1=new rectangle();
7.4 Distinction between a class and an object
❖ A class creates a new data type that can be used to create objects. That is, a class creates a
logical framework that defines the relationship between its members.
❖ When we declare an object of a class, we are creating an instance of that class.
❖ Thus, a class is a logical construct. An object has physical reality. That is, an object occupies
space in memory.
68
7.5 Accessing Class Members
❖ The instance variables and methods are accessed using the dot (.) operator.
❖ The syntax for accessing a class member is:
objectname.variablename
objectname.methodname(parameter-list);
Here objectnme is the name of the object, variablename is the name of the instance variable
inside the object we wish to access, methodname is the method that we wish to call, and
parameter-list is a comma separated list of “actual values” (or expressions) that must match in
type and number with the parameter list of the methodname declared in the class.
Example:
Rectangle rect1=new Rectangle();
rect1.length=15;
rect1.width=10;
We can call the getData() method on any Rectangle object to set the values of both length and
width.
Example:
Rectangle rect1=new Rectangle(); // Creating an object
rect1.getData(15,10); // Calling the method using the object
This code creates rect1 object and then passes the values 15 and 10 for the x and y parameters
of the method getData(). This method then assigns these values to length and width variables
respectively.
7.6 Assigning Object Reference Variables
❖ Object reference variables act differently than we might expect when an assignment takes place.
Example:
Rectangle r1=new Rectangle();
Rectangle r2=r1;
We might think that r2 is being assigned a reference to a copy of the object referred to by r1.
After this fragment executes, r1 and r2 will both refer to the same object. The assignment of r1
to r2 did not allocate any memory or copy any part of the original object. It simply makes r2
refer to the same object as does r1. Thus, any changes made to the object through r2 will affect
the object r1 is referring, since they are the same object.
7.7 Methods
❖ Methods are the functions that operate on instances of classes in which they are defined.
❖ Objects can communicate with each other using methods and can call methods in other classes.
❖ Classes usually consist of two things: instance variables and methods.
❖ Methods are declared inside the body of the class but immediately after the declaration of
69
instance variables.
❖ The general form of method declaration is
type methodname(parameter-list)
{
// Body of method
}
Here, type specifies the type of data returned by the method. This can be any valid type,
including class types that we create. If the method does not return a value, its return type must
be void.
The methodname can be any valid identifier that specifies the name of the method.
The parameter-list is a sequence of type and identifier pairs separated by commas. Parameters
are essentially variables that receive the value of the arguments passed to the method when it is
called. If the method has no parameters, then the parameter list will be empty.
The body actually describes the operations to be performed on the data.
❖ A method may be instructed to return a value after its execution is over. The following form of
the return statement is used.
return value;
Here, value is the value returned.
7.8 Calling Methods
❖ Calling a method is similar to calling or referring to an instance variable. The methods are
accessed using the dot notation.
Example:
// Java Application using classes and objects
// RectArea.java
import java.io.*;
class Rectangle
{
int length, width; // Declaration of variables
void getData(int x,int y) // Definition of method
{
length=x;
width=y;
}
1. Default Constructor
❖ A constructor that has no parameter is known as the default constructor.
❖ The default constructor automatically initializes all instance variables to zero.
71
❖ The general form is
constructorname() // Constructor with no argument
{
// Give initial values to data members
}
Where, constructorname is the name of the class.
Example:
// Java Application using default constructor
// RectangleArea.java
class Rectangle
{
int length, width; // Declaration of variables
Rectangle() // Default Constructor
{
length=10;
width=15;
}
int rectArea()
{
return(length*width);
}
}
class RectangleArea // Class with main method
{
public static void main(String args[])
{
Rectangle rect1=new Rectangle(); // Calling constructor
int area1=rect1.rectArea();
System.out.println("Area of the rectangle="+area1);
}
}
Output:
Area of the rectangle=150
2. Parameterized Constructors
❖ A constructor that has parameters is known as parameterized constructor
❖ The parameterized constructor is used to provide different values to distinct objects.
❖ The general format of the parameterized constructor is as follows:
constructorname(datatype arg1, datatype arg2,…datatype argN)
{
// Give initial values to data members
}
where, constructorname is the name of the class.
datatype arg1, datatype arg2,… are the list of parameters
Example:
72
// Java Application using Parameterized Constructors
// RectangleArea.java
import java.io.*;
class Rectangle
{
int length, width; // Declaration of variables
Rectangle(int x, int y) // Defining parameterized constructor
{
length=x;
width=y;
}
int rectArea()
{
return(length*width);
}
}
class RectangleArea // Class with main method
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int l, b;
System.out.println("Enter the length");
l=Integer.parseInt(br.readLine());
System.out.println("Enter the breadth");
b=Integer.parseInt(br.readLine());
Rectangle rect1=new Rectangle(l,b); // Calling constructor
int area1=rect1.rectArea();
System.out.println("Area of the rectangle="+area1);
}
}
7.10 The this keyword
❖ The this keyword is used to refer to the current object.
❖ It can be used inside the method or constructor of a class.
❖ The most common use of this keyword is to eliminate the confusion between class attributes
and the parameters with the same name.
❖ Methods declared with the keyword static (class methods) cannot use this.
Example:
// Java program that illustrates the usage of the keyword this
// ThisDemo.java
import java.io.*;
class Sample
{
int x,y;
void GetData(int x, int y)
{
this.x=x;
this.y=y;
}
73
void Display()
{
System.out.println("x="+x);
System.out.println("y="+y);
}
}
class ThisDemo
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int a,b;
System.out.println("Enter the values of a & b");
a=Integer.parseInt(br.readLine());
b=Integer.parseInt(br.readLine());
Sample obj=new Sample();
obj.GetData(a,b);
obj.Display();
}
}
Output:
Enter the values of a & b
30
40
x=30
y=40
❖ Method Overloading allows a class to define multiple methods with the same name, but
different parameters.
Example:
74
{
return (x + y);
}
public int sum(int x, int y, int z)
{
return (x + y + z);
}
public double sum(double x, double y)
{
return (x + y);
}
// Main Program
public static void main(String args[])
{
Sum_Nos S = new Sum_Nos();
System.out.println(S.sum(10, 20));
System.out.println(S.sum(10, 20, 30));
System.out.println(S.sum(10.5, 20.5));
}
}
Output:
30
60
31.0
75
id = i;
name = n;
age=a;
}
void display()
{
System.out.println(id+" "+name+" "+age);
}
public static void main(String args[])
{
Student s1 = new Student(111,"Sun");
Student s2 = new Student(222,"Chandra",16);
s1.display();
s2.display();
}
}
Output:
111 Sun 0
222 Chandra 16
7.13 Objects as Parameters
Test incrByTen()
{
Test temp=new Test(a+10);
return temp;
}
}
class RetOb
{
public static void main(String args[])
{
Test ob1=new Test(2);
Test ob2;
ob2= ob1.incrByTen();
System.out.println(" ob1.a : "+ob1.a);
System.out.println(" ob2.a : "+ob2.a);
ob2= ob2.incrByTen();
System.out.println(" ob2.a after second increase : "+ob2.a);
}
}
Output:
79
ob1.a : 2
ob2.a : 12
ob2.a after second increase : 22
7.16 Recursion
❖ Recursion is a process by which a function calls itself.
❖ A method in Java that calls itself is called recursive method.
❖ This technique provides a way to break complicated problems down into simple problems which
are easier to solve.
Example:
81
Syntax:
class Sub-classname extends Super-classname
{
// Variables and Methods
}
❖ The extends keyword indicates that we are creating a new class that derives from an existing
class.
❖ A class which is inherited is called a parent or superclass, and the new class is called child or
subclass.
Example:
// Java Application using Single Inheritance
//SingleInheritance.java
import java.io.*;
class Room
{
int length;
int breadth;
int area()
{
return (length*breadth);
}
}
class BedRoom extends Room
{
int height;
BedRoom(int x, int y, int z)
{
length= x;
breadth=y;
height=z;
}
int volume()
{
return (length*breadth*height);
}
}
class SingleInheritance
{
82
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int l,b,h;
System.out.println("Enter the length");
l=Integer.parseInt(br.readLine());
System.out.println("Enter the breadth");
b=Integer.parseInt(br.readLine());
System.out.println("Enter the height");
h=Integer.parseInt(br.readLine());
BedRoom room1=new BedRoom(l,b,h);
int area1= room1.area();
int volume1=room1.volume();
System.out.println("Area = "+area1);
System.out.println("Volume = "+volume1);
}
}
Output:
Enter the length
10
Enter the breadth
20
Enter the height
30
Area = 200
Volume = 600
The super keyword
❖ The super keyword in Java is used in subclasses to access superclass members.
❖ The most common use of the super keyword is to eliminate the confusion between superclasses
and subclasses that have methods with the same name.
❖ Super has two general forms. The first calls the superclass constructor. The second is used to
access a member of the superclass that has been hidden by a member of a subclass.
i) Using super to Call Superclass Constructors
❖ A subclass can call a constructor method defined by its superclass by use of the following form
of super:
super(parameter-list);
Here, parameter-list specifies any parameter needed by the constructor in the superclass.
super() must always be the first statement executed inside a subclass constructor.
ii) A Second Use for super
❖ The second form of super acts somewhat like this, except that it always refers to the superclass
of the sublass in which it is used.
❖ This usage has the following general form:
83
super.member
Here, member can be either a method or an instance variable.
❖ This second form of super is most applicable to situations in which member names of a subclass
hide members by the same name in the superclass.
Example:
// Java program using super to overcome name hiding.
//SuperDemo.java
import java.io.*;
class A
{
int i;
}
// Create a subclass by extending class A.
class B extends A
{
int i; // this i hides the i in A
B(int a, int b)
{
super.i=a; // i in A
i=b; // i in B
}
void show()
{
System.out.println("i in superclass: "+super.i);
System.out.println("i in subclass : "+i);
}
}
class SuperDemo
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int x,y;
System.out.println("Enter the values of x & y");
x=Integer.parseInt(br.readLine());
y=Integer.parseInt(br.readLine());
B subOb=new B(x,y);
subOb.show();
}
}
Output:
Enter the values of x & y
4
84
6
i in superclass: 4
i in subclass : 6
2. Multiple Inheritance
❖ The mechanism of inheriting the features of more than one base class into a single class is known
as multiple inheritance.
❖ Java does not support multiple inheritance but the multiple inheritance can be achieved by
using the interface.
3. Multilevel Inheritance
❖ The mechanism of deriving a class from another derived class is called multilevel
inheritance.
❖ This concept allows us to build a chain of classes as shown in Figure 7.2
4. Hierarchical Inheritance
❖ Hierarchical Inheritance is a method of inheritance where one or more derived classes are
derived from a common base class. i.e there is one super class and multiple subclasses.
❖ This form of inheritance is commonly used in Java program design.
86
Syntax:
class Subclassname1 extends Superclassname
{
// Variables and Methods
}
class Subclassname2 extends Superclassname
{
// Variables and Methods
}
Example:
// Java program to implement Hierarchical Inheritance
//HierInheritanceDemo.java
class Employee
{
float salary = 40000;
void dispSalary()
{
System.out.println("The Employee salary is :" +salary);
}
}
class PermanentEmp extends Employee
{
double hike = 0.5;
void incrementSalary()
{
System.out.println("The Permanent Employee incremented salary is :" +(salary+(salary * hike)));
}
}
class TemporaryEmp extends Employee
{
double hike = 0.35;
void incrementSalary()
{
System.out.println("The Temporary Employee incremented salary is :" +(salary+(salary * hike)));
}
}
public class HierInheritanceDemo
{
public static void main(String args[])
{
PermanentEmp p = new PermanentEmp();
TemporaryEmp t = new TemporaryEmp();
p.dispSalary();
p.incrementSalary();
t.dispSalary();
t.incrementSalary();
}
}
87
Output:
The Employee salary is: 40000.0
The Permanent Employee incremented salary is : 60000.0
The Employee salary is: 40000.0
The Temporary Employee incremented salary is : 54000.0
7.18 Method Overriding
❖ Method Overriding is a feature that allows us to use the same method name in the child
class which is already present in the parent class.
❖ In other words, it is performed between two classes using inheritance relation.Method Overriding
is one of the way by which Java can achieve Run Time Polymorphism.
Rules for Method Overriding
1. Method name must be the same in both parent and child classes.
2. The method must have the same parameter as in the parent class.
3. There must be an IS-A relationship between classes (inheritance).
4. Private, final and static methods cannot be overridden.
Example:
// Java program to implement Method Overriding
// MethodOverriding.java
import java.io.*;
class Parent // Base Class
{
void show()
{
System.out.println("Parent's show method");
}
}
class Child extends Parent // Inherited Class
{
// This method overrides show() of Parent
void show()
{
System.out.println("Child's show method");
}
}
class MethodOverriding // Main class
{
public static void main(String args[])
{
Parent obj1 = new Parent();
obj1.show();
Parent obj2 = new Child();
obj2.show();
}
}
Output:
88
Parent's show method
Child's show method
7.19 Differences between Method Overloading and Method Overriding in Java
❖ There are many differences between method overloading and method overriding in java.
❖ A list of differences between method overloading and method overriding are given below:
Sl.
Method Overloading Method Overriding
No.
1) Method Overloading is used to increase Method Overriding is used to provide the
the readability of the program. specific implementation of the method that
is already provided by its super class.
2) Method Overloading is performed within Method Overriding occurs in two classes
class. that have IS-A (inheritance) relationship.
3) In case of method In case of method overriding, parameter
overloading, parameter must be must be same.
different.
4) Method Overloading is an example Method Overriding is an example for Run
for Compile Time Polymorphism. Time Polymorphism.
5) Return type can be same or different in Return type must be same in method
method overloading. But we must have overriding.
to change the parameter.
89
}
public static void main(String args[])
{
Bike obj=new Bike();
obj.run();
}
}
Output:
Compile Time Error
final Methods
❖ The final keyword is used in a method declaration to indicate that the method cannot be
overridden by subclasses.
❖ Methods called from constructors should generally be declared final.
❖ A final method cannot be overriden or hidden by subclasses. This is used to prevent unexpected
behavior from a subclass altering a method that may be crucial to the function or consistency of
the class.
Example:
//Final Method Example
class Bike
{
final void run()
{
System.out.println("Running");
}
}
class Honda extends Bike
{
void run()
{
System.out.println("Running safely with 100kmph");
}
public static void main(String args[])
{
Honda honda= new Honda();
honda.run();
}
}
Output:
Compile Time Error
7.21 final classes
❖ A class that cannot be subclassed is called a final class.
❖ This is achieved in Java using the keyword final as follows:
final class A {………………}
final class B extends A {…………..}
90
❖ Any attempt to inherit these classes will cause an error and the compiler will not allow it.
❖ Declaring a class final prevents any unwanted extensions to the class
Example:
Example:
Output:
Finalizing…
Finalized.
7.24 Abstract Methods and Classes
Abstract Methods
❖ A method without body (no implementation) is known as abstract method.
❖ A method must always be declared in an abstract class, or in other words we can say that if a
class has an abstract method, it should be declared abstract as well.
❖ The general form is:
abstract type name(parameter-list);
Rules of Abstract Method
1. Abstract methods don’t have body, they just have method signature as shown above.
92
2. If a class has an abstract method it should be declared abstract, the vice versa is not true, which
means an abstract class doesn’t need to have an abstract method compulsory.
3. If a regular class extends an abstract class, then the class must have to implement all the abstract
methods of abstract parent class or it has to be declared abstract as well.
Example:
// Java program using abstract method in an abstract class
// Demo.java
import java.io.*;
abstract class Sum
{
public abstract int sumOfTwo(int n1, int n2);
public abstract int sumOfThree(int n1, int n2, int n3);
//Regular method
public void disp()
{
System.out.println("Method of class Sum");
}
}
//Regular class extends abstract class
class Demo extends Sum
{
public int sumOfTwo(int num1, int num2)
{
return num1+num2;
}
public int sumOfThree(int num1, int num2, int num3)
{
return num1+num2+num3;
}
public static void main(String args[])
{
Demo obj = new Demo();
System.out.println(obj.sumOfTwo(3, 7));
System.out.println(obj.sumOfThree(4, 3, 19));
obj.disp();
}
}
Output:
10
26
Method of class Sum
Abstract Class
❖ A class that is declared with an abstract keyword is known as abstract class.
❖ An abstract class cannot be instantiated, which means we are not allowed to create an object of
it. It can be used only as a super-class for those classes that extend the abstract class.
❖ The default functionality of the class still exists, with its fields, methods and constructors being
accessed in the same way as with the other classes.
93
❖ An abstract class may contain methods without any implementation, called abstract methods.
❖ A class that extends an abstract class must implement all its abstract methods (if any).
❖ The general form of an abstract class is:
abstract class Class_Name
{
………….
………….
abstract type name(parameter-list);
…………
}
Here,
abstract: It is a keyword that must be used at the time of declaration.
Class_Name: We can provide class names according to our functionality.
abstract method: Each abstract class has at least one abstract method.
Example:
// Java program to demonstrate abstract class
//AbstractDemo.java
import java.io.*;
abstract class Shape
{
abstract void draw();
}
class Rectangle extends Shape
{
void draw()
{
System.out.println("Drawing Rectangle");
}
}
class Circle extends Shape
{
void draw()
{
System.out.println("Drawing Circle");
}
}
class AbstractDemo
{
public static void main(String args[])
{
Circle c=new Circle();
c.draw();
}
}
94
Output:
Drawing Circle
7.25 Visibility Control (Access Control)
❖ Visibility Control is otherwise called access control or access specifiers or access modifiers.
❖ Access Control is used to restrict the access to certain variables and methods from outside
the class.
❖ Java provides a number of access modifiers to set access levels for classes, variables, methods,
and constructors. They are:
1. private
2. public
3. protected
❖ When no access specifier is used, then by default the member of a class is public within its own
package but cannot be accessed outside of its package.
private
❖ Methods, variables, and constructors that are declared private can only be accessed within
the declared class itself.
❖ Private access modifier is the most restrictive access level. Class and interfaces cannot be private.
❖ Using the private modifier is the main way that an object encapsulates itself and hides data from the
outside world.
Example:
Example:
95
The main() method of an application has to be public. Otherwise, it could not be called by a Java
interpreter (such as java) to run the class.
protected
❖ Variables, methods, and constructors, which are declared protected in a superclass can be
accessed only by the subclasses in other package or any class within the package of the
protected members' class.
❖ The protected access modifier cannot be applied to class and interfaces. Methods, fields can be
declared protected, however methods and fields in a interface cannot be declared protected.
❖ Protected access gives the subclass a chance to use the helper method or variable, while preventing
a nonrelated class from trying to use it.
Example:
protected int number;
protected int sum();
7.26 Static Members
❖ The members that are declared using the keyword static are called static members.
❖ Static members always remain the same, regardless of where and how they are used.
❖ Because static members are associated with the class, it is not necessary to create an instance of
that class to invoke them.
❖ Static members can be defined as follows:
static int count;
static int max(int x, int y);
❖ The most common example of a static member is main(). main() is declared as static because
it must be called before any objects exist.
❖ Instance variables declared as static are, essentially, global variables.
❖ We can call a static method from outside of the class as follows:
classname.staticmethodname(parameter);
❖ Methods declared as static have several restrictions:
▪ They can only call other static methods.
▪ They must access only static data.
▪ They cannot refer to this or super in any way.
Example:
Example:
// Java program to demonstrate inner class
// InnerDemo.java
class Bank
{
private double bal, rate;
Bank(double b, double r)
{
bal = b;
rate = r;
}
void display()
{
Interest in=new Interest();
in.calculateInterest();
System.out.println("New Balance = "+bal);
}
private class Interest
97
{
void calculateInterest()
{
System.out.println("Balance = " +bal);
double interest=bal * rate/100;
System.out.println("Interest = "+interest);
bal+=interest;
}
}
}
class InnerDemo
{
public static void main(String args[])
{
Bank account=new Bank(20000,5);
account.display();
}
}
Output:
Balance = 20000.0
Interest = 1000.0
New Balance = 21000
7.28 Nesting of Methods
❖ A method can be called by using only its name by another method of the same class. This is
known as nesting of methods.
Example:
// Java program to illustrate nesting of method
// NestingTest.java
import java.io.*;
class Nesting
{
int m,n;
Nesting(int x, int y)
{
m=x;
n=y;
}
int largest()
{
if (m>=n)
return (m);
else
return(n);
}
98
void display()
{
int large = largest(); // Calling a method
System.out.println("Largest Value = "+large);
}
}
class NestingTest
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int a,b;
System.out.println("Enter the values of a & b");
a=Integer.parseInt(br.readLine());
b=Integer.parseInt(br.readLine());
Nesting nest=new Nesting(a,b);
nest.display();
}
}
Output:
Enter the values of a & b
30
40
Largest Value = 40
Exercises:
1. Define Class.
2. Define Instance Variable.
3. What is an Object? How to create Object for a class?
4. How do you access class members?
5. Define Methods.
6. What are Constructors?
7. Explain in Detail about Constructors with an example.
8. Define this keyword.
9. What is Method Overloading?
10. What is recursive function?
11. Discuss inheritance with an example.
12. Define extends keyword.
13. Define super keyword.
14. What is Method Overriding?
99
15. What are the differences between method overriding and overloading?
16. Define final keyword.
17. Explain briefly about Garbage Collection in Java.
18. What is finalize method?
19. Explain abstract method.
20. Discuss about visibility control in Java.
21. Explain static members.
22. Write a Java program to illustrate nested class.
**************************
100
******************************************************************************
Chapter 8 String Handling
******************************************************************************
8.1 Definition
❖ A string is a sequence of characters. Java implements strings as objects of type String.
❖ Java has methods to compare two strings, search for a substring, concatenate two strings, and
change the case of letters within a string. Also, String objects can be constructed a number of
ways, making it easy to obtain a string when needed.
❖ In Java, strings are class objects and implemented using two classes, namely, String and
StringBuffer. These classes are defined in the package java.lang.
8.2 String Class
❖ The String class represents character strings. A Java string is an instantiated object of the
String class. The Java platform provides the String class to create and manipulate strings.
❖ Strings are constant; their values cannot be changed after they are created. Java strings are
reliable and more predictable. A Java string is not a character array and is not NULL terminated.
❖ The class String includes methods for examining individual characters of the sequence, for
comparing strings, for searching strings, for extracting substrings, and for creating a copy of a
string with all characters translated to uppercase or to lowercase.
1. The String Constructors
String()
String(char chars[])
String(char chars[], int startIndex, int numChars)
String(String strObj)
String(byte asciiChars[])
String(byte asciiChars[], int startIndex, int numChars)
i) String()
❖ This is the default constructor. To create an empty string, we call the default constructor.
Example:
String S=new String();
will create an instance of String with no characters in it.
ii) String(char chars[])
❖ The String class provides a variety of constructors to create strings that have initial values. This
constructor is used to create a String initialized by an array of characters.
Example:
101
char chars[]={‘a’,’b’,’c’};
v) String(byte asciiChars[])
vi) String(byte asciiChars[], int startIndex, int numChars)
❖ The String class provides constructors that initialize a string when given a byte array. Here,
asciiChars specifies the array of bytes. The second form allows us to specify a sub range. In
each of these constructors, the byte-to-character conversion is done by using the default character
encoding of the platform.
Example:
2. String Methods
102
❖ The String class contains a number of methods that allow us to perform a string manipulation.
Some of the most commonly used string methods are as follows:
i) charAt()
❖ The charAt() method returns the character at the specified index in a string.
❖ The index of the first character is 0, the second character is 1, and so on.
❖ The general form is:
StringObject.charAt(int index)
Example:
//Java program to demonstrate charAt method
import java.io.*;
public class CharAtDemo
{
public static void main(String args[])
{
String Str = "Hello";
char result = Str.charAt(0);
System.out.println(result);
}
}
Output:
H
ii) compareTo()
❖ The compareTo() method is used to compare two stringslexicographically (in the dictionary
order).
❖ This method is returns negative if string1 is less than string2, positive if string1 is greater than
string2, and zero if string1 is equal to string2.
❖ The general form is:
StringObject.compareTo(string)
Example:
//Java program to compare strings
import java.io.*;
class CompareTo_Ex
{
public static void main(String args[])
{
String Str1 = "Learn Java";
String Str2 = "Learn Java";
String Str3 = "Learn Python";
int result;
// Comparing Str1 with Str2
103
result = Str1.compareTo(Str2);
System.out.println(result); // 0
// Comparing Str1 with Str3
result = Str1.compareTo(Str3);
System.out.println(result); // -1
// Comparing Str3 with Str1
result = Str3.compareTo(Str1);
System.out.println(result); // 1
}
}
Output:
0
-6
6
iii) concat()
❖ The concat() method concatenates multiple strings. This method appends the specified
string at the end of the given string and returns the combined string.
❖ The general form is:
StringObject.concat(string)
Example:
//Java program to demonstrate concat method
import java.io.*;
public class ConcatDemo
{
public static void main(String args[])
{
String FirstName = "Raja";
String LastName = "ram";
System.out.println(FirstName.concat(LastName));
}
}
Output:
Rajaram
iv) equals()
❖ The equals() method compares two strings, and returns true if the strings are equal, and false
if not.
❖ The general form is:
StringObject.equals(string)
Example:
104
//Java program to demonstrate equals method
import java.io.*;
public class EqualsDemo
{
public static void main(String args[])
{
String Str1 = "Java";
String Str2 = "Java";
StringStr3 = "Python";
System.out.println(Str1.equals(Str2));
System.out.println(Str1.equals(Str3));
}
}
Output:
true
false
v) equalsIgnoreCase()
❖ The equalsIgnoreCase() method compares two strings, ignoring lowercase and uppercase
differences.
❖ This method returns true if the strings are equal, and false if not.
❖ The general form is:
StringObject.equalsIgnoreCase(string)
Example:
//Java program to demonstrate equalsIgnoreCase method
import java.io.*;
public class EqualsIgnoreCaseDemo
{
public static void main(String args[])
{
String Str1 = "Java";
String Str2 = "JAVA";
StringStr3 = "Python";
System.out.println(Str1.equalsIgnoreCase(Str2));
System.out.println(Str1.equalsIgnoreCase(Str3));
}
}
Output:
true
false
vi) endsWith()
❖ The endsWith() method is used to check whether a given string ends with the specified string.
❖ The general form is:
StringObject.endsWith(String str)
105
Here, str is the String being tested. If the string matches, true is returned. Otherwise, false is
returned.
Example:
106
Output:
Sindhi College
viii) getBytes()
❖ The getBytes() method returns the byte array of the string. In other words, it returns sequence
of bytes.
❖ The general form is:
StringObject.getBytes()
Example:
//Java program to demonstrate getBytes method
import java.io.*;
public class GetBytesEx
{
public static void main(String args[])
{
String Str="ABCD";
byte[] arr=Str.getBytes();
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}
Output:
65
56
67
68
ix) indexOf()
❖ The indexOf() method Searches for the first occurrence of a character or substring in a given
String.
❖ There are 4 variations of this method in String class:
int indexOf(int ch): It returns the index of the first occurrence of character ch in a given String.
int indexOf(int ch, int fromIndex): It returns the index of first occurrence of character ch in
the given string after the specified index “fromIndex”.
int indexOf(String str): Returns the index of string str in a particular String.
int indexOf(String str, int fromIndex): Returns the index of string str in the given string after
the specified index “fromIndex”.
107
❖ All the above variations returns -1 if the specified char/substring is not found in the
particular String.
Example 1:
Now is the time for all good men to come to the aid of their country.
indexOf(t) = 7
indexOf(the) = 7
indexOf(t, 10) = 11
indexOf(the, 10) = 44
x) lastIndexOf()
❖ The lastIndexOf() method searches for the last occurrence of a character or substring in a given
string.
❖ It has the following 4 forms:
int lastIndexOf(int ch): It returns the last occurrence of character ch in the given String.
int lastIndexOf(int ch, int startIndex): It returns the last occurrence of ch, it starts looking
backwards from the specified index “startIndex”.
int lastIndexOf(String str): Returns the last occurrence of substring str in a String.
int lastIndexOf(String str, int startIndex): Returns the last occurrence of str, starts searching
backward from the specified index “startIndex”.
Example:
//Java program to demonstrate lastIndexOf().
import java.io.*;
class LastIndexOfDemo
108
{
public static void main(String args[])
{
String S = "Now is the time for all good men to come to the aid of their country.";
System.out.println(S);
System.out.println("lastIndexOf(t) = " + S.lastIndexOf('t'));
System.out.println("lastIndexOf(the) = " + S.lastIndexOf("the"));
System.out.println("lastIndexOf(t, 60) = " +S.lastIndexOf('t', 60));
System.out.println("lastIndexOf(the, 60) = " + S.lastIndexOf("the", 60));
}
}
Output:
Now is the time for all good men to come to the aid of their country.
lastIndexOf(t) = 65
lastIndexOf(the) = 55
lastIndexOf(t, 60) = 55
lastIndexOf(the, 60) = 55
xi) length()
1. replace()
2. replaceAll()
3. replaceFirst()
109
1. replace()
❖ The replace() method replaces every occurrence of a given character with a new character and
returns a new string.
❖ The general form is:
StringObject.replace(char original, char replacement)
Here, original specifies the string to be replaced by the string specified by replacement. The
resulting string is returned.
Example:
2. replaceAll()
❖ The replaceAll() method returns a new string where each occurrence of the matching substring
is replaced with the replacement string.
❖ The general form is:
StringObject.replaceAll(String regex, String replacement)
Here,
regex - regular expression that is to be replaced
replacement -matching substrings are replaced with this string
Example:
xiii) startsWith()
❖ The startsWith() method checks whether the given string begins with the specified string or
not.
❖ The general form is:
StringObject.startsWith(String str)
Here, str is the String being tested. If the string matches, true is returned. Otherwise, false is
returned.
Example:
//Java program to demonstrate startsWith method
import java.io.*;
class StartsWith_Ex
{
111
public static void main(String args[])
{
String str = "Java Programming";
System.out.println(str.startsWith("Java"));
System.out.println(str.startsWith("Program"));
}
}
Output:
true
false
xiv) substring()
1. substring(jnt StartIndex)
❖ The substring() method is used to extract a part of the string.
❖ The general form is:
StringObject.substring(int StartIndex)
Here, StartIndex specifies the beginning index
Example:
//SubstrExample
import java.io.*;
public class Substr_Ex1
{
public static void main(String args[])
{
String Str = new String("Welcome to DataPoint");
System.out.print("The extracted substring is : ");
System.out.println(Str.substring(11));
}
}
Output:
113
xvi) toLowerCase()
❖ The toLowerCase() method is used to convert all the characters of a string to lowercase letters.
❖ The general form is:
StringObject.toLowerCase()
Example:
Example:
Example:
114
//Java program to demonstrate toUpperCase method
import java.io.*;
public class ToUpperCase_Ex
{
public static void main(String args[])
{
String Str = "Sindhi College";
//Convert to UpperCase
System.out.println(Str.toUpperCase());
}
}
Output:
SINDHI COLLEGE
xix) trim()
❖ The trim() method is used to remove leading and trailing whitespaces from a string.
❖ The general form is:
StringObject.trim()
Example:
Output:
115
• valueOf(int i) − Returns the string representation of the int argument.
• valueOf(long l) − Returns the string representation of the long argument.
• valueOf(Object obj) − Returns the string representation of the Object argument.
❖ The general form is:
StringObject.valueOf()
Example:
1. StringBuffer Constructors
116
(i) StringBuffer()
(ii) StringBuffer(int size)
(iii) StringBuffer(String str)
(iv) StringBuffer(charSequence []ch)
i) StringBuffer()
❖ This constructor creates an empty stringbuffer and reserves space for 16 characters.
❖ This is the default constructor.
❖ The general form is:
StringBuffer bufname=new StringBuffer();
Example:
StringBuffer str=new StringBuffer();
StringBufferObject.append(String str)
Example:
//Java program to demonstrate append method
117
import java.io.*;
public class StringBuffer_AppendEx
{
public static void main(String args[])
{
StringBuffer str = new StringBuffer("Sindhi");
str.append("College");
System.out.println(str);
}
}
Output:
SindhiCollege
ii) capacity()
❖ The capacity()method returns the allocated capacity of the StringBuffer object.
❖ The general form is:
StringBufferObject.capacity()
Example:
//Java program to demonstrate capacity() method
import java.io.*;
public class StrBuffer_CapacityEx
{
public static void main(String args[])
{
StringBuffer str = new StringBuffer();
System.out.println(str.capacity());
}
}
Output:
16
v) deleteCharAt(int index)
Example:
119
import java.io.*;
public class StringBuffer_DeleteCharAtEx
{
public static void main(String args[])
{
StringBuffer sb = new StringBuffer("Raghav");
System.out.println("String buffer before deletion = " + sb);
// Deleting the character at index 5
sb.deleteCharAt(5);
System.out.println("String buffer after deletion = " + sb);
}
}
Output:
16
34
vii) getChars()
120
❖ The getChars() method copies characters from the given string into the destination character
array.
❖ The general form is:
. StringBufferObject.getChars(int srcStartIndex,int srcEndIndex,char[]destArray,int
destStartIndex)
Here,
srcStartIndex: Index of the first character in the string to copy.
srcEndIndex: Index after the last character in the string to copy.
destArray: Destination array where chars wil get copied.
destStartIndex: Index in the array starting from where the charswill be pushed into the
array.
Example:
Output:
Sindhi College
viii) insert()
❖ The insert() method is used to insert the given string at the specified index.
❖ There are various overloaded insert() methods available in StringBuffer class.
❖ The few forms of the insert() method are:
StringBufferObject.insert(int index, String str)
StringBufferObject.insert(int index, char ch)
StringBufferObject.insert(int index, Object obj)
Here, index specifies the index at which point the string will be inserted into the invoking
StringBuffer object.
Example:
121
//Java program to demonstrate insert() method of StringBuffer class
import java.io.*;
class Insert_Example
{
public static void main(String args[])
{
StringBuffer sb=new StringBuffer("Hello ");
sb.insert(1,"Java");//Now original string is changed
System.out.println(sb);//prints HJavaello
}
}
Output:
HJavaello
ix) indexOf()
❖ The indexOf() method is used to return the index of the first occurrence of the specified
substring.
❖ In StringBuffer class, there are two types of indexOf() method depending upon the
parameters passed to it.
1. indexOf(String str)
❖ This method returns the position of the first occurrence of the specified substring within the
original string.
❖ If the substring str is not present, then -1 is returned.
❖ The general form is:
StringBufferObject.indexOf(String str)
Here, str is the string to be searched.
Example:
122
Given String = Programming language
Index of substring = 17
Index of substring = -1
2. indexOf(String str, int startIndex)
❖ This method returns the index of the first occurrence of the substring starting at the specified
index.
❖ If the substring str is not present, then -1 is returned.
❖ The general form is:
StringBufferObject.indexOf(String str, int startIndex)
Here, str is the string to be searched. startIndex specifies the index of the first character
Example:
//Java program to demonstrate indexOf(String str, int startIndex) method
import java.io.*;
public class IndexOf_Ex2
{
public static void main(String args[])
{
StringBuffer sb = new StringBuffer("Let us go to JavaTpoint to learn Java");
System.out.println("String: " + sb);
// Returns the index of first occurrence substring after the given index
System.out.println("Index of substring Java: " + sb.indexOf("Java",20));
System.out.println("Index of substring to: " + sb.indexOf("to",8));
}
}
Output:
nt to learn java
String: Let us go to JavaTpoint to learn Java
Index of substring Java: 33
Index of substring to: 10
x) lastIndexOf()
❖ The lastIndexOf() method returns the index of the last occurrence of the specified substring.
❖ There are two overloaded lastIndexOf() methods available in StringBuffer class.
1. lastIndexOf(String str)
❖ This method returns the position of the last occurrence of the specified substring.
❖ The general form is:
StringBufferObject.lastIndexOf(String str)
123
//Java program to implement lastindexOf
import java.io.*;
public class LastIndexOf_Ex1
{
public static void main(String args[])
{
StringBuffer Str = new StringBuffer("This is lastIndexOf example");
System.out.println("Given String: "+Str);
//Rreturns last index of example
System.out.println("Last index of example: " + Str..lastIndexOf("example"));
}
}
Output:
Given String: This is lastIndexOf example
Last index of example: 20
2. lastIndexOf(String str, int startIndex)
❖ This method returns the position of the last occurrence of the specified substring.
❖ The argument startIndex is the index to start the search from.
❖ The general form is:
StringBufferObject.lastIndexOf(String str, int startIndex)
Here, str is the string to be searched. startIndex specifies the index of the first character.
Example:
//Java program to implement lastIndexOf method
import java.io.*;
public class LastIndexOf_Ex2
{
public static void main(String args[])
{
StringBuffer Str = new StringBuffer("This is string it value is java");
System.out.println("Given String: " + Str);
//Returns last index of is, fromIndex 10
System.out.println("Last index of is: " + sb2.lastIndexOf("is",10));
}
}
Output:
❖ The length()method is used to return the length of the string i.e. total number of characters.
❖ The general form is:
StringBufferObject.length()
124
Example:
//Java program to demonstrate length() method
import java.io.*;
public class Length_Ex
{
public static void main(String args[])
{
StringBuffer Str = new StringBuffer("Sindhi College");
// Printing the length of stringbuffer
System.out.println("Length = " + Str.length());
}
}
Output:
Length = 14
xii) replace()
❖ The replace() method is used to replace one string with another string.
❖ The substring being replaced is specified by the indexes startIndex and endIndex. Thus, the
substring at the startIndex through endIndex–1 is replaced.
❖ The general form is:
StringBufferObject.replace(int startIndex, int endIndex, String str)
Here,
StartIndex - It is the starting index of the substring
EndIndex - It is the end index (exclusive) of the substring.
Str - It is a string which replaces the substring from this sequence.
Example:
//Java program to demonstrate replace() method
import java.io.*;
public class Replace_Ex
{
public static void main(String args[])
{
StringBuffer sb = new StringBuffer("Program compile time");
System.out.println("Given String: "+sb);
System.out.println("After replace: "+sb.replace(8, 15, "run"));
}
}
Output:
Given String: Program compile time
After replace: Program run time
xiii) reverse()
125
❖ The reverse() method is used to reverse the given string.
❖ The general form is:
StringBufferObject.reverse()
Example:
//Java program using StringBuffer reverse()
import java.io.*;
public class Reverse_Ex
{
public static void main(String args[])
{
StringBuffer Str = new StringBuffer("Hello");
Str.reverse();
System.out.println(Str);
}
}
Output:
olleH
xiv) setCharAt()
❖ The setCharAt() method is used to set the specified character at the given index.
❖ The general form is:
StringBufferObject.setCharAt(int index, char ch)
where index specifies the position of the character being set and ch specifies the new value of the
character.
Example
//Java program to demonstrate setCharAt method
import java.io.*;
public class SetCharAt_Ex
{
public static void main(String args[])
{
StringBuffer sb = new StringBuffer("abc");
System.out.println("Given String: " + sb);
// Character at index 1
System.out.println("Character at index 1: " + sb.charAt(1));
// Set character at index 1
sb.setCharAt(1, 'x');
System.out.println("New String: " + sb);
// Character at index 1
System.out.println("Character at index 1: " + sb.charAt(1));
}
}
Output:
126
Given String: abc
Character at index 1: bc
New String: axc
Character at index 1: xharacter at index 1: b
xv) setLength()
❖ The setLength() method is used to set the new length of the string.
❖ The general form is:
StringBufferObject.setLength(int len)
Here, len specifies the length of the buffer. This value must be nonnegative. When we increase
the size of the buffer, null characters are added to the end of the existing buffer.
Example:
//Java program to implement setLength method
import java.io.*;
public classSetLength_Example
{
public static void main(String[] args)
{
StringBuffer sb = new StringBuffer("Sindhi College");
System.out.println("Given String: "+sb);
System.out.println("Length: "+sb.length());
//Set new length of character sequence
sb.setLength(7);
System.out.println("Set new length: "+sb.length());
System.out.println("New String: "+sb);
}
}
Output:
Given String: Sindhi College
Length: 14
Set new length: 7
New String: Sindhi
xvi) substring()
❖ The substring() method is used to extract a substring from the original string.
❖ There are two overloaded substring() methods available in StringBuffer class. These methods
are differentiated on the base of their parameters.
1. substring(int startIndex)
❖ This method is used to return the substring from the specified startIndex.
❖ The general form is:
StringBufferObject.substring(int startIndex)
This form will extract substring from startIndex till the end of the buffer.
127
Example:
//Java program to demonstrate substring(int startIndex) Method
import java.io.*;
public class SubString_Ex1
{
public static void main(String args[])
{
StringBuffer sb = new StringBuffer("StringBuffer");
System.out.println("Given String: "+sb);
String sub_str= sb.substring(6);
System.out.println("Sub String from start index 6= "+sub_str);
}
}
Output:
Given String: StringBuffer
Sub String from start index 6= Buffer
2. substring(int startIndex, int endIndex)
❖ This method is used to return the substring from the specified startIndex and endIndex.
❖ The general form is:
StringBufferObject.substring(int startIndex, int endIndex)
This will extract a substring from startIndex till the endIndex but won't include the character
at endIndex.
Example:
//Java program to demonstrate sunstring(int StartIndex, int endIndex) method
import java.io.*;
public class Substring_Ex2
{
public static void main(String args[])
{
StringBuffer sb = new StringBuffer("Java is a programming language");
System.out.println("Given String: "+sb);
String sub_str= sb.substring(10,20);
//Sub string from start index 10 and end index 20
System.out.println("Sub string from index 10 to 20: "+sub_str);
}
}
Output:
stva is a programming language
Given String: Java is a programming languageequence from index 10 to 22:
string from index 10 to 22: programming
xvii) toString()
❖ The toString() method can be used to convert a StringBuffer object to a String.
❖ The general form is:
StringBufferObject.toString()
128
Example:
Exercises:
UNIT - III
129
*******************************************************************************
Chapter 9 Packages
*******************************************************************************
9.1 Definition
❖ A package is a group of related classes and interfaces. The grouping is usually done
according to functionality. In fact, packages act as “containers” for classes.
❖ Java classes can be grouped together in packages. A package name is the same as the directory
(folder) name which contains the .java files.
9.2 Benefits of using packages
❖ The classes contained in the packages of another program can be easily reused.
❖ Packages also allow programmers to separate design from coding.
❖ In packages, classes can be declared uniquely compared with classes in other packages.
❖ Java Packages provide a way to ‘hide’ classes thus preventing other programs or packages from
accessing classes that are meant for internal use only.
❖ Packages provide access protection.
❖ Java package removes naming collision.
9.3 Different types of Packages
❖ Java packages are classified into two types. They are:
1. Java API Packages
2. User Defined Packages
Java API Packages
❖ Java API provides a large number of classes grouped into different packages according to
functionality. Most of the time we use the packages available with the Java API as shown in
Figure 10.1.
130
java.lang Language support classes. These are classes that Java compiler itself uses and
therefore they are automatically imported. They include classes for primitive
types, strings, math functions, threads and exceptions.
java.util Language utility classes such as vectors, hash tables, random numbers, date,
etc.
java.io Input / output support classes. They provide facilities for the input and output
of data.
java.awt Set of classes for implementing graphical user interface. They include
classes for
windows, buttons, lists, menus, and so on.
java.net Classes for networking. They include classes for communicating with local
computers as well as with Internet servers.
java.applet Classes for creating and implementing applets
❖ This statement uses a fully qualified class name Math to invoke the method sqrt().
❖ The package names must be unique. Duplicate names will cause run-time errors.
❖ Naming a package is therefore a very important aspect of creating a package. Since multiple
users work on Internet, duplicate package names are unavoidable.
❖ Java designers have recognized this problem and therefore suggested a package naming
convention that ensures uniqueness.
❖ This suggests the use of domain names as prefix to the preferred package names. For example:
cbe.psg.mypackage
Here, cbe denotes city name and psg denotes the organization name.
9.5 Creating Packages
❖ The package statement is used to create a new package.
❖ The package statement should be the first line in the source file. There can be only one package
statement in each source file, and it applies to all types in the file.
131
❖ The general form of the package statement is:
package packagename;
where packagename is the name of the package.
Example:
package MyPackage; // package declaration
public class FirstClass // class definition
{
………………
……………… (body of class)
………………
}
class Palintest
{
public static void main(String args[]) throws IOException
{
Palindrome P=new Palindrome();
Scanner in=new Scanner(System.in);
String message;
System.out.println("\tJava Program using Package");
133
System.out.println("\t***********************");
System.out.println("Input");
System.out.println("-------");
System.out.println("Enter the String");
String str= in.nextLine();
message=P.test(str);
System.out.println("Output");
System.out.println("---------");
System.out.println("The given string is "+message);
}
}
C:\>md mypackage
C:\>cd mypackage
C:\mypackage>path="c:\program files\java\jdk1.6.0_01\bin";
C:\mypackage>javac Palindrome.java
C:\mypackage>cd\
C:\>path="c:\program files\java\jdk1.6.0_01\bin";
C:\>javac Palintest.java
C:\>java Palintest
Output
---------
The given string is Palindrome
C:\>java Palintest
Java Program using Package
***********************
Input
-------
Enter the String
welcome
Output
---------
The given string is Not Palindrome
C:\>
9.6 Access Protection
❖ Java provides many levels of security that provides the visibility of members (variables and
methods) within the classes, subclasses, and packages.
134
❖ There are four types of access modifiers available in java:
1) Default – No keyword required
2) Private
3) Protected
4) Public
1) Default
❖ When no access modifier is specified for a class, method, or data member – It is said to be
having the default access modifier by default.
❖ The data members, class or methods which are not declared using any access modifiers i.e.
having default access modifier are accessible only within the same package.
2) private
❖ The private access modifier is specified using the keyword private.
❖ The scope of private modifier is limited to the class only.
❖ The methods or data members declared as private are accessible only within the class in
which they are declared.
3) protected
❖ The protected access modifier is specified using the keyword protected.
❖ The methods or data members declared as protected are accessible within the same package
or subclasses in different packages.
4) public
❖ The public access modifier is specified using the keyword public.
❖ The members, methods and classes that are declared public can be accessed
from anywhere.
❖ There is no restriction on the scope of public data members.
9.7 Accessing a Package
The import statement
❖ The import statement is used to access the package.
❖ The general form of import statement for searching a class is:
import package1 [.package2] [.package3].classname;
Here, package1 is the name of the top-level package. package2 is the name of the package that
is inside the 1st package i.e. package1 and so on. Programmers can use any number of packages
in the package hierarchy. At the end, the explicitly classname is specified.
❖ The import statement should appear before any class definitions in a source file. Multiple
import statements are allowed. The following is an example of importing a particular class:
import firstPackage.secondPackage.MyClass;
135
❖ After defining this statement, all members of the class MyClass can be directly accesses using
the class name or its objects directly without using the package name.
❖ We can also use another approach as follows:
import packagename.*;
Here, packagename may denote a single package or hierarchy of packages. The star (*) indicates
that the compiler should search this entire package hierarchy where it encounters a class name.
this implies that we can access all classes contained in the above package directly.
Exercises:
1. Define package.
2. List out few Java packages.
3. Explain Java API packages briefly.
4. What are the naming conventions for Java packages?
5. How will you create a user defined packages in Java?
6. Explain Access Protection in Java.
7. Define import keyword.
8. How will you access the Java package?
**************************
*******************************************************************************
Chapter 10 Interfaces
*******************************************************************************
10.1 Introduction
136
❖ An interface is similar to a class, but it contains abstract methods and static final variables
only.
❖ To access the interface methods, the interface must be "implemented" by another class with
the implements keyword.
❖ Like abstract classes, interfaces cannot be used to create objects.
❖ Interface methods do not have a body - the body is provided by the "implement" class.
❖ On implementation of an interface, we must override all of its methods.
❖ Interface methods are by default abstract and public..
❖ Interface attributes are by default public, static and final.
❖ An interface cannot contain a constructor.
10.2 Defining an Interface
❖ The syntax for defining an interface is very similar to that for defining a class.
❖ The general form of an interface definition is:
interface InterfaceName
{
//Variable declaration;
//Methods declaration;
}
Here, interface is the keyword and InterfaceName is any valid Java variable. Variables are
declared as follows:
static final type VariableName=value;
All variables are declared as constants. Methods declaration will contain only a list of methods
without any body statements. Methods are declared as follows:
return-type methodName(parameter_list);
Example 1:
interface Item
{
static final float code=1001;
static final String name=”Fan”;
void display();
}
Here, the code for the method is not included in the interface and the method declaration simply
ends with a semicolon. The class that implements this interface must define the code for the method.
Example 2:
interface Area
{
float static float pi=3,142F;
137
float compute(float x, float y);
void show();
}
Example:
interface ItemConstants
{
int code=1001;
String name=”Fan”;
}
interface Item extends ItemConstants
{
display();
}
The interface Item would inherit both the constants code and name into it. The variables name
and code are declared like simple variables. It is allowed because all the variables in an interface
are created as constants although the keywords final and static are not present.
❖ We can also combine several interfaces together into a single interface. Following declarations
are valid.
interface ItemConstants
{
int code=1001;
String name=”Fan”;
}
interface ItemMethods
{
display();
}
138
❖ While interfaces are allowed to extend to other interfaces, subinterfaces cannot define the
methods declared in the superinterfaces, Instead, it is the responsibility of any class that
implements the derived interface to define all the methods.
❖ An interface cannot extend classes.
10.4 Implementing Interfaces
❖ A class uses the implements keyword to implement an interface. The implements keyword
appears in the class declaration following the extends portion of the declaration.
❖ Interfaces are used as “superclasses” whose properties are inherited by classes. It is therefore
necessary to create a class that inherits the given interface. This is done as follows:
class classname implements Interfacename
{
//Body of classname
}
Here the class classname “implements” the interface interfacename. A more general form of
implementation may look like this:
class classname extends superclass implements Interfac1, Interface2, …
{
//Body of classname
}
This shows that a class can extend another class while implementing interfaces. When a class
implements more than one interface, they are separated by a comma.
Example:
140
10.6 Differences between class and interface in Java
Class Interface
A class is declared by using a keyword called An interface is declared by using a keyword
class. interface.
A class can be instantiated. The keyword new An interface can never be instantiated. That is
can only create an instance of a class. an object of interface can never be created.
Variables in a class can be declared using any All variables in an interface are always public,
access modifiers such as public, protected, static, and final.
default, and private. They can also be static,
final, or neither.
Methods declared in a class are implemented. Methods declared in an interface cannot be
i.e, methods have a body. Methods that have a implemented. i.e, In an interface, methods have
body is called concrete method. no body. It contains only abstract method.
Note: Java 8 introduces default method, which
allows us to give the body of a method in an
interface.
The members of a class can be declared with The members of an interface are always public
any access modifiers such as private, default, by default.
protected, and public.
A class can have constructors to initialize An interface cannot have any constructors.
instance variables.
Class allows only single, multilevel and Interface supports all types of inheritance such
hierarchical inheritances but do not support as multilevel, hierarchical, and multiple
multiple inheritance. inheritance.
A class can implement any number of the Interface cannot implement any class.
interface.
A class can extend only one class at a time. An interface can extend multiple interfaces at a
time.
A class is used to define the attributes and Interface is used for defining behavior that can
behaviors of an object. be implemented by any class anywhere in the
class hierarchy.
A method in a class can be declared as final. The method in an interface cannot be final
because if we declare a method as final,the
method cannot be modified by its subclass.
A class may contain main() method. Interface cannot have main() method.
Exercises:
1. Define interface.
2. Define abstract class.
3. How interfaces are extended?
4. Explian in detail about implementing interfaces.
5. Write a Java program to create and implement an interface.
6. How will you access interface variables?
7. Distinguish between class and interface in Java.
**************************
*******************************************************************************
Chapter 11 Exception Handling
*******************************************************************************
11.1 Introduction
141
❖ Exception Handling is a construct in some programming languages to handle or deal with
errors automatically.
❖ Errors are the wrongs that can make a program go wrong. An error may produce an incorrect
output or may terminate the execution of the program abruptly or even may cause the system to
crash.
11.2 Types of Errors
❖ Errors may be broadly classified into two categories:
• Compile-time errors
• Run-time errors
Compile-Time Errors
❖ A compile-time error is an error that is detected by the compiler. Compile-time errors occur
while a program is being compiled.
❖ All syntax errors will be detected and displayed by the Java compiler and therefore these errors
are known as compile-time errors.
❖ Whenever the compiler displays an error, it will not create the .class file. It is therefore necessary
that we fix all the errors before we can successfully compile and run the program.
Example:
❖ Most of the compile-time errors are due to typing mistakes. Typographical errors are hard to
find. The most common problems are:
• Missing semicolon
• Missing brackets in classes and methods
• Misspelling of identifiers and keywords
• Missing double quotes in strings
• Use of undeclared variables
• Incompatible types in assignments / initialization
• Use of = in place of == operator
Run-Time Errors
❖ An error that occurs during the execution of a program is called a run-time error. For
example, running out of memory will often cause run-time error.
142
❖ Most common run-time errors are:
• Dividing an integer by zero
• Accessing an element that is out of the bounds of an array
• Trying to store a value into an array of an incompatible class or type
• Trying to cast an instance of a class to one of its subclasses
• Passing a parameter that is not in a valid range or value for a method
• Trying to illegally change the state of a thread
• Attempting to use a negative size for an array
• Using a null object reference as a legitimate object reference to access a method or a variable
• Converting invalid string to a number
• Accessing a character that is out of bounds of a string
Example:
The above program is syntactically correct and therefore does not cause any problem during
compilation. However, while executing, it displays the following message and stops without
executing further statements.
Java.lang.ArithmeticException: / by zero
At Error2.main(Error2.java:10)
When Java run-time tries to execute a division by zero, it generates an error condition, which causes
the program to stop after displaying an appropriate message.
11.3 Exceptions
143
“exceptional circumstance“ so that appropriate action can be taken. The mechanism suggests
incorporation of a separate error handling code that performs the following tasks:
1. Find the problem (Hit the exception)
2. Inform that an error has occurred (Throw the exception)
3. Receive the error information (Catch the exception)
4. Take correction actions (Handle the exception)
❖ The error handling code basically consists of two segments, one to detect errors and to throw
exceptions and the other to catch exceptions and to take appropriate actions.
❖ All exception classes are subtypes of the java.lang.Exception class. The Exception class is a
subclass of the Throwable class.
11.4 Types of Exception in Java
❖ Java defines several types of exceptions that relate to its various class libraries.
❖ Java also allows users to define their own exceptions.
Built-in Exceptions
❖ Built-in exceptions are the exceptions which are available in Java libraries. These exceptions are
suitable to explain certain error situations. Below is the list of important built-in exceptions in
Java.
1. ArithmeticException
It is thrown when an exceptional condition has occurred in an arithmetic operation.
2. ArrayIndexOutOfBoundsException
It is thrown to indicate that an array has been accessed with an illegal index. The index
is either negative or greater than or equal to the size of the array.
3. ClassNotFoundException
This Exception is raised when we try to access a class whose definition is not found
4. FileNotFoundException
This Exception is raised when a file is not accessible or does not open.
5. IOException
It is thrown when an input-output operation failed or interrupted
6. InterruptedException
It is thrown when a thread is waiting, sleeping, or doing some processing, and it is
interrupted.
144
7. NoSuchFieldException
It is thrown when a class does not contain the field (or variable) specified
8. NoSuchMethodException
It is thrown when accessing a method which is not found.
9. NullPointerException
This exception is raised when referring to the members of a null object. Null represents
nothing
10. NumberFormatException
This exception is raised when a method could not convert a string into a numeric format.
11. RuntimeException
This represents any exception which occurs during runtime.
12. StringIndexOutOfBoundsException
It is thrown by String class methods to indicate that an index is either negative or greater
than the size of the string
Example:
//Java program to demonstrate Arithmetic Exception
import java.io.*;
class ArithmeticException_Demo
{
public static void main(String args[])
{
try
{
int a = 30, b = 0;
int c = a/b; // Cannot divide by zero
System.out.println ("Result = " + c);
}
catch(ArithmeticException e)
{
System.out.println ("Can't divide a number by 0");
}
}
}
145
❖ The catch statement allows us to define a block of code to be executed, if an error occurs in the
try block.
❖ The try and catch keywords come in pairs.
Syntax:
try
{
// Statements that may cause an exception
}
catch(Exception e)
{
// Exception handling ccode
}
❖ The try block can have one or more statements that could generate an exception. If any
statement generates an exception, the remaining statements in the block are skipped and
execution jumps to the catch block that is placed next to the try block.
❖ The catch block can have one or more statements that are necessary to process the exception.
❖ Every try statement should be followed by at least one catch statement; otherwise compiler
error will occur.
Example:
//Java program to demonstrate try…catch Statement
import java.io.*;
class TryCatch_Ex
{
public static void main(String args[])
{
int num1, num2;
try
{
num1 = 0;
num2 = 62 / num1;
System.out.println(num2);
}
catch (ArithmeticException e)
{
System.out.println("You should not divide a number by zero");
}
}
}
Output:
You should not divide a number by zero
11.6 Multiple catch Statements
❖ A single try block can have multiple catch blocks.
❖ Each catch block must contain a different exception handler.
146
Syntax:
try
{
//Statements that may cause an exxception
}
catch(ExceptionType1 e1)
{
//Statements
}
catch(ExceptionType2 e2)
{
//Statements
}
catch(ExceptionType3 e3)
{
//Staatements
}
...
catch(ExceptionTypeN en)
{
//Statements
}
Example:
//Java program using multiple catch blocks
import java.util.Scanner;
public class MultiCatchEx
{
public static void main(String[] args)
{
int x, y;
Scanner sc = new Scanner(System.in);
try
{
System.out.println("Enter the first number");
x = Integer.parseInt(sc.nextLine());
System.out.println("Enter the second number");
y = Integer.parseInt(sc.nextLine());
int z = x / y;
System.out.println("z = " +z);
}
catch(ArithmeticException ae)
{
System.out.println("A number cannot be divided by 0");
}
catch(NumberFormatException nfe)
{
System.out.println("Invalid data types are entered, number must be an integer.");
}
}
}
Output:
147
Enter the first number
40
Enter the second number
20
z=2
--------------------------------------------
Enter the first number
40
Enter the second number
0
A number cannot be divided by 0
--------------------------------------------
Enter the first number
40
Enter the second number
5.5
Invalid data types are entered, number must be an integer.
11.7 Nested try Statements
❖ A try block within another try block is known as nested try block.
❖ The try block which encloses another try block is called outer try block and the enclosed try
block is called inner try block.
Syntax:
149
//Java program to demonstrate finally sstatement
import java.io.*;
class Example
{
public static void main(String args[])
{
try
{
int num=101/0;
System.out.println(num);
}
catch(ArithmeticException e)
{
System.out.println("Number should not be divided by zero");
}
finally
{
System.out.println("This is finally block");
}
}
}
Output:
Number should not be divided by zero
This is finally block
throws clause
Here, exception-list is a comma-separated list of the exceptions that a method can throw.
Example:
151
Output:
java.io.IOException: IOException occurred
❖ The Exception class does not define any methods of its own. It does, of course, inherit those
methods provided by Throwable.
❖ Thus, all exceptions, including those that we create, have the methods defined by Throwable
available to them.
Methods Defined by Throwable
Sl. Method Description
No.
1. Throwable Returns a Throwable object that contains a
fillInStackTrace() completed stack trace. This object can be
rethrown.
2. String Returns a localized description of the exception.
getLocalizedMessage()
3. String getMessage() Returns a description of the exception.
4. void printStackTrace() Displays the stack trace.
5. void Sends the stack trace to the specified stream.
printStackTrace(PrintStream
stream)
6. void Sends the stack trace to the specified stream
printStackTrace(PrintWriter
stream)
7. String toString() Returns a String object containing a description of the
exception. This method is called by println() when
outputting a Throwable object.
Example:
152
{
public static void main(String args[])
{
try
{
throw new MyException();
}
catch (MyException ex)
{
System.out.println("Exception Caught");
System.out.println(ex.getMessage());
}
}
}
Output:
1. Define exception.
2. Explain the different types of errors in Java
3. What is exception handling?
4. Explain the various types of exception in Java.
5. List out any five built-in exception.
6. Explain multiple catch exception with an example.
7. What is the use of finally block?
8. Explain briefly the methods defined by throwable.
**************************
******************************************************************************
Chapter 12 Multithreading
******************************************************************************
12.1 Definition
154
• Thread(ThreadGroup group, Runnable target, String name): Allocates a new Thread
object so that it has target as its run object, has the specified name as its name, and belongs to
the thread group referred to by group
• Thread(ThreadGroup group, Runnable target, String name, long stackSize): Allocates a
new Thread object so that it has target as its run object, has the specified name as its name, and
belongs to the thread group referred to by group, and has the specified stack size
• Thread(ThreadGroup group, String name): CAllocates a new Thread object
❖ This method tests whether the current thread has been interrupted.
Syntax:
public static boolean interrupted()
12. isAlive()
❖ This method tests if the thread is alive.
Syntax:
public final boolean isAlive()
13. isInterrupted()
❖ This method tests whether the thread has been interrupted.
Syntax:
public boolean isInterrupted()
14. join()
❖ This method waits for a thread to die.
Syntax:
public final void join() throws InterruptedException
156
public final void join(long millis) throws InterruptedException
Parameters:
millis - the time to wait in milliseconds
16. resume()
❖ This method is used to resume the suspended thread.
public void resume()
17. run()
❖ This method is used to perform action for a thread.
Syntax:
public void run()
18. start()
❖ This method causes the thread to begin execution; the Java Virtual Machine calls the run
method of the thread.
Syntax:
public void start()
19. sleep(long millis)
❖ This method causes the currently executing thread to sleep (temporarily cease execution) for
the specified number of milliseconds.
Syntax:
public static void sleep(long millis) throws InterruptedException
Parameters:
millis - the length of time to sleep in milliseconds
20. setPriority(int newPriority)
❖ This method changes the priority of the thread.
Syntax:
public final void setPriority(int newPriority)
Parameters:
newPriority - priority to set this thread to
21. setName(String name)
❖ This method changes the name of the thread.
Syntax:
public final void setName(String name)
Parameters:
name - the new name for this thread.
22. stop()
157
This method is used to stop the thread.
Syntax:
public void stop()
23. suspend()
❖ This method is used to suspend the thread.
Syntax:
public void suspend()
24. toString()
❖ This method returns a string representation of the thread, including the thread’s name, priority,
and thread group.
Syntax:
public String toString()
25. yield()
❖ This method causes the currently executing thread object to temporarily pause and allow other
threads to execute.
Syntax:
public static void yield()
12.5 Creating a Thread
❖ There are two ways to create a thread:
i) Extending the Thread class
ii) Implementing the Runnable interface
i) Extending the Thread class
❖ The first way to create a thread is to create a new class that extends Thread class using the
following steps.
1. Declare the class as extending the Thread class.
2. Implement the run() method that is responsible for executing the sequence of code that the
thread will execute.
3. Create a thread object and call the start() method to initiate the thread execution.
Declaring the Class
❖ The Thread class can be extended as follows:
❖ The run() method has been inherited by the class MyThread. We have to override this method in
order to implement the code to be executed by our thread. The basic implementation of run() will
look like this:
public void run()
{
……………….
………………. // Thread code here
……………….
}
When we start the new thread, Java calls the thread’s run() method, so it is the run() where all of
the action takes place.
Example:
159
// Java program to implement the Runnable interface
import java.io.*;
class Multi implements Runnable
{
public void run()
{
System.out.println("Thread is running...");
}
public static void main(String args[])
{
Multi m1=new Multi();
Thread t1 =new Thread(m1);
t1.start();
}
}
Output:
Thread is running...
12.6 Starting New Thread
❖ The start() method of thread class is used to begin the execution of thread. The result of this
method is two threads that are running concurrently: the current thread (which returns from the
call to the start method) and the other thread (which executes its run method).
❖ The start thread performs the following tasks:
• It stats a new thread
• The thread moves from New State to Runnable state.
• When the thread gets a chance to execute, its target run() method will run.
❖ To actually create and run an instance of our thread class, we must write the following:
MyThread Th=new MyThread();
Th.start();
The first line instantiates a new object of class MyThread.
The second line calls the start() method causing the thread to move into a runnable state.
Example:
// Creating threads using the Thread class
// File Name : ThreadClassDemo.java
import java.io.*;
public class ThreadClassDemo
{
public static void main(String [] args)
{
Runnable hello = new DisplayMessage();
Thread thread1 = new Thread(hello);
thread1.setDaemon(true);
thread1.setName("hello");
System.out.println("Starting hello thread...");
160
thread1.start();
Runnable bye = new DisplayMessage("Goodbye");
Thread thread2 = new Thread(bye);
thread2.setPriority(Thread.MIN_PRIORITY);
thread2.setDaemon(true);
System.out.println("Starting goodbye thread...");
thread2.start();
System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
thread3.start();
try
{
thread3.join();
}
catch (InterruptedException e)
{
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
thread4.start();
System.out.println("main() is ending...");
}
}
Output:
Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......
12.7 Stopping and Blocking a Thread
Stopping a Thread
❖ The stop() method is used to stop the thread from running further.
Example:
MyThread.stop()
161
This method causes the thread to move to the dead state. A thread will also move to the dead state
automatically when it reaches the end of its method. The stop() method may be used when the
premature death of the thread is desired.
Blocking a Thread
❖ A thread can be temporarily suspended or blocked from entering into the runnable and
subsequently running state by using either of the following thread methods:
sleep() // blocked for a specified time
suspend() // blocked until further orders
wait() // blocked until certain condition occurs
These methods cause the thread to go into the blocked (or non-runnable) state. The thread will
return to the runnable state when the specified time is elapsed in the case of sleep(), the resume()
method is invoked in the case of suspend(), and the notify() method is called in the case of
wait().
12.8 Life Cycle of a Thread
❖ A thread moves through several states from its creation to termination. During the lifetime of a
thread, there are many states it can enter. They include:
• New
• Runnable
• Running
• Blocked (Waiting)
• Dead (Terminated)
❖ A thread is always in one of these five states. It can move from one state to another via a variety
of ways as shown in Figure 12.1.
❖ A new thread begins its life cycle in the new state. It remains in this state until the program
starts the thread. It is also referred to as a born thread.
2) Runnable State
162
❖ The runnable state means that the thread is ready for execution and is waiting for the availability
of the processor. That is, the thread has joined the queue of threads that are waiting for
execution. If all threads have equal priority, then they are given time slots for execution in round
robin fashion i.e., first-come, first-serve manner. This process of assigning time to threads is
known as time-slicing.
3) Running State
❖ Running state means that the processor has given its time to the thread for its execution. A
thread can come into running state only from runnable state.
❖ A thread is said to be blocked when it is prevented from entering into the runnable state and
subsequently the running state. This happens when the thread is suspended, sleeping, or waiting
in order to satisfy certain requirements.
❖ A runnable thread enters the terminated state when it completes its task or otherwise terminates.
❖ The default priority of the main thread is 5, child thread will take the priority that is equal to its
parent thread priority.
❖ We can change the priority of any thread that it may be the main thread or user-defined thread.
❖ It is recommended to change the priority by using constants available in the Thread class like
follows:
1. Thread.MIN_PRIORITY;
2. Thread.NORM_PRIORITY;
3. Thread.MAX_PRIORITY;
❖ Threads are assigned priorities, based on that the thread scheduler can use to determine how the
thread will be scheduled.
❖ The thread scheduler can use thread priorities to determine which thread gets to run.
setPriority() method
❖ The setPriority() method is used to set the thread’s priority.
163
❖ The general form is:
ThreadName.setPriority(int newPriority);
Note: The newPriority value range should between 1 to 10 else it leads to exception
java.lang.illegalArgumentException.
Example:
t.setPriority(7); //Valid
t.setPriority(Thread.NORM_PRIORITY+2); //Valid(recommended)
getPriority() method
❖ The getPriority() method is used to obtain the current priority setting.
❖ The general form is:
ThreadName.getPriority();
Example:
// Java program using priority in threads
import java.io.*;
class TestMultiPriority1 extends Thread
{
public void run()
{
System.out.println("Running thread name is:"+Thread.currentThread().getName());
System.out.println("Running thread priority is:"+Thread.currentThread().getPriority());
}
public static void main(String args[])
{
TestMultiPriority1 m1=new TestMultiPriority1();
TestMultiPriority1 m2=new TestMultiPriority1();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();
}
}
Output:
Running thread name is : Thread-0
Running thread priority is: 10
Running thread name is : Thread-1
Running thread priority is: 1
12.10 Synchronization
❖ The process of allowing multiple threads to modify an object in a sequence is called
synchronization.
❖ Synchronization in Java is the capability to control the access of multiple threads to any shared
resource.
164
❖ Thread Synchronization is a process of allowing only one thread to use the object when
multiple threads are trying to use the particular object at the same time.
❖ A thread can be synchronized by using the synchronized keyword as a modifier in the method
declaration.
❖ The general form of the synchronized statement is
synchronized(object)
{
//Statements to be synchronized
}
Here, object is a reference to the objet being synchronized. If we want to synchronize only a
single statement, then the curly braces are not needed. A synchronized block ensures that a call
to a method that is a member of object occurs only after the current thread has successfully
entered object’s monitor.
Example:
// Java program for synchronization
// SyncDemo.java
import java.io.*;
import java.lang.*;
class ThreadX extends Thread
{
Thread s;
public void call(Thread name) throws IOException
{
s=name;
s.start();
}
public void run()
{
try
{
caller(s);
}
catch (Exception obj)
{
}
}
synchronized void caller(Thread r) throws Exception
{
System.out.println("Good Morning");
System.out.println("Good Afternoon");
r.sleep(2000);
System.out.println("Good Evening");
}
}
class SyncDemo
{
public static void main(String args[]) throws Exception
165
{
ThreadX one=new ThreadX();
Thread x= new Thread(one);
Thread y=new Thread(one);
Thread z=new Thread(one);
one.call(x);
one.call(y);
one.call(z);
}
}
Output:
Good Morning
Good Afternoon
Gooed Evening
Good Morning
Good Afternoon
Gooed Evening
Good Morning
Good Afternoon
Gooed Evening
12.11 Interthread Communication
❖ Interthread communication in Java is a technique through which multiple threads
communicate with each other.
❖ It provides an efficient way through which more than one thread communicate with each other
by reducing CPU idle time.
❖ When more than one threads are executing simultaneously, sometimes they need to communicate
with each other by exchanging information with each other. A thread exchanges information
before or after it changes its state.
❖ Interthread communication in Java can be achieved by using three methods provided by Object
class of java.lang package. They are:
1. wait()
2. notify()
3. notifyAll()
❖ These methods can be called only from within a synchronized method or synchronized block of
code otherwise, an exception named IllegalMonitorStateException is thrown.
• wait(): This method tells the calling thread to give up the monitor and go to sleep until some
other thread enters the same monitor and calls notify( ).
• notify(): This method wakes up the first thread that called wait( ) on the same object.
• notifyAll(): This method wakes up all the threads that called wait( ) on the same object The
highest priority thread will run first.
❖ These methods are declared within Object, as shown here:
166
final void wait() throws InterruptedException
final void notify()
final void notifyAll()
Example:
167
{
char m;
String[] s1 = { "Hi", "How are you ?", "I am also doing fine!" };
public T1(Chat m1)
{
this.m = m1;
new Thread(this, "Question").start();
}
public void run()
{
for (int i = 0; i < s1.length; i++)
{
m.Question(s1[i]);
}
}
}
class T2 implements Runnable
{
Chat m;
String[] s2 = { "Hi", "I am good, what about you?", "Great!" };
public T2(Chat m2)
{
this.m = m2;
new Thread(this, "Answer").start();
}
public void run()
{
for (int i = 0; i < s2.length; i++)
{
m.Answer(s2[i]);
}
}
}
public class TestThread
{
public static void main(String args[])
{
Chat m = new Chat();
new T1(m);
new T2(m);
}
}
Output:
Hi
Hi
168
How are you ?
I am good, what about you?
I am also doing fine!
Great!
12.12 Deadlock
❖ Deadlock describes a situation where two or more threads are blocked forever, waiting for
each other.
❖ Deadlock occurs when multiple threads need the same locks but obtain them in different order.
❖ A Java multithreaded program may suffer from the deadlock condition because the
synchronized keyword causes the executing thread to block while waiting for the lock, or
monitor, associated with the specified object.
Example:
169
}
}
}
}
private static class ThreadDemo2 extends Thread
{
public void run()
{
synchronized (Lock2)
{
System.out.println("Thread 2: Holding lock 2...");
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1)
{
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
Output:
Thread 1: Holding lock 1...
Thread 2: Holding lock 2...
Thread 1: Waiting for lock 2...
Thread 2: Waiting for lock 1...
12.13 Thread Control
Suspending, Resuming, and Stopping Threads
❖ The suspend( ), resume( ), and stop( ) methods defined by the Thread class are used to pause,
restart, and stop the execution of a thread.
❖ The functions of Suspend, Resume and Stop a thread is performed using Boolean-type flags in
a multithreading program. These flags are used to store the current status of the thread.
1. If the suspend flag is set to true then run() will suspend the execution of the currently
running thread.
2. If the resume flag is set to true then run() will resume the execution of the suspended
thread.
3. If the stop flag is set to true then a thread will get terminated.
❖ There are various static methods which we can use on thread objects to control their behavior.
Following table lists down those methods –
Sl. No Method Description
170
public void suspend() This method puts a thread in the suspended state and can
1
be resumed using resume() method.
2 public void stop() This method stops a thread completely.
This method resumes a thread, which was suspended
3 public void resume()
using suspend() method.
Causes the current thread to wait until another thread
4 public void wait()
invokes the notify().
Wakes up a single thread that is waiting on this object's
5 public void notify()
monitor.
Example:
//Java program to implement suspend, resume and stop operations
import java.io.*;
class temp implements Runnable
{
Thread Th;
boolean suspend_flag, stop_flag;
temp(String tN)
{
Th=new Thread(this, tN);
suspend_flag=false;
stop_flag=false;
Th.start();
}
public void run()
{
try
{
int j=1;
while(++j<20)
{
synchronized(this)
{
while(suspend_flag)
{
wait();
}
if(stop_flag)
{
break;
}
}
}
}
catch(InterruptedException IE)
{
System.out.println("Thread Interrupted");
}
}
synchronized void my_suspend()
{
suspend_flag=true;
171
}
synchronized void my_resume()
{
suspend_flag=false;
notify();
}
synchronized void my_stop()
{
suspend_flag=false;
stop_flag=true;
notify();
}
}
public class SRS
{
public static void main(String args[])
{
try
{
temp t1=new temp("SRS");
System.out.println("Thread SRS is Created and Started");
Thread.sleep(2000);
t1.my_suspend();
System.out.println("Thread SRS is Suspended");
Thread.sleep(2000);
t1.my_resume();
System.out.println("Thread SRS is Resumed");
Thread.sleep(2000);
t1.my_suspend();
System.out.println("Thread SRS is Suspended");
Thread.sleep(2000);
t1.my_resume();
System.out.println("Thread SRS is Resumed");
Thread.sleep(2000);
t1.my_stop();
System.out.println("Thread SRS is Stopped");
}
catch(InterruptedException IE)
{
System.out.println("Generated interrupted exception");
}
}
}
Output:
Thread SRS is Created and Started
Thread SRS is Suspended
Thread SRS is Resumed
Thread SRS is Suspended
Thread SRS is Resumed
Thread SRS is Stopped
12.14 Differences between a process and a thread
172
Sl. No. Process Thread
1. Process means any program in Thread means segment of a process.
execution.
2. Process takes more time for creation. Thread takes less time for creation.
3. Process takes more time to terminate. Thread takes less time to terminate.
4. Processes require more time for context Threads require less time for context
switching. switching.
5. Communication between processes Communication between threads requires
requires more time than between less time than between processes.
threads.
6. Process consumes more resources. Thread consumes less resources.
7. Process is called heavy weight process. Thread is called light weight process.
8. Processes have independent data and A thread shares the data segment, code
code segments. segment, files etc. with its peer threads.
9. If one process is blocked then it will not If a user level thread gets blocked, all of its
affect the execution of other processes. peer threads also get blocked.
10. Process has its own Process Control Thread has Parents’ PCB, its own Thread
Block, Stack and Address Space. Control Block and Stack and common
Address Space.
Exercises:
1. Define Thread.
2. What is Multithreading?
3. Explain the various methods of Thread class.
4. Explain the methods to create a thread.
5. Explain Thread Life Cycle.
6. List out the Thread priorities.
7. Define synchronization.
8. Discuss about synchronization in detail.
9. Discuss in detail about Inter-thread Communication.
10. Define Deadlock.
11. Explain thread controlling methods.
12. Diffrentiate between a process and a thread.
*****************************
********************************************************************************
Chapter 13 I/O Streams
********************************************************************************
13.1 Introduction
173
❖ An I/O Stream represents an input source or an output destination. A stream can represent many
different kinds of sources and destinations, including disk files, devices, other programs, and
memory arrays.
❖ Streams support many different kinds of data, including simple bytes, primitive data types,
localized characters, and objects. Some streams simply pass on data; others manipulate and
transform the data in useful ways.
❖ A stream is a sequence of data.
❖ A program uses an input stream to read data from a source, one item at a time.
❖ A program uses an output stream to write data to a destination, one item at time:
174
❖ Table 13.1 gives a brief description of all the methods provided by the InputStream class.
Method Description
int available() Returns the number of bytes of input currently available for reading.
void close() Closes the input source. Further read attempts will generate an
IOException.
Places a mark at the current point in the input stream that will
void mark(int numBytes) remain valid until numBytes bytes are read.
Returns true if mark()/reset() are supported by the invoking
Boolean markSupported() stream.
Returns an integer representation of the next available byte of input.
int read() –1 is returned when the end of the file is encountered.
Attempts to read up to buffer.length bytes into buffer and returns the
int read(byte buffer[]) actual number of bytes that were successfully read. –1 is returned
when the end of the file is encountered.
int read(byte buffer[], int Attempts to read up to numBytes bytes into buffer starting at
offset, int numBytes) buffer[offset], returning the number of bytes successfully read. –1 is
returned when the end of the file is encountered.
Resets the input pointer to the previously set mark.
void reset()
Ignores (that is, skips) numBytes bytes of input, returning the
long skip(long numBytes) number of bytes actually ignored.
Table 13.1: The methods defined by InputStream
Method Description
void close( ) Closes the output stream. Further write attempts will generate an
IOException.
void flush( ) Finalizes the output state so that any buffers are cleared. That is, it
flushes the output buffers.
void write(int b) Writes a single byte to an output stream. The parameter is an int,
which allows us to call write() with expressions without having to
cast them back to byte.
void write(byte buffer[ ]) Writes a complete array of bytes to an output stream.
void write(byte buffer[ ], int Writes a sub range of numBytes bytes from the array buffer,
offset, int numBytes) beginning at buffer[offset].
Table 13.2: The methods defined by OutputStream
ByteArrayInputStream
175
❖ ByteArrayInputStream is an implementation of an input stream that uses a byte array as the
source. In this stream, the data is read from a byte array.
❖ This class has two constructors, each of which requires a byte array to provide the data source:
ByteArrayInputStream(byte array[])
ByteArrayInputStream(byte array[], int start, int numBytes)
Here, array is the input source. The second constructor creates an InputStream from a subset
of our byte array that begins with the character at the index specified by start and is numBytes
long.
Methods
Method Description
int available() It is used to return the number of remaining bytes that can
be read from the input stream.
int read() It is used to read the next byte of data from the input stream.
int read(byte[] ary, int off, int len) It is used to read up to len bytes of data from an array of
bytes in the input stream.
boolean markSupported() It is used to test the input stream for mark and reset method.
long skip(long x) It is used to skip the x bytes of input from the input stream.
void mark(int readAheadLimit) It is used to set the current marked position in the stream.
void reset() It is used to reset the buffer of a byte array.
void close() It is used for closing a ByteArrayInputStream.
Example:
176
ASCII value of Character is:35; Special character is: #
ASCII value of Character is:36; Special character is: $
ASCII value of Character is:37; Special character is: %
ASCII value of Character is:38; Special character is: &
ByteArrayOutputStream
❖ The ByteArrayOutputStream class is used to write common data into multiple files. In this
stream, the data is written into a byte array which can be written to multiple streams later.
❖ The ByteArrayOutputStream holds a copy of data and forwards it to multiple streams.
❖ ByteArrayOutputStream has two constructors, shown here:
ByteArrayOutputStream()
ByteArrayOutputStream(int numBytes)
In the first form, a buffer of 32 bytes is created. In the second, a buffer is created with a size
equal to that specified by numBytes. The buffer size will be increased automatically, if needed.
Methods
Method Description
int size() It is used to returns the current size of a buffer.
byte[] toByteArray() It is used to create a newly allocated byte array.
String toString() It is used for converting the content into a string decoding
bytes using a platform default character set.
String toString(String charsetName) It is used for converting the content into a string decoding
bytes using a specified charsetName.
void write(int b) It is used for writing the byte specified to the byte array
output stream.
void write(byte[] b, int off, int len It is used for writing len bytes from specified byte array
starting from the offset off to the byte array output stream.
void writeTo(OutputStream out) It is used for writing the complete content of a byte array
output stream to the specified output stream.
void reset() It is used to reset the count field of a byte array output stream
to zero value.
void close() It is used to close the ByteArrayOutputStream.
Example:
177
FileOutputStream fout2=new FileOutputStream("D:\f2.txt");
ByteArrayOutputStream bout=new ByteArrayOutputStream();
bout.write(65);
bout.writeTo(fout1);
bout.writeTo(fout2);
bout.flush();
bout.close();//has no effect
System.out.println("Success...");
}
}
Output:
Success...
f1.txt:
A
f2.txt:
A
Buffered Byte Streams
❖ The buffered byte stream classes are BufferedInputStream and BufferedOutputStream.
PushbackInputStream also implements a buffered stream.
i) BufferedInputStream
BufferedInputStream(InputStream inputStream)
BufferedInputStream(InputStream inputStream, int bufSize)
The first form creates a buffered stream using a default buffer size. In the second, the size of
the buffer is passed in bufSize.
Methods
Method Description
int available() It returns an estimate number of bytes that can be read from the
input stream without blocking by the next invocation method for
the input stream.
int read() It read the next byte of data from the input stream.
178
int read(byte[] b, int off, int ln) It read the bytes from the specified byte-input stream into a
specified byte array, starting with the given offset.
void close() It closes the input stream and releases any of the system
resources associated with the stream.
void reset() It repositions the stream at a position the mark method was last
called on this input stream.
void mark(int readlimit) It sees the general contract of the mark method for the input
stream.
long skip(long x) It skips over and discards x bytes of data from the input stream.
boolean markSupported() It tests for the input stream to support the mark and reset
methods.
Example:
Example:
//Java Program using BufferedOutputStream
import java.io.*;
public class BufferedOutputStreamExample
{
public static void main(String args[]) throws Exception
{
FileOutputStream fout=new FileOutputStream("D:\testout.txt");
BufferedOutputStream bout=new BufferedOutputStream(fout);
String S="Welcome to Java";
byte b[]=s.getBytes();
bout.write(b);
bout.flush();
bout.close();
fout.close();
System.out.println("Success");
}
}
Output:
Success
testout.txt
Welcome to Java
SequenceInputStream
180
The first form creates a new input stream by reading the data of two input stream in order, first
s1 and then s2.
The second form creates a new input stream by reading the data of an enumeration whose type
is InputStream.
Methods
Method Description
int read() It is used to read the next byte of data from the input
stream.
int read(byte[] ary, int off, int len) It is used to read len bytes of data from the input stream
into the array of bytes.
int available() It is used to return the maximum number of byte that can
be read from an input stream.
void close() It is used to close the input stream.
Example:
//Java Program to implement SequenceInputStream
import java.io.*;
class InputStreamExample
{
public static void main(String args[]) throws Exception
{
FileInputStream input1=new FileInputStream("D:\testin.txt");
FileInputStream input2=new FileInputStream("D:\testout.txt");
SequenceInputStream inst=new SequenceInputStream(input1, input2);
int j;
while((j=inst.read())!=-1)
{
System.out.print((char)j);
}
inst.close();
input1.close();
input2.close();
}
}
testin.txt:
Welcome to Java Programming.
testout.txt:
It is an example of Java SequenceInputStream class.
Output:
181
Welcome to Java Programming. It is an example of Java SequenceInputStream class.
PrintStream
❖ The PrintStream class provides methods to write data to another stream.
❖ The PrintStream class automatically flushes the data so there is no need to call flush() method.
❖ It has the following constructors:
PrintStream(OutputStream outputStream)
PrintStream(OutputStream outputStream, boolean flushOnNewline)
where flushOnNewline controls whether Java flushes the output stream every time a newline
(\n) character is output. If flushOnNewline is true, flushing automatically takes place. If it is
false, flushing is not automatic. The first constructor does not automatically flush.
❖ Java’s PrintStream objects support the print() and println() methods for all types, including
Object. If an argument is not a simple type, the PrintStream methods will call the object’s
toString() method and then print the result.
Example:
The content of a text file testout.txt is set with the below data
2021
Hello Java
Welcome to Java
13.5 Character Stream Classes
❖ Character streams can be used to read and write 16-bit Unicode characters. There are two kinds
of character stream classes, namely, Reader stream classes Writer stream classes.
182
i) Reader Stream Classes
❖ Reader stream classes are designed to read character from the files. Reader class is the base
class for all other classes.
❖ It has the following constructors:
Reader()
Reader(Object lock)
The first form creates a new character-stream reader whose critical sections will synchronize
on the reader itself.
The second form creates a new character-stream reader whose critical sections will synchronize
on the given object.
❖ Table 13.3 lists the methods in the Reader class. All of the methods in this class will throw an
IOException on error conditions.
Method Description
abstract void close() Closes the input source. Further read attempts will generate
an IOException.
void mark(int numChars) Places a mark at the current point in the input stream that will
remain valid until numChars characters are read.
boolean markSupported() Returns true if mark()/reset() are supported on this stream.
int read() Returns an integer representation of the next available
character from the invoking input stream. –1 is returned when
the end of the file is encountered.
int read(char buffer[]) Attempts to read up to buffer.length characters into buffer and
returns the actual number of characters that were successfully
read. –1 is returned when the end of the file is encountered.
abstract int read(char buffer[], Attempts to read up to numChars characters into buffer
int offset, int numChars) starting at buffer[offset], returning the number of characters
successfully read. –1 is returned when the end of the file is
encountered.
boolean ready() Returns true if the next input request will not wait.
Otherwise, it returns false.
void reset() Resets the input pointer to the previously set mark.
long skip(long numChars) Skips over numChars characters of input, returning the
number of characters actually skipped.
Table 13.3: The Methods Defined by Reader
Example:
file.txt:
I love my country
Output:
I love my country
ii) Writer Stream Classes
❖ The Writer stream classes are designed to write characters.
❖ The Writer is an abstract class that defines streaming character output.
❖ It has the following constructors:
Writer()
Writer(Object lock)
The first form creates a new character-stream writer whose critical sections will synchronize on
the writer itself.
The second form creates a new character-stream writer whose critical sections will synchronize
on the given object.
❖ Table 13.4 lists the methods in the Writer class. All of the methods in this class return a void
value and throw an IOException in the case of errors.
Method Description
abstract void close() Closes the output stream. Further write attempts will
generate an IOException.
abstract void flush() Finalizes the output state so that any buffers are cleared.
That is, it flushes the output buffers.
void write(int ch) Writes a single character to the invoking output stream.
void write(char buffer[]) Writes a complete array of characters to the invoking output
stream.
184
abstract void write(char buffer[], Writes a subrange of numChars characters from the array
int offset, int numChars) buffer, beginning at buffer[offset] to the invoking output
stream.
void write(String str) Writes str to the invoking output stream.
void write(String str, int offset, Writes a subrange of numChars characters from the array
int numChars) str, beginning at the specified offset.
Table 13.4: The Methods Defined by Writer
Example:
185
int read() It is used to read a single character
int read(char[] b, int off, int len) It is used to read characters into the portion of an array.
boolean ready() It is used to tell whether the stream is ready to read.
boolean markSupported() It is used to tell whether the stream supports mark() operation.
long skip(long n) It is used to skip the character in the input stream.
void mark(int readAheadLimit) It is used to mark the present position in the stream.
void reset() It is used to reset the stream to a most recent mark.
void close() It is used to closes the stream.
Example:
//Java Program to implement CharArrayReader
import java.io.*;
public class CharArrayExample
{
public static void main(String args[]) throws Exception
{
char[] ary = { 'j', 'a', 'v', 'a', 't', 'p', 'o', 'i', 'n', 't' };
CharArrayReader reader = new CharArrayReader(ary);
int k = 0;
// Read until the end of a file
while ((k = reader.read()) != -1)
{
char ch = (char) k;
System.out.print(ch + " : ");
System.out.println(k);
}
}
}
Output:
j : 106
a : 97
v : 118
a : 97
t : 116
p : 112
o : 111
i : 105
n : 110
t : 116
CharArrayWriter
❖ The CharArrayWriter class can be used to write common data to multiple files. This class
inherits Writer class.
❖ CharArrayWriter has two constructors, shown here:
186
CharArrayWriter()
CharArrayWriter(int numChars)
In the first form, a buffer with a default size is created. In the second, a buffer is created with a
size equal to that specified by numChars. The buffer size will be increased automatically, if
needed.
Methods
Method Description
int size() It is used to return the current size of the buffer.
char[] toCharArray() It is used to return the copy of an input data.
String toString() It is used for converting an input data to a string.
CharArrayWriter append(char c) It is used to append the specified character to the
writer.
CharArrayWriter append(CharSequence csq) It is used to append the specified character
sequence to the writer.
CharArrayWriter append(CharSequence csq, It is used to append the subsequence of a
int start, int end) specified character to the writer.
void write(int c) It is used to write a character to the buffer.
void write(char[] c, int off, int len) It is used to write a character to the buffer.
void write(String str, int off, int len) It is used to write a portion of string to the buffer.
void writeTo(Writer out) It is used to write the content of buffer to
different character stream.
void flush() It is used to flush the stream.
void reset() It is used to reset the buffer.
void close() It is used to close the stream.
Example:
//Java Program to implement CharArrayWriter
import java.io.*;
public class CharArrayWriterExample
{
public static void main(String args[]) throws Exception
{
CharArrayWriter out=new CharArrayWriter();
out.write("Welcome to Java");
FileWriter f1=new FileWriter("D:\a.txt");
FileWriter f2=new FileWriter("D:\b.txt");
FileWriter f3=new FileWriter("D:\c.txt");
FileWriter f4=new FileWriter("D:\d.txt");
out.writeTo(f1);
out.writeTo(f2);
out.writeTo(f3);
out.writeTo(f4);
f1.close();
187
f2.close();
f3.close();
f4.close();
System.out.println("Success...");
}
}
Output:
Success...
After executing the program, we can see that all files have common data: Welcome to Java
a.txt:
Welcome to Java
b.txt:
Welcome to Java
c.txt:
Welcome to Java
d.txt:
Welcome to Java
BufferedReader
❖ The BufferedReader class is used to read the text from a character-based input stream. It can
be used to read data line by line by readLine() method.
❖ It has two constructors:
BufferedReader(Reader inputStream)
BufferedReader(Reader inputStream, int bufSize)
The first form creates a buffered character stream using a default buffer size.
In the second, the size of the buffer is passed in bufSize.
Methods
Method Description
int read() It is used for reading a single character.
int read(char[] cbuf, int off, int len) It is used for reading characters into a portion of an array.
boolean markSupported() It is used to test the input stream support for the mark and
reset method.
String readLine() It is used for reading a line of text.
boolean ready() It is used to test whether the input stream is ready to be read.
188
long skip(long n) It is used for skipping the characters.
void reset() It repositions the stream at a position the mark method was
last called on this input stream.
void mark(int readAheadLimit) It is used for marking the present position in a stream.
void close() It closes the input stream and releases any of the system
resources associated with the stream.
Example:
//Java Program using BufferedReader Class
import java.io.*;
public class BufferedReaderExample
{
public static void main(String args[]) throws Exception
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter your name");
String name=br.readLine();
System.out.println("Welcome "+name);
}
}
Output:
Enter your name
Ashok
Welcome Ashok
BufferedWriter
❖ The BufferedWriter class is used to provide buffering for Writer instances.
❖ Using a BufferedWriter can increase performance by reducing the number of times data is
actually physically written to the output stream.
❖ A BufferedWriter has these two constructors:
BufferedWriter(Writer outputStream)
BufferedWriter(Writer outputStream, int bufSize)
The first form creates a buffered stream using a buffer with a default size.
In the second, the size of the buffer is passed in bufSize.
Methods
Method Description
void newLine() It is used to add a new line by writing a line separator.
void write(int c) It is used to write a single character.
void write(char[] cbuf, int off, int len) It is used to write a portion of an array of characters.
void write(String s, int off, int len) It is used to write a portion of a string.
void flush() It is used to flush the input stream.
void close() It is used to close the input stream
189
Example:
Methods
Method Description
void println(boolean x) It is used to print the boolean value.
void println(char[] x) It is used to print an array of characters.
void println(int x) It is used to print an integer.
PrintWriter append(char c) It is used to append the specified character to the
writer.
190
PrintWriter append(CharSequence ch) It is used to append the specified character
sequence to the writer.
PrintWriter append(CharSequence ch, int start, It is used to append a subsequence of specified
int end) character to the writer.
boolean checkError() It is used to flushes the stream and check its error
state.
protected void setError() It is used to indicate that an error occurs.
protected void clearError() It is used to clear the error state of a stream.
PrintWriter format(String format, Object args) It is used to write a formatted string to the writer
using specified arguments and format string.
void print(Object obj) It is used to print an object.
void flush() It is used to flushes the stream.
void close() It is used to close the stream.
Example:
//Java Program using PrintWriter
import java.io.*;
public class PrintWriterExample
{
public static void main(String args[]) throws Exception
{
//Data to write on Console using PrintWriter
PrintWriter writer = new PrintWriter(System.out);
writer.write("Java is an Object Oriented Language.");
writer.flush();
writer.close();
//Data to write in File using PrintWriter
PrintWriter writer1 =null;
writer1 = new PrintWriter(new File("D:\\testout.txt"));
writer1.write("I Like Java, Visual Basic, Android, PHP etc.”);
writer1.flush();
writer1.close();
}
}
Output:
Java is an Object Oriented Language.
The content of a text file testout.txt is set with the data I Like Java, Visual Basic, Android, PHP
etc.
13.6 Serialization
❖ Serialization in Java is a mechanism of writing the state of an object into a byte stream.
❖ It is mainly used in Hibernate, RMI, JPA, EJB and JMS technologies.
❖ The reverse operation of serialization is called deserialization.
❖ The interfaces and classes that support serialization are as follows.
191
Serializable
❖ Serializable is a marker interface (has no data member and method).
❖ It is used to "mark" Java classes so that objects of these classes may get the certain capability.
❖ The Cloneable and Remote are also marker interfaces.
❖ It must be implemented by the class whose object you want to persist.
❖ The String class and all the wrapper classes implement the java.io.Serializable interface by
default.
Externalizable
❖ The Externalizable interface provides the facility of writing the state of an object into a byte
stream in compress format. It is not a marker interface.
❖ The Externalizableinterface defines these two methods:
void readExternal(ObjectInput inStream) throws IOException, ClassNotFoundException
void writeExternal(ObjectOutput outStream) throws IOException
In these methods, inStream is the byte stream from which the object is to be read, and outStream
is the byte stream to which the object is to be written.
ObjectOutput
❖ The ObjectOutput interface extends the DataOutput interface and supports object
serialization.
❖ It defines the methods shown in Table 13.5.
Method Description
void close() Closes the invoking stream. Further write
attempts will generate an IOException.
void flush() Finalizes the output state so that any buffers
are cleared. That is, it flushes the output
buffers.
void write(byte buffer[]) Writes an array of bytes to the invoking
stream.
void write(byte buffer[], int offset, int Writes a subrange of numBytes bytes from
numBytes) the array buffer, beginning at buffer[offset].
192
❖ A constructor of this class is
ObjectOutputStream(OutputStream outStream) throws IOException
The argument outStream is the output stream to which serialized objects will be written.
❖ The most commonly used methods in this class are shown in Table 13.6. They will throw an
IOException on error conditions.
Method Description
void close() Closes the invoking stream. Further write attempts
will generate an IOException.
void flush() Finalizes the output state so that any buffers are
cleared. That is, it flushes the output buffers.
void write(byte buffer[]) Writes an array of bytes to the invoking stream.
void write(byte buffer[], int offset, int Writes a subrange of numBytes bytes from the array
numBytes) buffer, beginning at buffer[offset].
ObjectInputStream
The argument inStream is the input stream from which serialized objects should be read. The
most commonly used methods in this class are shown in Table 13.8. They will throw an
IOException on error conditions.
Method Description
int read(byte buffer[], int offset, int Attempts to read up to numBytes bytes into
numBytes) buffer starting at buffer[offset], returning the
number of bytes that were successfully read. –1
is returned when the end of the file is
encountered.
Object readObject() Reads an object from the invoking stream.
194
long skip(long numBytes) Ignores (that is, skips) numBytes bytes in the
invoking stream, returning the number of bytes
actually ignored.
int available() Returns the number of bytes that are now
available in the input buffer.
void close() Closes the invoking stream. Further read
attempts will generate an IOException.
int read() Returns an integer representation of the next
available byte of input. –1 is returned when the
end of the file is encountered.
int read(byte buffer[], int offset, int Attempts to read up to numBytes bytes into
numBytes) buffer starting at buffer[offset], returning the
number of bytes successfully read. –1 is
returned when the end of the file is encountered.
boolean readBoolean() Reads and returns a boolean from the invoking
stream.
byte readByte() Reads and returns a byte from the invoking
stream.
char readChar() Reads and returns a char from the invoking
stream.
double readDouble() Reads and returns a double from the invoking
stream.
float readFloat() Reads and returns a float from the invoking
stream.
void readFully(byte buffer[]) Reads buffer.length bytes into buffer. Returns
only when all bytes have been read.
void readFully(byte buffer[], int offset, int Reads numBytes bytes into buffer starting at
numBytes) buffer[offset]. Returns only when numBytes
have been read.
int readInt() Reads and returns an int from the invoking
stream.
long readLong() Reads and returns a long from the invoking
stream.
final Object readObject() Reads and returns an object from the invoking
stream.
short readShort() Reads and returns a short from the invoking
stream.
int readUnsignedByte() Reads and returns an unsigned byte from the
invoking stream.
int readUnsignedShort() Reads an unsigned short from the invoking
stream.
Table 13.8: Commonly Used Methods Defined by ObjectInputStream
Example:
195
class Deserial
{
public static void main(String args[]) throws Exception
{
ObjectInputStream in=new ObjectInputStream(new FileInputStream("f.txt"));
Student s=(Student)in.readObject();
System.out.println(s.id+" "+s.name);
in.close();
}
}
Output:
100 Abilash
13.7 Other Useful I/O Classes
❖ The java.io package supports many other classes for performing certain specialized functions.
They include:
• RandomAccessFile
• StreamTokenizer
RandomAccessFile
❖ RandomAccessFile enables us to read and write bytes, text and Java data types to any location
in a file.
❖ This class extends Object class and implements DataInput and DataOutput interfaces.
❖ It also supports positioning requests - that is, we can position the file pointer within the file.
❖ It has these two constructors:
RandomAccessFile(File fileObj, String access) throws FileNotFoundException
RandomAccessFile(String filename, String access) throws FileNotFoundException
In the first form, fileObj specifies the name of the file to open as a File object.
In the second form, the name of the file is passed in filename. In both cases, access determines
what type of file access is permitted. If it is “r”, then the file can be read, but not written. If it is
“rw”, then the file is opened in read-write mode. If it is “rws”, the file is opened for read-write
operations and every change to the file’s data or metadata will be immediately written to the
physical device. If it is “rwd”, the file is opened for read-write operations and every change to
the file’s data will be immediately written to the physical device.
Methods
Method Description
Void close() It closes this random access file stream and releases any system
resources associated with the stream.
FileChannel getChannel() It returns the unique FileChannel object associated with this file.
int readInt() It reads a signed 32-bit integer from this file.
String readUTF() It reads in a string from this file.
196
void seek(long pos) It sets the file-pointer offset, measured from the beginning of this
file, at which the next read or write occurs.
void writeDouble(double v) It converts the double argument to a long using the
doubleToLongBits method in class Double, and then writes that
long value to the file as an eight-byte quantity, high byte first.
void writeFloat(float v) It converts the float argument to an int using the floatToIntBits
method in class Float, and then writes that int value to the file as a
four-byte quantity, high byte first.
void write(int b) It writes the specified byte to this file.
int read() It reads a byte of data from this file.
long length() It returns the length of this file.
void seek(long pos) It sets the file-pointer offset, measured from the beginning of this
file, at which the next read or write occurs.
Example 1:
// Writing and reading with random access
import java.io.*;
class RandomIO
{
public static void main(String args[])
{
RandomAccessFile file=null;
try
{
file=new RandomAccessFile(“rand.dat”,”rw”);
// Writing to the file
file.writeChar(‘X’);
file.writeInt(555);
file.writeDouble(3.1412);
file.seek(0); // Go to the beginning
// Reading from the file
System.out.println(file.readChar());
System.out.println(file.readInt());
System.out.println(file.readDouble());
file.seek(2); // Go to the second item
System.out.println(file.readInt());
// Go to the end and append false to the file
file.seek(file.length());
file.writeBoolean(false);
file.seek(4);
System.out.println(file.readBoolean());
file.close();
}
catch(IOException e)
{
System.out.println(e);
197
}
}
}
Output:
X
555
3.1412
555
false
Appending to an existing file
Example 2:
StreamTokenizer
❖ The StreamTokenizer class takes an input stream and parses it into "tokens" allowing the
tokens to be read one at a time.
❖ The StreamTokenizer can recognize identifiers, numbers, quoted strings, and various
comment styles.
❖ It has this constructor:
StreamTokenizer(Reader r)
This creates a tokenizer that parses the given character stream.
Field
198
• String sval − If the current token is a word token, this field contains a string giving the
characters of the word token.
• static int TT_EOF − A constant indicating that the end of the stream has been read.
• static int TT_EOL − A constant indicating that the end of the line has been read.
• static int TT_NUMBER − A constant indicating that a number token has been read.
• static int TT_WORD − A constant indicating that a word token has been read.
• int ttype − After a call to the nextToken method, this field contains the type of the token just
read.
Methods
Method Description
void commentChar(int ch) Specified that the character argument starts a
single-line comment.
void eolIsSignificant(boolean flag) This method determines whether or not ends of
line are treated as tokens.
int lineno() This method returns the current line number.
void lowerCaseMode(boolean fl) This method determines whether or not word
token are automatically lowercased.
int nextToken() This method parses the next token from the input
stream of this tokenizer.
void ordinaryChar(int ch) This method specifies that the character argument
is "ordinary" in this tokenizer.
void ordinaryChars(int low, int hi) This method specifies that all characters c in the
range low <= c <= high are "ordinary" in this
tokenizer.
void parseNumbers() This method specifies that numbers should be
parsed by this tokenizer.
void pushBack() This method causes the next call to the nextToken
method of this tokenizer to return the current
value in the ttype field, and not to modify the
value in the nval or sval field.
void quoteChar(int ch) This method specifies that matching pairs of this
character delimit string constants in this
tokenizer.
void resetSyntax() This method resets this tokenizer's syntax table so
that all characters are "ordinary." See the
ordinaryChar method for more information on a
character being ordinary.
void slashSlashComments(boolean flag) This method determines whether or not the
tokenizer recognizes C++ style comments.
void slashStarComments(boolean flag) This method determines whether or not the
tokenizer recognizes C style comments.
String toString() This method returns the string representation of
the current stream token and the line number it
occurs on.
199
void whitespaceChars(int low, int hi) This method specifies that all characters c in the
range low <= c <= high are white space
characters.
void wordChars(int low, int hi) This method specifies that all characters c in the
range low <= c >= high are word constituents.
Example:
This
is
a
test
string
for
Stream
Tokenizer
i) File(File parent, String child) : Creates a new File instance from a parent abstract pathname
and a child pathname string.
ii) File(String pathname) : Creates a new File instance by converting the given pathname string
into an abstract pathname.
200
iii) File(String parent, String child) : Creates a new File instance from a parent pathname string
and a child pathname string.
iv) File(URI uri) : Creates a new File instance by converting the given file: URI into an abstract
pathname.
Methods
Method Description
boolean canExecute() Tests whether the application can execute the file
denoted by this abstract pathname.
boolean canRead() Tests whether the application can read the file denoted
by this abstract pathname.
boolean canWrite() Tests whether the application can modify the file
denoted by this abstract pathname.
boolean createNewFile() Atomically creates a new, empty file named by this
abstract pathname .
boolean delete() Deletes the file or directory denoted by this abstract
pathname. If this pathname denotes a directory, then the
directory must be empty in order to be deleted. Returns
true if and only if the file or directory is successfully
deleted; false otherwise.
boolean equals(Object obj) Tests this abstract pathname for equality with the given
object.
Tests whether the file or directory denoted by this
boolean exists()
abstract pathname exists. Returns true if and only if the
file or directory denoted by this abstract pathname
exists; false otherwise.
String getName() Returns the name of the file or directory denoted by this
abstract pathname.
String getParent() Returns the pathname string of this abstract pathname's
parent, or null if this pathname does not name a parent
directory.
String getPath() Converts this abstract pathname into a pathname string.
Tests whether this abstract pathname is absolute.
boolean isAbsolute()
Returns true if this abstract pathname is absolute, false
otherwise.
Returns the absolute pathname string of this abstract
String getAbsolutePath()
pathname.
Tests whether the file denoted by this abstract pathname
boolean isDirectory()
is a directory. Returns true if and only if the file denoted
by this abstract pathname exists and is a directory; false
otherwise.
Tests whether the file denoted by this abstract pathname
boolean isFile()
is a normal file. Returns true if and only if the file
denoted by this abstract pathname exists and is a normal
file; false otherwise.
201
long lastModified() Returns the time that the file denoted by this abstract
pathname was last modified.
Returns the length of the file denoted by this abstract
long length()
pathname. The return value is unspecified if this
pathname denotes a directory.
Returns an array of strings naming the files and
String[] list()
directories in the directory denoted by this abstract
pathname.
Returns an array of strings naming the files and
String[] list(FilenameFilter filter)
directories in the directory denoted by this abstract
pathname that satisfy the specified filter.
Returns an array of abstract pathnames denoting the files
File[] listFiles()
in the directory denoted by this abstract pathname.
File[] listFiles(FileFilter filter) Returns an array of abstract pathnames denoting the
files and directories in the directory denoted by this
abstract pathname that satisfy the specified filter.
Creates the directory named by this abstract pathname.
boolean mkdir()
Returns true if and only if the directory was created;
false otherwise.
Creates the directory named by this abstract pathname,
boolean mkdirs()
including any necessary but nonexistent parent
directories. Returns true if and only if the directory was
created, along with all necessary parent directories; false
otherwise.
Renames the file denoted by this abstract pathname.
boolean renameTo(File dest)
Returns true if and only if the renaming succeeded; false
otherwise.
Sets the last-modified time of the file or directory named
boolean setLastModified(long
by this abstract pathname. Returns true if and only if the
time) operation succeeded; false otherwise.
Example:
//Demonstrate File class
import java.io.*;
public class RetrieveFileData
{
public static void main(String args[]) throwsIOException
{
File f1=newFile("abc.txt");
202
System.out.println("getName() : "+f1.getName());
System.out.println("getAbsolutePath() : "+f1.getAbsolutePath());
System.out.println("canRead() : "+f1.canRead());
System.out.println("canWrite() : "+f1.canWrite());
System.out.println("isFile() : "+f1.isFile());
System.out.println("isDirectory : "+f1.isDirectory());
System.out.println("File size in bytes : "+f1.length());
System.out.println("File exists() : "+f1.exists());
}
}
Output:
getName() : abc.txt
getAbsolutePath() : C:\Java\Jdk1.6.0_01\binabc.txt
canRead() : true
canWrite() : true
isFile() : true
isDirectory : false
File size in bytes : 53
File exists() : true
13.9 Reading / Writing Characters
❖ The two subclasses used for handling characters in files are FileReader (for reading characters)
and FileWriter (for writing characters)
i) FileReader
❖ FileReader class is used to read data from the file. It is character-oriented class which is used
for file handling in Java.
❖ Its two most commonly used constructors are shown here:
FileReader(String filePath)
FileReader(File fileObj)
Either can throw a FileNotFoundException. Here, filePath is the full path name of a file, and
fileObj is a File object that describes the file.
Methods
Method Description
int read() It is used to return a character in ASCII form. It returns -1 at the end of file.
void close() It is used to close the FileReader class.
Example:
Method Description
void write(String text) It is used to write the string into FileWriter.
void write(char c) It is used to write the char into FileWriter.
void write(char[] c) It is used to write char array into FileWriter.
void flush() It is used to flushes the data of FileWriter.
void close() It is used to close the FileWriter.
Example:
Method Description
int available() It is used to return the estimated number of bytes that can be
read from the input stream.
int read() It is used to read the byte of data from the input stream.
int read(byte[] b) It is used to read up to b.length bytes of data from the input
stream.
int read(byte[] b, int off, int len) It is used to read up to len bytes of data from the input stream.
long skip(long x) It is used to skip over and discards x bytes of data from the
input stream.
FileChannel getChannel() It is used to return the unique FileChannel object associated
with the file input stream.
FileDescriptor getFD() It is used to return the FileDescriptor object.
protected void finalize() It is used to ensure that the close method is call when there is
no more reference to the file input stream.
205
void close() It is used to close the stream.
Example:
//Java Program using FileInputStream Class
import java.io.*;
public class DataStreamExample
{
public static void main(String args[])
{
try
{
FileInputStream fin=new FileInputStream("D:\testout.txt");
int i=0;
while((i=fin.read())!=-1)
{
System.out.print((char)i);
}
fin.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Output:
Welcome to Java Programming.
ii) FileOutputStream
❖ The FileOutputStream is an output stream used for writing data to a file.
❖ We can write byte-oriented as well as character-oriented data through FileOutputStream class.
❖ Its most commonly used constructors are shown here:
FileOutputStream(String filePath)
FileOutputStream(File fileObj)
FileOutputStream(String filePath, boolean append)
FileOutputStream(File fileObj, boolean append)
Methods
Method Description
206
protected void finalize() It is used to clean up the connection with the file output
stream.
void write(byte[] ary) It is used to write ary.length bytes from the byte array to the
file output stream.
void write(byte[] ary, int off, int len) It is used to write len bytes from the byte array starting at
offset off to the file output stream.
void write(int b) It is used to write the specified byte to the file output stream.
FileChannel getChannel() It is used to return the file channel object associated with the
file output stream.
FileDescriptor getFD() It is used to return the file descriptor associated with the
stream.
void close() It is used to closes the file output stream.
Example:
//Java Program using FileOutputStream
import java.io.*;
public class FileOutputStreamExample
{
public static void main(String args[])
{
try
{
FileOutputStream fout=new FileOutputStream("D:\testout.txt");
String s="Welcome to Java Programming.";
byte b[]=s.getBytes();//Converting string into byte array
fout.write(b);
fout.close();
System.out.println("Success...");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Output:
Success...
The content of a text file testout.txt is set with the data Welcome to Java Programming.testout.txt
Welcome to Java Programming.
13.11 Other Stream Classes
❖ Java supports many other input / output streams that we might find useful in some situations.
Object Streams
❖ The object streams are created using the ObjectInputStream and ObjectOutputStream
classes.
❖ In this case, we may declare records as objects and use the object classes to write and read these
207
objects from files.
❖ This process is known as object serialization.
Piped Streams
❖ Piped streams provide functionality for threads to communicate and exchange data between
them.
❖ The write thread sends data to a read thread through a pipeline that connects an object of
PipedInputStream to an object of PipedOutputStream.
❖ The objects inputPipe and outputPipe are connected using the connect() method.
PushBack Streams
❖ The pushback streams created by the classes PushbackInputStream and PushbackReader
can be used to push a single byte or character (that was previously read) back into the input
stream so that it can be reread.
❖ This is commonly used with parsers.
❖ When a character indicating a new input token is read, it is pushed back into the input stream
until the current input token is processed. It is then reread when processing of the next input
token is initiated.
PushbackInputStream
❖ Pushback is used on an input stream to allow a byte to be read and then returned (that is, “pushed
back”) to the stream.
❖ The PushbackInputStream class provides a mechanism to “peek” at what is coming from an
input stream without disrupting it.
❖ PushbackInputStreamhas the following constructors:
PushbackInputStream(InputStream inputStream)
The first form creates a stream object that allows one byte to be returned to the input stream.
The second form creates a stream that has a pushback buffer that is numBytes long. This allows
multiple bytes to be returned to the input stream.
// Demonstrate unread().
import java.io.*;
class PushbackInputStreamDemo
{
public static void main(String args[]) throws IOException
{
String s = "if (a == 4) a = 0;\n";
byte buf[] = s.getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(buf);
PushbackInputStream f = new PushbackInputStream(in);
int c;
while ((c = f.read()) != -1)
{
switch(c)
{
case '=':
if ((c = f.read()) == '=')
System.out.print(".eq.");
else
{
System.out.print("<-");
f.unread(c);
}
break;
default:
System.out.print((char) c);
break;
}
}
}
}
Output:
if (a .eq. 4) a <- 0;
ii) PushbackReader
❖ The PushbackReader class allows one or more characters to be returned to the input stream.
This allows us to look ahead in the input stream.
❖ An IOException will be thrown if there is an attempt to return a character when the pushback
buffer is full.
❖ Here are its two constructors:
209
PushbackReader(Reader inputStream)
PushbackReader(Reader inputStream, int bufSize)
The first form creates a buffered stream that allows one character to be pushed back. In the
second, the size of the pushback buffer is passed in bufSize.
Methods
Method Description
int read() It is used to read a single character.
void mark(int readAheadLimit) It is used to mark the present position in a stream.
boolean ready() It is used to tell whether the stream is ready to be read.
boolean markSupported() It is used to tell whether the stream supports mark() operation.
long skip(long n) It is used to skip the character.
void unread (int c) It is used to pushes back the character by copying it to the
pushback buffer.
void unread (char[] cbuf) It is used to pushes back an array of character by copying it to the
pushback buffer.
void reset() It is used to reset the stream.
void close() It is used to close the stream.
Example:
// Demonstrate unread().
import java.io.*;
class PushbackReaderDemo
{
public static void main(String args[]) throws IOException
{
String s = "if (a == 4) a = 0;\n";
char buf[] = new char[s.length()];
s.getChars(0, s.length(), buf, 0);
CharArrayReader in = new CharArrayReader(buf);
PushbackReader f = new PushbackReader(in);
int c;
while ((c = f.read()) != -1)
{
switch(c)
{
case '=':
if ((c = f.read()) == '=')
System.out.print(".eq.");
else
{
System.out.print("<-");
f.unread(c);
}
break;
210
default:
System.out.print((char) c);
break;
}
}
}
}
Filtered Streams
❖ Java supports two abstract classes, namely, FilterInputStream and FilterOutputStream that
provide the basic capability to create input and output streams for filtering input/output in a
number of ways.
❖ These streams known as filters sit between an input stream and an output stream and perform
some optional processing on the data they transfer.
❖ The DataInputStream and DataOutputStream classes are used as filters for handling
primitive type data.
❖ The constructors defined for the FilterInputStream and FilterOutputStream classes are
shown below:
FilterOutputStream(OutputStream os)
FilterInputStream(InputStream is)
❖ The methods provided in these classes are identical to those in InputStream and
OutputStream.
Exercises:
1. Define stream.
2. What is file stream?
3. What are input and output streams?
4. Define Byte stream.
5. Define print stream.
211
6. Define character stream.
7. Distinguish between Input Stream and Output Stream classes.
8. Distinguish between Byte Stream and Character Stream clases.
9. Explain about buffered ByteStream and its methods.
10. Explain about Reader and Writer Stream classes.
11. What is serialization?
12. Explain serialization concepts in detail.
13. Define random access file.
14. Define streamtokenizer.
15. Explain various File class methods in detail.
*****************************
*******************************************************************************
Chapter 14 Applets
*******************************************************************************
14.1 Introduction
❖ An Applet is a Java program that runs in a Web browser.
❖ Applets are small Java programs that are primarily used for Internet computing. They can be
transported over the Internet from one computer to another and runs using the Appletviewer or
212
any Web Browser that supports Java.
❖ An Applet, like any other application program, can do many things for us. It can perform
arithmetic operations, display graphics, play sounds, accept user input, create animation, and
play interactive games.
❖ An Applet is embedded in an HTML page using the APPLET tag and hosted on a web server.
❖ Applets are used to make the web site more dynamic and entertaining.
Local and Remote Applets
❖ An applet developed locally and stored in a local system is known as a local applet. When
a Web page is trying to find a local applet, it does not need to use the Internet, and therefore the
local system does not require the Internet connection. It simply searches the directories in the
local system and locates and loads the specified applet.
❖ A remote applet is that which is developed by someone else and stored on a computer
connected to the Internet. If our system is connected to the Internet, we can download the
remote applet onto our system via the Internet and run it.
❖ In order to locate and load a remote applet, we must know the applet’s address on the Web. This
address is known as Uniform Resource Locator (URL) and must be specified in the applet’s
HTML document as the value of the CODEBASE attribute.
Example:
CODEBASE=http://www.netserve.com/applets
In the case of local applets, CODEBASE may be absent or may specify a local directory.
14.2 Differences between Applets and Applications
Applet Application
Applets are small Java programs that are Applications are stand-alone programs that can be
designed to be included with the HTML web executed independently without using the web
document. They require a Java-enabled web browser.
browser for execution.
Applet does not require a main function for Application program requires a main function for
its execution. its execution.
Applets can't read from or write to the files on An application can read from or write to the files
the local computer. on the local computer.
An Applet requires Graphical User Interface An application doesn't require Graphical User
(GUI). Interface (GUI).
Applets can't communicate with other servers The application can communicate with other
on the network. servers on the network.
Applets can only access the browser specific Applications can access all kinds of resources
services. They don’t have access to the local available on the system.
system.
An applet program is needed to perform An application program is needed to perform
small tasks or the part of it. some task directly for the user.
213
14.3 Applet Basics
❖ Applet is a Java program that can be embedded into a web page.
❖ It runs inside the web browser and works at client side.
❖ The applet code uses the services of the two classes, namely, Applet and Graphics from the
Java class library.
❖ The Applet class provides the necessary support for applets.
❖ The Applet class is contained in the java.applet package. Thus, all applets must import
java.applet.
❖ Applets must also import java.awt.AWT stands for Abstract Window Toolkit.
❖ Applets are executed by either a Web browser or an applet viewer.
❖ Applet contains several methods that give us detailed control over the execution of
our applet.
Example:
/*
<applet code="MyApplet" width=200 height=60>
</applet>
*/
❖ This comment contains an APPLET tag that will run an applet called MyApplet in a window
that is 200 pixels wide and 60 pixels high.
❖ An applet code will have a general format as shown below:
import java.awt.*;
import java.applet.*;
………………….
………………….
public class appletclassnaame extends Applet
{
…………………..
…………………..
public void paint(Graphics G)
{
………………….
…………………. // Applet operations code
}
…………………..
…………………..
}
The appletclassname is the main class for the applet. When the applet is loaded, Java creates an
instance of the class, and then a series of Applet class methods are called on that instance to
execute the code.
Example:
init() method
❖ The init() method is the first method to be called.
❖ Variable declaration and initialization operations are performed in this method.
❖ This method is called only once during the run time of our applet.
❖ The general form is:
public void init()
{
…………
………… (Action)
…………
}
start() method
❖ The start() method is called after init().
❖ The start() method contains the actual code of the applet that should run.
❖ It also executes whenever the applet is restored, maximized or moving from one tab to another
tab in the browser.
❖ The general form is:
public void start()
{
…………
………… (Action)
…………
}
stop() method
❖ The stop() method stops the execution of the applet.
❖ The stop() method executes when the applet is minimized or when moving from one tab to
another in the browser.
❖ The general form is:
public void stop()
217
{
…………
………… (Action)
…………
}
destroy() method
❖ The destroy() method executes when the applet window is closed or when the tab containing the
webpage is closed.
❖ The stop() method is always called before destroy(). The destroy() method removes the applet
object from memory.
❖ The general form is:
public void destroy()
{
…………
………… (Action)
…………
}
paint()
❖ The paint() method is used to redraw the output on the applet display area.
❖ The paint() method executes after the execution of start() method and whenever the applet or
browser is resized.
❖ The general form is:
public void paint(Graphics g)
{
…………
………… (Display statements)
…………
}
Example:
218
}
public void paint(Graphicsg)
{
System.out.println("Painting...");
}
public void destroy()
{
System.out.println("Applet destroyed");
}
}
Output:
Applet initialized
Applet execution started
Painting…
Painting…
Applet execution stopped
Applet destroyed
update()
❖ This method is called when the applet has requested that a portion of its window be redrawn.
❖ The default version of update() first fills an applet with the default background color and then
calls paint().
❖ If we fill the background using different color in paint(), the user will experience a flash of the
default background each time update() is called – that is, whenever the window is repainted.
❖ One way to avoid is to override the update() method so that it performs all necessary display
activities.
Example:
// Java program using update() method
import java.awt.*;
import java.applet.*;
/*
<applet code=PaintTest width=100 height=100>
</applet>
*/
public class PaintTest extends Applet
{
public void paint(Graphics g)
{
System.out.println("In paint");
}
public void update(Graphics g)
{
System.out.println("In update");
}
}
219
14.7 Simple Applet Display Methods
❖ Applets are displayed in a window and they use the AWT to perform input and output.
drawString()
❖ The drawString() method is used to output a string to an applet.
❖ This method is a member of the Graphics class.
❖ It is called from within either update() or paint().
❖ The general form is:
void drawString(String message, int x, int y)
Here, message is the string to be output beginning at x, y. In a Java window, the upper left corner
is location 0, 0. The drawString method will not recognize newline characters. If we want to start
a line of text on another line, we must do so manually, specifying the precise x, y locations where
we want the line to begin.
setBackground()
❖ The setBackground() method is used to change the background color of an applet’s window.
❖ This method is defined by the Component class.
❖ The general form is:
void setBackground(Color newColor)
Here, newColor specifies the new color. The class Color defines the constants shown here that
can be used to specify colors:
Color.black Color.magenta
Color.blue Color.orange
Color.cyan Color.pink
Color.darkGray Color.red
Color.gray Color.white
Color.green Color.yellow
Color.lightGray
Example:
setBackground(Color.green);
setForeground()
❖ The setForeground() method is used to change the color of the text in the applet’s window. This
method is defined by the Component class.
❖ The general form is:
void setForeground(Color newColor)
Here, newColor specifies the new color.
Example:
setForeground(Color.red);
220
❖ A good place to set the foreground and background colors is in the init() method. The default
foreground color is black. The default background color is light gray.
getBackground()
❖ The getBackground() method is used to obtain the current settings for the background color.
❖ This method is also defined by the Component class. The general form is:
Color getBackground()
getForeground()
❖ The getForeground() method is used to obtain the current settings for the foreground color.
❖ This method is also defined by the Component class. The general form is:
Color getForeground()
Example:
// A simple applet that sets the foreground and background colors and outputs a string
import java.awt.*;
import java.applet.*;
/*
<applet code="Sample" width=300 height=50>
</applet>
*/
public class Sample extends Applet
{
String msg;
// Set the foreground and background colors.
public void init()
{
setBackground(Color.cyan);
setForeground(Color.red);
msg="Inside init() –";
}
// Initialize the string to be displayed.
public void start()
{
msg+="Inside start()..";
}
// Display msg in applet window.
public void paint(Graphics g)
{
msg+="Inside paint().";
g.drawString(msg, 10, 30);
}
}
Output:
Requesting Repainting
repaint()
❖ The repaint() method causes the AWT runtime system to execute the update() method of the
221
Component class which clears the window with the background color of the applet and then calls
the paint() method.
❖ The repaint() method has four forms. The simplest version of repaint() is shown here:
void repaint()
This version causes the entire window to be repainted. The following version specifies a region
that will be repainted:
void repaint(int left, int top, int width, int height)
Here, the coordinates of the upper-left corner of the region are specified by left and top, and the
width and height of the region are passed in width and height. These dimensions are specified in
pixels.
void repaint(long maxDelay)
void repaint(long maxDelay, int x, int y, int width, int height )
Here, maxDelay specifies the maximum number of milliseconds that can elapse before update()
is called. If the time elapses before update() can be called, it isn’t called. There is no return value
or exception thrown, so we must be careful.
14.8 Development and Execution of a Simple Applet
❖ The development and execution of an Applet involves the following steps:
1) Writing the applet’s code (.java file)
2) Compiling the applet’s code (.class file will be ready after compilation)
3) Writing the HTML code (.html file)
4) Invoking the appletviewer utility from a command shell window
Writing the applet’s code
// Java program to create an Applet
// HelloApplets.java
import java.awt.*;
import java.applet.*;
❖ Compiling an applet is exactly the same as compiling an application. Therefore, we can use the
Java compiler to compile the applet.
❖ The steps required for compiling the HelloApplets applet are:
222
1. Move to the directory containing the source code and type the following command:
Javac HelloApplets.java
2. The compiled output file called HelloApplets.class is placed in the same directory as the source.
3. If any error message is received, then we must check for errors, correct them and compile the
applet again.
Writing the HTML code
❖ The code for the HelloApplets.html file shall be keyed in, as shown here:
<html>
<head>
<title>Hello World !</title>
</head>
<body>
<applet code=”HelloApplets.class” width=400 height=200>
</applet>
</body>
</html>
Invoking the appletviewer utility from a command shell window
❖ The appletviewer is available as part of the Java Development Kit that we have been using so far.
❖ We can use it to run our applet as follows:
appletviewer HelloApplets.html
❖ The showStatus() method is used to display a message in the status window of the browser or
applet viewer on which the applet is running.
❖ The status window is a good place to give the user feedback about what is occurring in the applet,
suggest options, or possibly report some types of errors.
❖ The status window also makes an excellent debugging aid, because it gives an easy way to output
information about our applet.
Example:
/*
<applet code="StatusWindow" width=300 height=50>
</applet>
*/
public class StatusWindow extends Applet
{
223
public void init()
{
setBackground(Color.cyan);
}
// Display msg in applet window.
public void paint(Graphics g)
{
g.drawString("This is in the applet window.",10,20);
showStatus("This is shown in the status window.");
}
}
14.10 The APPLET Tag
❖ The <APPLET> tag is used to incorporate an applet into a web page.
❖ The <APPLET> tag creates a space of the required size and then displays the applet output in that
space.
❖ The APPLET tag is used to start an applet from both an HTML document and from an applet
viewer.
❖ An applet viewer will execute each APPLET tag that it finds in a separate window, while web
browsers like Netscape Navigator, Internet Explorer, and HotJava will allow many applets on a
single page.
❖ The syntax for the standard Applet tag is shown here. Bracketed items are optional.
<APPLET
[CODEBASE=codebase_URL]
CODE=AppletFileName.class
[ALT=alternate_text]
[NAME=applet_instance_name]
WIDTH=pixels
HEIGHT=pixels
[ALIGN=alignment]
[VSPACE=pixels]
[HSPACE=pixels]
>
[<PARAM NAME=name1 VALUE=value1>]
[<PARAM NAME=name2 VALUE=value2>]
………………
………………
[Text to be displayed in the absence of Java]
</APPLET>
CODE=AppletFileName.class
WIDTH=pixels
HEIGHT=pixels
The attributes of the APPLET tag are as follows:
Attribute Meaning
224
CODEBASE= codebase_URL Specifies the URL of the directory in which the applet
resides. If the applet resides in the same directory as the
HTML file, then the CODEBASE attribute may be
omitted entirely.
CODE= AppletFileName.class CODE is a required attribute that gives the name of the
file containing our applet’s compiled .class file. This file
is relative to the code base URL of the applet, which is
the directory that the HTML file was in or the directory
indicated by CODEBASE if set.
ALT=alternate_text The ALT tag is an optional attribute used to specify a
short text message that should be displayed if the
browser understands the APPLET tag but can’t
currently run Java applets.
NAME=applet_instance_name A name for the applet may optionally be specified so
that other applets on the page may refer to this applet.
This facilitates inter-applet communication.
WIDTH=pixels WIDTH and HEIGHT are required attributes that give
HEIGHT=pixels the size (in pixels) of the applet display area.
ALIGN=alignment ALIGN is an optional attribute that specifies the
alignment of the applet. Possible values are: LEFT,
RIGHT, TOP, BOTTOM, MIDDLE, BASELINE,
TEXTTOP, ABSMIDDLE, and ABSBOTTOM.
VSPACE=pixels VSPACE specifies the amount of vertical blank space,
in pixels, above and below the applet. Used only when
some vertical alignment is specified with the ALIGN
attribute (TOP, BOTTOM, etc.). This attribute is
optional.
HSPACE=pixels HSPACE specifies the amount of horizontal blank
space, in pixels, on each side of the applet. Used only
when ALIGN is set to LEFT or RIGHT. This attribute
is optional.
PARAM NAME and VALUE The PARAM tag allows us to specify applet-specific
arguments in an HTML page. Applets access their
attributes with the getParameter() method.
225
String str;
public void init()
{
str=getParameter("string"); // Receiving parameter value
if (str==null)
str="Java";
str="Hello"+str; // Using the value
}
public void paint(Graphics g)
{
g.drawString(str,10,20);
}
}
The HTML file for HelloJavaParam applet.
<HTML>
<!-- Parameterized HTML file -- >
<HEAD>
<TITLE>Welcome to Java Applets </TITLE>
</HEAD>
<BODY>
<APPLET CODE=HelloJavaParam.class WIDTH=400 HEIGHT=200>
<PARAM NAME=”string” VALUE=”Applet!”>
</APPLET>
</BODY>
</HTML>
❖ Save this file as HelloJavaParam.html and then run the applet using the applet viewer as follows:
appletviewer HelloJavaParam.html
14.12 Displaying Numeric Values
❖ In applets, we can display numerical values by first converting them into strings and then using
the drawString() method of Graphics class.
❖ We can do this easily by calling the valueOf() method of String class.
Example:
❖ Applets work in a graphical environment. Therefore, applets treat inputs as text strings.
❖ We must first create an area of the screen in which user can type and edit input items (which may
be any data type).
❖ We can do this by using the TextField class of the applet package. Once text fields are created for
receiving input, we can type the values in the fields and edit them, if necessary.
Example:
Method Description
clearRect() Erases a rectangular area of the canvas.
copyArea() Copies a rectangular area of the canvas to another area.
drawArc() Draws a hollow arc.
drawLine() Draws a straight line.
drawOval() Draws a hollow oval.
drawPolygon() Draws a hollow polygon.
drawRect() Draws a hollow rectangle.
drawRoundRect() Draws a hollow rectangle with rounded corners.
drawString() Displays a text string.
fillArc() Draws a filled arc.
fillOval() Draws a filled oval.
fillPolygon() Draws a filled polygon.
fillRect() Draws a filled rectangle.
fillRoundRect() Draws a filled rectangle with rounded corners.
getColor() Retrieves the current drawing color.
getFont() Retrieves the currently used font.
getFontMetrics() Retrieves information about the current font.
setColor() Sets the drawing color.
setFont() Sets the font.
drawRect()
will draw a rectangle starting at (10, 60) having a width of 40 pixels and a height of 30 pixels.
The drawRect() method draws only the outline of a box.
fillRect()
❖ The fillRect() method is used to draw a solid box.
❖ This also takes four parameters corresponding to the starting point, the width and the height of
the rectangle.
❖ For example, the statement
g.fillRect(60, 10, 30, 80);
❖ The drawRoundRect() and fillRoundRect() methods are used to draw rounded rectangles
(which are rectangles with rounded edges).
❖ These two methods are similar to drawRect() and fillRect() except thatthey taketwo extra
arguments representing the width and height of the angle of corners.
❖ These extra parameters indicate how much of corners will be rounded.
Example:
229
g.fillRect(60, 10, 30, 80);
g.drawRoundRect(10, 100, 80, 50, 10, 10);
g.fillRoundRect(20, 110, 60, 30, 5, 5);
g.drawLine(100, 10, 230, 140);
g.drawLine(100, 140, 230, 10);
}
}
LineRect.html
<APPLET
CODE=LineRect.class
WIDTH=250
HEIGHT=200>
</APPLET>
Output:
Applet
Applet Started
Output:
231
arguments for drawOval() method and the last two represent the starting angle of the arc and
the number of degrees around the arc.
❖ The fillArc() method is used to fill anarc.Filled arcs are drawnas if they were sections of a pie.
Example:
Output:
Example:
Exercises:
1. Define applet.
2. Distinguish between applet and application.
3. Explain the various methods of Applet Class.
4. Describe the life cycle of an applet.
5. Discuss the applet display methods with an example.
6. Define <applet> tag.
7. Explain drawString method with an example program.
8. Explain about Graphics class in applets.
9. Define setColor() method.
234
10. Write an applet program to draw lines and rectangles.
*************************************************************************
Chapter 15 Introduction to Data Structures
*************************************************************************
15.1 What is a Data Structure?
❖ A Data Structure is a way of storing and organizing data in a computer so that it can be
used efficiently.
❖ Data Structures provide a means to manage large amounts of data efficiently.
❖ Efficient data structures are a key to designing efficient algorithms.
❖ Data Structures can be used to organize the storage and retrieval of information stored in
both main memory and secondary memory.
❖ Data Structures where data elements are arranged sequentially or linearly are
called linear data structures.
❖ Linear data structures are easy to implement because computer memory is arranged in a linear
way.
❖ Its examples are: Array, Stack, Queue, Linked List etc.
Array:
❖ An Array is a collection of data items having the same data types.
Stack:
❖ A Stack is a LIFO (Last-In First-Out) data structure where the element that is added last will be
deleted first.
❖ All operations on stack are performed from one end called TOP.
Queue:
❖ A Queue is a FIFO (First-In First-Out) data structure where the element that is added first will
be deleted first.
236
❖ In queue, insertion is performed from one end called REAR and deletion is performed from
another end called FRONT.
Linked List:
❖ A Linked List is a linear data structure, in which the elements are not stored at contiguous memory
locations.
❖ A Linked List is a collection of nodes where each node is made up of a data element and a
reference/link to the next node in the sequence.
ii) Non Linear Data Structures
❖ Data Structures where data elements are not arranged sequentially or linearly are
called non-linear data structures.
❖ Non-linear data structures are not easy to implement in comparison to linear data structure.
❖ It utilizes computer memory efficiently in comparison to a linear data structure.
❖ Its examples are: Trees and Graphs.
Trees:
❖ A tree is a non-linear data structure because it does not store in a sequential manner.
❖ It is a hierarchical structure as elements in a Tree are arranged in multiple levels.
❖ The topmost node in the hierarchy is called root node and the bottommost nodes are called leaf
nodes.
❖ Each node contains some data and a link or reference to adjacent nodes.
Graphs:
❖ A Graph is a non-linear data structure consisting of nodes and edges.
❖ The nodes are also referred to as vertices and the edges are lines that connect any two nodes in
the graph.
❖ Graphs are also used in social networks like LinkedIn, Facebook etc.
15.2 Advantages and Disadvantages of Data Structures
Advantages:
1) Allows easier processing of data.
2) It allows information stored on disk very efficiently.
3) These are necessary for designing an efficient algorithm.
4) It provides management of databases like indexing with the help of hash tables and arrays.
5) We can access data anytime and anywhere.
6) It is secure way of storage of data.
7) Graphs models real life problems
8) It allows processing of data on software system
Disadvantages:
237
1) It is applicable only for advanced users.
2) If any issue occurs it can be solved only by experts.
3) Slow access in case of some data types
15.4 Operations on Data Structures
1) Traversing: Traversing the data structure means visiting each element of the data structure in
order to perform some specific operation like searching or sorting.
Example: If we need to calculate the average of the marks obtained by a student in 5 different
subjects, we need to traverse the complete array of marks and calculate the total sum then we will
divide that sum by the number of subjects i.e. 5, in order to find the average.
2) Insertion: Insertion can be defined as the process of adding the elements to the data structure at
any location.
If the size of data structure is n then we can only insert n-1 data elements into it.
3) Deletion:The process of removing an element from the data structure is called Deletion. We can
delete an element from the data structure at any random location.
If we try to delete an element from an empty data structure then underflow occurs.
4) Searching: The process of finding the location of an element within the data structure is called
Searching. There are two algorithms to perform searching, Linear Search and Binary Search.
5) Sorting: The process of arranging the data structure in a specific order is known as Sorting. There
are many algorithms that can be used to perform sorting, for example, insertion sort, selection sort,
bubble sort, etc.
6) Merging: When two lists List A and List B of size M and N respectively, of similar type of
elements joined to produce the third list, List C of size (M+N), then this process is called merging.
15.5 DS Algorithm
What is an Algorithm?
❖ An Algorithm is a step by step procedure for solving any problem.
❖ The following are the characteristics of an algorithm:
1) Input: An algorithm has zero or more inputs.
2) Output: An algorithm has one or more outputs.
3) Definiteness: The steps in the algorithm must be clearly defined and detailed.
4) Finiteness: The algorithm must terminate after a finite number of steps.
5) Effectiveness: An algorithm is also generally expected to be effective. Effectiveness is precisely
measured after translating the algorithm into a Computer program.
Algorithm Complexity
❖ The performance of an algorithm can be measured on the basis of the following properties:
238
1. Time Complexity
2. Space Complexity
1. Time Complexity:
❖ The Time Complexity of an algorithm is the amount of time required to complete the execution.
2. Space Complexity:
❖ Space Complexity is the amount of memory used by the algorithm to execute and produce the
result.
Analysis of Algorithms
❖ There are three types of analysis that we perform on a particular algorithm.
• Best Case − Minimum time required for program execution.
• Average Case − Average time required for program execution.
• Worst Case − Maximum time required for program execution.
15.6 Asymptotic Notations
❖ Asymptotic Notations are the expressions that are used to represent the complexity of an
algorithm.
❖ There are mainly three types of asymptotic notations:
• Big-O Notation
• Omega Notation
• Theta Notation
i) Big-O Notation (O)
❖ The Big-O Notation is used to express the upper bound of an algorithm’s running time.
❖ It measures the worst case time complexity of an algorithm.
f(n) = O(g(n))
Here, f(n) and g(n) are the two functions defined for positive integers.
ii) Omega Notation (Ω)
❖ The Omega Notation is used to express the lower bound of an algorithm's running time.
❖ It measures the best case time complexity of an algorithm.
f(n) = Ω (g(n))
Here, f(n) and g(n) are the two functions defined for positive integers.
iii) Theta Notation (Θ)
❖ The Theta Notation is used to express both the lower bound and the upper bound of an
algorithm's running time.
❖ It measures thee average case time complexity of an algorithm.
f(n)= θg(n)
239
Here, f(n) and g(n) are the two functions defined for positive integers.
15.7 Abstract Data Type (ADT)
What is ADT?
❖ ADT stands for Abstract Data Type.
❖ An abstract data type is special kind of data type, whose behavior is defined by a set of
values and set of operations.
❖ The definition of ADT only mentioned what operations are to be performed but not how these
operations will be implemented.
❖ It does not specify how data will be organized in memory and what algorithms will be used
for implementing the operations.
❖ It is called “abstract” because it gives an implementation-independent view. The process of
providing only the essentials and hiding the details is known as abstraction.
❖ Some examples of ADT are Stack, Queue, List, etc.
❖ For example, an abstract stack could be defined by three operations: push, that inserts some data
items onto the stack, pop, that extracts an item from it, and peek, that allows data on top of the
stack to be examined without removal.
❖ Abstract data types are purely theoretical entities, used to simplify the description of abstract
algorithms, to classify and evaluate data structures, and to formally describe the type systems
of programming languages.
Advantages of ADT
❖ ADT is reusable and ensures robust data structure.
❖ It reduces coding efforts.
❖ Encapsulation ensures that data cannot be corrupted.
❖ ADT is based on principles of Object Oriented Programming (OOP) and Software Engineering
(SE).
❖ It specifies error conditions associated with operations.
15.8 List ADT
A list is a sequence of zero or more elements of a given type a1, a2,..., an (n=0)
n : length of the list
a1 : first element of the list
an : last element of the list
n=0 : empty list
elements can be linearly ordered according to their position in the list
We say ai precedes ai + 1, ai + 1 follows ai, and ai is at position i
Let us assume the following:
L : list of objects of type element type
240
x : an object of this type
p : of type position
END(L) : a function that returns the position following the last position in the list L
Define the following operations:
1. Insert (x, p, L)
Insert x at position p in list L
If p = END(L), insert x at the end
If L does not have position p, result is undefined
2. Locate (x, L)
returns position of x on L
returns END(L) if x does not appear
3. Retrieve (p, L)
returns element at position p on L
undefined if p does not exist or p = END(L)
4. Delete (p, L)
delete element at position p in L
undefined if p = END(L) or does not exist
5. Next (p, L)
returns the position immediately following position p
6. Prev (p, L)
returns the position previous to p
7. Makenull (L)
causes L to become an empty list and returns position END(L)
8. First (L)
returns the first position on L
9. Printlist (L)
print the elements of L in order of occurrence
15.9 Implementation of List
❖ A list can be implemented in two ways:
1. Array Based Implementation
2. Linked List Implementation
1. Array Based Implementation
❖ This implementation stores the list in an array.
241
❖ The position of each element is given by an index from 0 to n-1, where n is the number of
elements.
❖ The element with the index can be accessed in constant time (ie) the time to access does not
depend on the size of the list.
❖ The time taken to add an element at the end of the list does not depend on the size of the list.
But the time taken to add an element at any other point in the list depends on the size of the list
because the subsequent elements must be shifted to next index value. So the additions near the
start of the list take longer time than the additions near the middle or end.
❖ Similarly when an element is removed, subsequent elements must be shifted to the previous
index value. So removals near the start of the list take longer time than removals near the middle
or end of the list.
Problems with Array implementation of lists
❖ Insertion and deletion are expensive. For example, inserting at position 0 (a new first element)
requires first pushing the entire array down one spot to make room, whereas deleting the first
element requires shifting all the elements in the list up one, so the worst case of these operations
is O(n).
❖ Even if the array is dynamically allocated, an estimate of the maximum size of the list is
required. Usually this requires a high over-estimate, which wastes considerable space. This
could be a serious limitation, if there are many lists of unknown size.
❖ Simple arrays are generally not used to implement lists. Because the running time for insertion
and deletion is so slow and the list size must be known in advance.
243
************************************************************
Chapter 16 Linked Lists
************************************************************
16.1 Introduction to Linked List
❖ A Linked List is a linear data structure.
❖ A Linked List consists of a set of nodes where each node contains a data field and a reference
(link) to the next node in the list.
❖ The first node of the linked list is called the head, and the last node of the list is called the tail
of the list.
❖ A linked list is another way to collect similar data. However, unlike an array, elements in a
linked list are not stored in consecutive memory locations.
❖ It is a commonly used data structure in Computer programs and helps us to build even more
complex data structures like Stacks, Queues, etc.
❖ The Figure 16.1 illustrates a Linked List
244
Array works with a static memory. Here static The Linked list works with dynamic memory.
memory means that the memory size is fixed and Here, dynamic memory means that the memory
cannot be changed at the run time. size can be changed at the run time according to
our requirements.
Array elements are independent of each other. Linked list elements are dependent on each other.
As each node contains the address of the next
node so to access the next node, we need to access
its previous node.
Array takes more time while performing any Linked list takes less time while performing any
operation like insertion, deletion, etc. operation like insertion, deletion, etc.
Accessing any element in an array is faster as the Accessing an element in a linked list is slower as
element in an array can be directly accessed it starts traversing from the first element of the
through the index. linked list.
In the case of an array, memory is allocated at In the case of a linked list, memory is allocated at
compile-time. run time.
Memory utilization is inefficient in the array. For Memory utilization is efficient in the case of a
example, if the size of the array is 6, and array linked list as the memory can be allocated or
consists of 3 elements only then the rest of the deallocated at the run time according to our
space will be unused. requirement.
246
Figure 16.6: Inserting a node with data N at the beginning of the list
b) Inserting a node at the end of the list
❖ To insert a node at the end of the list the following algorithm is followed –
• Traverse the list until we find the last node.
• The new node’s reference is assigned to the last node’s next field.
Figure 16.7: Inserting a node with data N at the end of the list
c) Inserting a node at a specified position in the list
❖ To insert a node at a specified position in the list the following algorithm is followed –
• Traverse (position – 1) times or till the end of the list is reached and maintain previous and
current references.
• Assign the reference of the new node to the prev node’s next field.
• Assign the cur node’s reference to the new node’s next field.
Example:
251
Output:
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
1
Enter the element to insert at the beginning
5
Singly Linked List = 5
Do you want to continue? (Type Y or N)
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
1
Enter the element to insert at the beginning
7
Singly Linked List = 7->5
Do you want to continue? (Type Y or N)
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
2
Enter the element to insert at the end
4
Singly Linked List = 7->5->4
Do you want to continue? (Type Y or N)
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
252
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
2
Enter the element to insert at the end
2
Singly Linked List = 7->5->4->2
Do you want to continue? (Type Y or N)
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
1
Enter the element to insert at the beginning
9
Singly Linked List = 9->7->5->4->2
Do you want to continue? (Type Y or N)
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
3
Enter the element to insert at any position
3
Enter the position
3
Singly Linked List = 9->7->3->5->4->2
Do you want to continue (Type y or n)
y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
253
6. Exit
Enter Your Choice
3
Enter the element to insert at any position
2
Enter the position
2
Singly Linked List = 9->2->7->3->5->4->2
Do you want to continue? (Type Y or N)
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
5
Singly Linked List = 9->2->7->3->5->4->2
Do you want to continue? (Type Y or N)
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
4
Enter the position to delete
4
Singly Linked List = 9->2->7->5->4->2
Do you want to continue? (Type Y or N)
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice
5
Singly Linked List = 9->2->7->5->4->2
Do you want to continue? (Type Y or N)
254
Y
Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the List
6. Exit
Enter Your Choice:
6
Do you want to continue? (Type Y or N)
N
Advantages and Disadvantages of Singly Linked List
Advantages:
1) It is very easier for the accessibility of a node in the forward direction.
2) Insertions and deletions can be done easily.
3) Its size is not fixed. It can be extended or reduced according to requirements.
4) The Singly Linked List is the very easy data structure to implement.
5) It is less expensive.
Disadvantages:
1) No direct access to individual elements is possible. We have to access elements sequentially
starting from the first node.
2) A Singly Linked List uses more memory as compared to an array to store the reference to the
next node.
3) The accessing of a node is very time consuming.
4) It is not easy to sort the elements stored in the linear linked list.
Applications of Singly Linked List
❖ Linked Lists can be used to implement Stacks, Queues.
❖ Linked Lists can also be used to implement the Adjacency list representation of Graphs.
❖ A polynomial can be represented in an array or in a linked list by simply storing the coefficient
and exponent of each term.
❖ Linked lists are useful for dynamic memory allocation.
2. Doubly Linked List
❖ A Doubly Linked List is a linear data structure that consists of a sequence of elements called
nodes. Each node contains three fields: two link fields and one data field.
❖ The first link points to the previous node in the list and the second link points to the next node
in the list.
255
❖ The first node of the list has its previous link pointing to NULL similarly the last node of the
list has its next node pointing to NULL.
Doubly Linked List Representation
/* Given a node as prev_node, insert a new node after the given node */
public void InsertAfter(Node prev_Node, int new_data)
{
/*1. Check if the given prev_node is NULL */
if (prev_Node == null)
{
System.out.println("The given previous node cannot be NULL ");
return;
}
257
/*2. Allocate node
* 3. Put in the data */
Node new_node = new Node(new_data);
/*4. Make next of new node as next of prev_node */
new_node.next = prev_Node.next;
/*5. Make the next of prev_node as new_node */
prev_Node.next = new_node;
/*6. Make prev_node as previous of new_node */
new_node.prev = prev_Node;
/* 7. Change previous of new_node's next node */
if (new_node.next != null)
new_node.next.prev = new_node;
}
c) Add a node at the end: (7 steps process)
❖ The new node is always added after the last node of the given Linked List.
❖ Since a Linked List is typically represented by the head of it, we have to traverse the list till
end and then change the next of last node to new node.
258
d) Add a node before a given node:
Steps:
1. Check if the next_node is NULL or not. If it’s NULL, return from the function because any
new node cannot be added before a NULL
2. Allocate memory for the new node, let it be called new_node
3. Set new_node->data = new_data
4. Set the previous link of this new_node as the previous node of the next_node, new_node->prev
= next_node->prev
5. Set the previous pointer of the next_node as the new_node, next_node->prev = new_node
6. Set the next pointer of this new_node as the next_node, new_node->next = next_node;
7. If the previous node of the new_node is not NULL, then set the next pointer of this previous
node as new_node, new_node->prev->next = new_node
8. Else, if the prev of new_node is NULL, it will be the new head node. So, make (*head_ref) =
new_node.
❖ The deletion of a node in a doubly-linked list can be divided into three main categories:
i) Deleting the first node in a Doubly Linked List
❖ For deleting the first node, we need to change the head reference so that it starts referencing the
next node.
ii) Deleting the node at the given index in a Doubly Linked List
259
❖ If deleting node at index when (index == size-1) that is equivalent to deleteLast.
❖ Otherwise traverse to the node at the given index and change the references so that the node on
the left of the node to be deleted starts referencing the node on the right of the node to be deleted
and vice versa.
❖ For deleting the last node in the doubly linked list change the reference for tail so that it starts
referencing the previous node.
1. If the node to be deleted is the head node then make the next node as head.
2. If a node is deleted, connect the next and previous node of the deleted node.
Example:
p.setLinkNext(n);
n.setLinkPrev(p);
size-- ;
263
return;
}
ptr = ptr.getLinkNext();
}
}
// Function to display list elements
public void display()
{
System.out.print("\nDoubly Linked List = ");
if (size == 0)
{
System.out.print("List is empty\n");
return;
}
if (start.getLinkNext() == null)
{
System.out.println(start.getData() );
return;
}
Node ptr = start;
System.out.print(start.getData()+ " <-> ");
ptr = start.getLinkNext();
while (ptr.getLinkNext() != null)
{
System.out.print(ptr.getData()+ " <-> ");
ptr = ptr.getLinkNext();
}
System.out.print(ptr.getData()+ "\n");
}
}
public class DoublyLinkedListTest
{
public static void main(String args[]) throws IOException
{
Scanner sc = new Scanner(System.in);
DoublyLinkedList dll = new DoublyLinkedList();
System.out.println("Doubly Linked List Test\n");
char ch;
do
{
System.out.println("\nDoubly Linked List Operations");
System.out.println("1. Insert at beginning");
System.out.println("2. Insert at end");
System.out.println("3. Insert at position");
System.out.println("4. Delete at position");
System.out.println("5. Printing the list");
System.out.println("6. Exit");
264
System.out.println("Enter your choice");
int choice = sc.nextInt();
switch (choice)
{
case 1 :
System.out.println("Enter the element to insert at the beginning");
dll.insertAtStart( sc.nextInt() );
dll.display();
break;
case 2 :
System.out.println("Enter the element to insert at the end");
dll.insertAtEnd(sc.nextInt());
dll.display();
break;
case 3 :
System.out.println("Enter the element to insert at the specified position");
int num = sc.nextInt() ;
System.out.println("Enter the position");
int pos = sc.nextInt() ;
if (pos < 1 || pos > list.getSize() )
{
System.out.println("Invalid position\n");
}
else
{
dll.insertAtPos(num, pos);
}
dll.display();
break;
case 4 :
System.out.println("Enter the position to delete");
int p = sc.nextInt() ;
if (p < 1 || p > list.getSize() )
{
System.out.println("Invalid position\n");
}
else
{
dll.deleteAtPos(p);
}
dll.display();
break;
case 5 :
dll.display();
break;
case 6 :
System.exit(0);
265
break;
default :
System.out.println("Wrong Choice \n ");
break;
}
System.out.println("\nDo you want to continue? (Type Y or N) \n");
ch = sc.next().charAt(0);
}
while (ch == 'Y'|| ch == 'y');
}
}
Output:
270
Operations on Circular Linked List
1) Insertion on a Circular Linked List
❖ A node can be added in three ways:
1) Insertion at the beginning
2) Insertion at the end
3) Insertion in between the nodes
❖ Suppose we have a Circular Linked List with elements 1, 2, and 3.
New Node
271
❖ Point the next of newNode to the node next to p
❖ Store the address of newNode at next of p
272
Figure 16.16: Delete the specified node
273
class CircularSinglyLinkedList
{
protected Node start ;
protected Node end ;
public int size ;
public CircularSinglyLinkedList()
{
start = null;
end = null;
size = 0;
}
// Function to check if list is empty
public boolean IsEmpty()
{
return start == null;
}
// Function to get size of the list
public int getSize()
{
return size;
}
// Function to insert element at the begining
public void InsertAtStart(int val)
{
Node nptr = new Node(val,null);
nptr.setLink(start);
if(start == null)
{
start = nptr;
nptr.setLink(start);
end = start;
}
else
{
end.setLink(nptr);
start = nptr;
}
size++ ;
}
// Function to insert element at end
public void InsertAtEnd(int val)
{
Node nptr = new Node(val,null);
nptr.setLink(start);
if(start == null)
{
start = nptr;
nptr.setLink(start);
end = start;
}
else
{
end.setLink(nptr);
end = nptr;
274
}
size++ ;
}
// Function to insert element at position
public void InsertAtPos(int val , int pos)
{
Node nptr = new Node(val,null);
Node ptr = start;
pos = pos - 1 ;
for (int i = 1; i < size - 1; i++)
{
if (i == pos)
{
Node tmp = ptr.getLink() ;
ptr.setLink( nptr );
nptr.setLink(tmp);
break;
}
ptr = ptr.getLink();
}
size++ ;
}
// Function to delete element at position
public void DeleteAtPos(int pos)
{
if (size == 1 && pos == 1)
{
start = null;
end = null;
size = 0;
return ;
}
if (pos == 1)
{
start = start.getLink();
end.setLink(start);
size--;
return ;
}
if (pos == size)
{
Node s = start;
Node t = start;
while (s != end)
{
t = s;
s = s.getLink();
}
end = t;
end.setLink(start);
size --;
return;
}
Node ptr = start;
275
pos = pos - 1 ;
for (int i = 1; i < size - 1; i++)
{
if (i == pos)
{
Node tmp = ptr.getLink();
tmp = tmp.getLink();
ptr.setLink(tmp);
break;
}
ptr = ptr.getLink();
}
size-- ;
}
// Function to display contents
public void Display()
{
System.out.print("\nCircular Singly Linked List = ");
Node ptr = start;
if (size == 0)
{
System.out.print("List is empty\n");
return;
}
if (start.getLink() == start)
{
System.out.print(start.getData()+ "->"+ptr.getData()+ "\n");
return;
}
System.out.print(start.getData()+ "->");
ptr = start.getLink();
while (ptr.getLink() != start)
{
System.out.print(ptr.getData()+ "->");
ptr = ptr.getLink();
}
System.out.print(ptr.getData()+ "->");
ptr = ptr.getLink();
System.out.print(ptr.getData()+ "\n");
}
}
public class CircularSinglyLinkedListTest
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
CircularSinglyLinkedList CSLL = new CircularSinglyLinkedList();
System.out.println("Circular Singly Linked List Test\n");
char ch;
do
{
System.out.println("\nCircular Singly Linked List Operations");
System.out.println("1. Insert at beginning");
System.out.println("2. Insert at end");
276
System.out.println("3. Insert at position");
System.out.println("4. Delete at position");
System.out.println("5. Printing the List");
System.out.println("6. Exit");
System.out.println("Enter your choice");
int choice = sc.nextInt();
switch (choice)
{
case 1 :
System.out.println("Enter the element to insert at the beginning");
CSLL.InsertAtStart( sc.nextInt() );
CSLL.Display();
break;
case 2 :
System.out.println("Enter the element to insert at the end");
CSLL.InsertAtEnd( sc.nextInt() );
CSLL.Display();
break;
case 3 :
System.out.println("Enter the element to insert at the specified position");
int num = sc.nextInt();
System.out.println("Enter the position");
int pos = sc.nextInt() ;
if (pos <= 1 || pos > cll.getSize() )
{
System.out.println("Invalid Position\n");
}
else
{
CSLL.InsertAtPos(num, pos);
}
CSLL.Display();
break;
case 4 :
System.out.println("Enter the position to delete");
int p = sc.nextInt() ;
if (p < 1 || p > list.getSize() )
{
System.out.println("Invalid position\n");
}
else
{
CSLL.DeleteAtPos(p);
}
CSLL.Display();
break;
case 5 :
CSLL.Display();
break;
case 6 :
System.exit(0);
break;
default :
System.out.println("Wrong Choice \n ");
277
break;
}
System.out.println("\nDo you want to continue? (Type Y or N) \n");
ch = sc.next().charAt(0);
}
while (ch == 'Y'|| ch == 'y');
}
}
Output:
Circular Singly Linked List Test
Circular Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
1
Enter the element to insert at the beginning
4
Circular Singly Linked List = 4->4
Do you want to continue? (Type Y or N)
Y
Circular Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
1
Enter the element to insert at the beginning
1
Circular Singly Linked List = 1->4->1
Do you want to continue (Type Y or N)
Y
Circular Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
2
Enter the element to insert at the end
3
Circular Singly Linked List = 1->4->3->1
Do you want to continue? (Type Y or N)
278
Y
Circular Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
2
Enter the element to insert at the end
7
Circular Singly Linked List = 1->4->3->7->1
Do you want to continue? (Type Y or N)
Y
Circular Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
3
Enter the element to insert to insert at the specified position
24
Enter the position
3
Circular Singly Linked List = 1->4->24->3->7->1
Do you want to continue? (Type Y or N)
Y
Circular Singly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
5
Circular Singly Linked List = 1->4->24->3->7->1
Do you want to continue? (Type Y or N)
Y
• List initially contain some nodes, start points to first node of the List: A node(Say M) is
inserted with data = 7, so previous link of M points to last node, next link of M points to first
node and last node’s next link points to this M node and first node’s previous link points to
this M node.
54
4
• Insertion at the beginning of the list: To insert a node at the beginning of the list, create a
node(Say T) with data = 5, T’s next link points to first node of the list, T’s previous link points
to last node the list, last node’s next link points to this T node, first node’s previous link also
points this T node.
282
• Insertion in between the nodes of the list: To insert a node in between the list, two data
values are required one after which new node will be inserted and another is the data of the
new node.
eting
2) Deleting a node from a Circular Doubly Linked List
Given a ‘key’, delete the first occurrence of this key in the circular doubly linked list.
Algorithm
Case 1: Empty List(start = NULL)
• If the list is empty, simply return it.
Case 2: The List initially contains some nodes, start points at the first node of the List
1. If the list is not empty, then we define two pointers curr and prev_1 and initialize the
pointer curr points to the first node of the list and prev_1 = NULL.
2. Traverse the list using the curr pointer to find the node to be deleted and before moving
from curr to the next node, every time set prev_1 = curr.
3. If the node is found, check if it is the only node in the list. If yes, set start = NULL and free
the node pointing by curr.
4. If the list has more than one node, check if it is the first node of the list. The condition to check
this is (curr == start). If yes, then move prev_1 to the last node(prev_1 = start -> prev). After
prev_1 reaches the last node, set start = start -> next and prev_1 -> next = start and start ->
prev = prev_1. Free the node pointing by curr.
5. If curr is not the first node, we check if it is the last node in the list. The condition to check
this is (curr -> next == start). If yes, set prev_1 -> next = start and start -> prev = prev_1. Free
the node pointing by curr.
6. If the node to be deleted is neither the first node nor the last node, declare one more
pointer temp and initialize the pointer temp points to the next of curr pointer (temp = curr-
>next). Now set, prev_1 -> next = temp and temp ->prev = prev_1. Free the node pointing by
curr.
• If the given key(Say 4) matches with the first node of the list(Step 4):
283
• If the given key(Say 8) matches with the last node of the list(Step 5):
• If the given key(Say 6) matches with the middle node of the list(Step 6):
Example:
case 5 :
CDLL.Display();
break;
case 6 :
System.exit(0);
break;
default :
System.out.println("Wrong Choice \n ");
break;
}
System.out.println("\nDo you want to continue? (Type Y or N) \n");
ch = sc.next().charAt(0);
}
while (ch == 'Y'|| ch == 'y');
}
}
Ouput:
Circular Doubly Linked List Test
290
1
Enter the element to insertaat the beginning
7
Circular Doubly Linked List = 7 <-> 5 <-> 7
Do you want to continue? (Type Y or N)
Y
Circular Doubly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
2
Enter the element to insert at the end
3
Circular Doubly Linked List = 7 <-> 5 <-> 3 <-> 7
Do you want to continue? (Type Y or N)
Y
Circular Doubly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
3
Enter the element to insert at the specified position
2
Enter the position
2
Circular Doubly Linked List = 7 <-> 2 <-> 5 <-> 3 <-> 7
Do you want to continue? (Type Y or N)
Y
Circular Doubly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
3
Enter the element to insert at the specified position
4
Enter position
4
Circular Doubly Linked List = 7 <-> 2 <-> 5 <-> 4 <-> 3 <-> 7
Do you want to continue? (Type Y or N)
Y
Circular Doubly Linked List Operations
1. Insert at beginning
291
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
4
Enter the position to delete
1
Circular Doubly Linked List = 2 <-> 5 <-> 4 <-> 3 <-> 2
Do you want to continue (Type Y or N)
Y
Circular Doubly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
1
Enter the element to insert at the beginning
1
Circular Doubly Linked List = 1 <-> 2 <-> 5 <-> 4 <-> 3 <-> 1
Do you want to continue? (Type Y or N)
Y
Circular Doubly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
4
Enter the position to delete
1
Circular Doubly Linked List = 2 <-> 5 <-> 4 <-> 3 <-> 2
Do you want to continue? (Type Y or N)
Y
Circular Doubly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
4
Enter the position to delete
1
Circular Doubly Linked List = 5 <-> 4 <-> 3 <-> 5
Do you want to continue? (Type Y or N)
Y
292
Circular Doubly Linked List Operations
1. Insert at beginning
2. Insert at end
3. Insert at position
4. Delete at position
5. Printing the list
6. Exit
Enter your choice
5
Circular Doubly Linked List = 5 <-> 4 <-> 3 <-> 5
Do you want to continue? (Type Y or N)
N
Exercises:
1. What is a Linked List?
2. Differentiate Linked List vs Array.
3. Explain the various types of Linked Lists.
4. Explain briefly about the operations on Linked List.
5. Define Doubly Linked List.
6. Define Circular Linked List.
7. How do you create Singly Linked List?
8. Explain in detail about Doubly Linked List.
9. Discuss in detail about Circular Singly Linked List representation.
10. Write a Java program to implement Circular Singly Linked List.
11. Discuss in detail about Circular Doubly Linked List representation.
******************************
293
************************************************************
Chapter 17 Stacks
************************************************************
17.1 Introduction
❖ A Stack is a linear data structure that follows the LIFO (Last-In-First-Out) principle.
❖ A stack is an ordered collection of items where the addition of new items and the removal of
existing items always take place at the same end. This end is commonly referred to as the “top”.
❖ The most recently added item is always on the top of the stack and thus will be removed first.
❖ There are many examples of stacks in everyday situations. Consider a stack of plates on a table,
where it’s only possible to add or remove plates to or from the top. Or imagine a stack of books
on a desk. The only book whose cover is visible is the one on top. To access the others, we must
first remove the ones sitting on top of them.
3) PEEK Operation
294
❖ Peek operation retrieves the element present at the top of the stack.
❖ The element retrieved does not get deleted or removed from the Stack.
17.4 Implementation of Stack Data Structure
❖ Stack can be easily implemented using an Array or a Linked List.
❖ Arrays are quick, but are limited in size and Linked List requires overhead to allocate, link,
unlink, and deallocate, but is not limited in size.
1) Array Implementation of Stack
❖ Stack can be implemented using one-dimensional array.
❖ One-dimensional array is used to hold elements of a stack.
❖ Implementing a stack using array can store fixed number of data values.
❖ In a stack, initially top is set to -1. Top is used to keep track of the index of the topmost element.
i) Algorithm for PUSH operation
1. Check if the stack is full or not.
2. If the stack is full, then print overflow error and exit the program.
3. If the stack is not full, then increment the top and add the element.
Example:
case 4:
s.display();
break;
case 5:
297
System.exit(0);
break;
default:
System.out.println("Wrong Choice");
break;
}
}
while(ch<=5);
}
}
Output:
1. PUSH
2. POP
3. PEEK
4. DISPLAY
5. QUIT
Enter your choice:
1
Enter the element to insert
8
8 is inserted into the stack
1. PUSH
2. POP
3. PEEK
4. DISPLAY
5. QUIT
Enter your choice
1
Enter the element to insert
30
30 is inserted into the stack
1. PUSH
2. POP
3. PEEK
4. DISPLAY
5. QUIT
Enter your choice
4
Stack: 8 30
1. PUSH
2. POP
3. PEEK
4. DISPLAY
5. QUIT
Enter your choice
3
298
The top most position of the stack holds 30
1. PUSH
2. POP
3. PEEK
4. DISPLAY
5. QUIT
Enter your choice
2
30 has been removed from stack
1. PUSH
2. POP
3. PEEK
4. DISPLAY
5. QUIT
Enter your choice
4
Stack: 8
1. PUSH
2. POP
3. PEEK
4. DISPLAY
5. QUIT
Enter your choice
5
2) Linked List Implementation of Stack
❖ A stack can be easily implemented through the linked list.
❖ In linked list implementation of stack, the nodes are maintained non-contiguously in the
memory.
❖ Each node contains a link to its immediate successor node in the stack.
❖ The topmost node in the stack always contains null in its address field.
❖ The main advantage of using linked list over an array is that it is possible to implement a stack
that can shrink or grow as much as needed. While using an array, we will put a restriction to
the maximum capacity of the array which can lead to stack overflow. Here each new node
will be dynamically allocated. So overflow is not possible.
299
❖ Adding a node to the stack is referred to as push operation.
❖ In order to push an element onto the stack, the following steps are involved.
• Create a newNode with the given data.
• Check whether the stack is empty (TOP == NULL).
• If it is empty, then set the pointer of the node to NULL.
• If it is not empty, then make the node point to TOP.
• Finally, make the newNode as TOP.
2. Deleting a node from the stack (POP Operation)
❖ Deleting a node from the top of stack is referred to as pop operation.
❖ In order to pop an element from the stack, we need to follow the following steps :
• Check whether stack is empty (top == NULL).
• If it is empty, then display "EMPTY STACK"
• If it is not empty, then create a temporary node and set it to TOP.
• Print the data of TOP.
• Make TOP to point to the next node.
• Delete the temporary node.
3. Display the nodes (Traversing)
❖ Displaying all the nodes of a stack needs traversing all the nodes of the linked list organized in
the form of stack.
❖ For this purpose, we need to follow the following steps.
1. Copy the head pointer into a temporary pointer.
2. Move the temporary pointer through all the nodes of the list and print the value field
Example:
Output:
Select 1. Push 2. Pop 3. Display 4. Exit
1
Enter the number of elements to push
3
Enter the elements:
10
20
30
Select 1. Push 2. Pop 3. Display 4. Exit
3
The current stack items:
30 20 10
Select 1. Push 2. Pop 3. Display 4. Exit
2
Enter the number of elements to pop:
1
30 is popped from stack...
Select 1. Push 2. Pop 3. Display 4. Exit
302
3
The current stack items:
20 10
Select 1. Push 2. Pop 3. Display 4. Exit
4
17.5 Applications of Stack
1) Expression Evaluation
❖ Stack is used to evaluate prefix, postfix and infix expressions.
2) Expression Conversion
❖ An expression can be represented in prefix, postfix or infix notation. Stack can be used to
convert one form of expression to another. This is one of the most important applications of
stack.
3) Syntax Parsing
❖ Many compilers use a stack for parsing the syntax of expressions, program blocks etc. before
translating into low level code.
4) Backtracking
❖ Suppose we are finding a path for solving maze problem. We choose a path and after following
it we realize that it is wrong. Now we need to go back to the beginning of the path to start with
new path. This can be done with the help of stack.
5) Parenthesis Checking
❖ Stack is used to check the proper opening and closing of parenthesis.
6) String Reversal
❖ Stack is used to reverse a string. We push the characters of string one by one into stack and then
pop character from stack.
7) Recursion
❖ The recursion means that the function is calling itself again. To maintain the previous states,
the compiler creates a system stack in which all the previous records of the function are
maintained.
8) DFS (Depth First Search)
❖ This search is implemented on a Graph, and Graph uses the stack data structure.
9) Function Call
❖ Stack is used to keep information about the active functions or subroutines.
10) Memory Management
❖ The stack manages the memory. The memory is assigned in the contiguous memory blocks.
The memory is known as stack memory as all the variables are assigned in a function call stack
memory. The memory size assigned to the program is known to the compiler. When the function
303
is created, all its variables are assigned in the stack memory. When the function completed its
execution, all the variables assigned in the stack are released.
17.6 Evaluating Arithmetic Expressions
❖ Stack data structure is used for evaluating the given expression.
❖ There are three ways of writing an expression: Infix, Prefix, and Postfix.
❖ Computers evaluate expressions in Prefix or Postfix, whereas humans are more familiar with
Infix way of denoting an expression.
❖ Conversion from one form of the expression to another form needs a stack.
Infix, Prefix and Postfix Notation
❖ An arithmetic expression can be written in three different but equivalent notations, i.e., without
changing the output of an expression. These notations are:
• Infix Notation
• Prefix (Polish) Notation
• Postfix (Reverse-Polish) Notation
Infix:
❖ An expression is called the infix expression if the operator appears in between the
operands.
❖ It has the following format:
(Operand1 Operator Operand2)
Example: (A+B) * (C-D))
Prefix:
❖ An expression is called the prefix expression if the operator appears in the expression
before the operands.
❖ It has the following format:
(Operator Operand1 Operand2)
❖ Prefix Notation is also known as Polish Notation.
Example: *+AB-CD (Infix: (A+B) * (C-D) )
Postfix:
❖ An expression is called the postfix expression if the operator appears in the expression
after the operands.
❖ It has the following format:
(Operand1 Operand2 Operator)
❖ Postfix notation is also known as Reversed Polish Notation.
Example: AB+CD-* (Infix: (A+B * (C-D))
Example:
305
// Current token is a number, push it to stack for numbers
if (tokens[i] >= '0' && tokens[i] <= '9')
{
StringBuffer sbuf = new StringBuffer();
// There may be more than one digits in number
while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9')
sbuf.append(tokens[i++]);
values.push(Integer.parseInt(sbuf.toString()));
i--;
}
// Current token is an opening brace, push it to 'ops'
else if (tokens[i] == '(')
ops.push(tokens[i]);
// Closing brace encountered, solve entire brace
else if (tokens[i] == ')')
{
while (ops.peek() != '(')
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
ops.pop();
}
// Current token is an operator.
else if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*' || tokens[i] == '/')
{
// While top of 'ops' has same or greater precedence to current token, which
// is an operator. Apply operator on top of 'ops' to top two elements in values
// stack
while (!ops.empty() && hasPrecedence(tokens[i], ops.peek()))
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Push current token to 'ops'.
ops.push(tokens[i]);
}
}
// Entire expression has been parsed at this point, apply remaining ops to
// remaining values
while (!ops.empty())
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Top of 'values' contains result, return it
return values.pop();
}
// Returns true if 'op2' has higher or same precedence as 'op1', otherwise returns false.
public static boolean hasPrecedence(char op1, char op2)
{
if (op2 == '(' || op2 == ')')
return false;
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
return false;
else
return true;
}
// A method to apply an operator 'op' on operands 'a' and 'b'. Return the result.
public static int applyOp(char op, int b, int a)
306
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw new UnsupportedOperationException("Cannot divide by zero");
return a / b;
}
return 0;
}
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String Str;
System.out.println("Enter the infix expression");
Str= br.readLine();
System.out.println(EvaluateString.evaluate(Str));
}
}
Output:
Enter the infix expression
10 + 2 * 6
22
2) Evaluation of Prefix Expression
❖ Prefix notation is a notation for writing arithmetic expressions in which the operands appear
after their operators.
❖ Prefix expression can be evaluated faster than an infix expression.
❖ This is because we don’t need to process any brackets or follow operator precedence rule.
❖ In the prefix expression, which ever operator comes before will be evaluated first, irrespective
of its priority.
❖ Also, there are no brackets in this expression.
Algorithm:
Step 1: Reverse the given expression and Iterate through it, one character at a time
Step 2: If a character is an operand push it to Stack
Step 3: If the character is an operator pop two elements from the Stack.Operate on these
elements according to the operator, and push the result back to the Stack
Step 4: Step 2 and 3 will be repeated until the end has reached.
307
Step 5: The Result is stored at the top of the Stack, return it
Example:
//Java program to evaluate the Prefix Expression using Stack
import java.io.*;
import java.util.*;
public class PrefixEvaluation
{
public static Double evaluate(double a, double b, char operator)
{
switch (operator)
{
case '+':
return a + b;
case '-':
return b - a;
case '*':
return a * b;
case '/':
if (a == 0)
throw new UnsupportedOperationException("Cannot divide by zero");
return b / a;
}
return 0.0;
}
public static Double convert(String expression)
{
StringBuilder input = new StringBuilder(expression);
input.reverse();
Stack<Double> stack = new Stack<>();
for (int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
//Check if it is a space (separator)
if(c==' ')
continue;
if (c == '*' || c == '/' || c == '^' || c == '+' || c == '-')
{
double s1 = stack.pop();
double s2 = stack.pop();
double temp = evaluate(s2, s1, c);
stack.push(temp);
}
else
{
//If it is a digit extract the characters and store it in num
308
StringBuffer temp = new StringBuffer();
while(Character.isDigit(c))
{
temp.append(c);
i++;
c = input.charAt(i);
}
i--;
//Push the number in stack
double num = Double.parseDouble(temp.reverse().toString());
stack.push(num);
}
}
double result = stack.pop();
return result;
}
public static void main(String args[]) throws IOException
{
String exp;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the Prefix Expression");
exp=br.readLine();
System.out.println("Prefix Expression: " + exp);
System.out.println("Evaluation: " + convert(exp));
}
}
Output:
Enter the Prefix Expression
- / * 20 * 50 + 3 6 300 2
Prefix Expression: - / * 20 * 50 + 3 6 300 2
Evaluation: 28.0
3) Evaluation of Postfix Expression
❖ The Postfix notation is used to represent algebraic expressions.
❖ The expressions written in postfix form are evaluated faster compared to infix notation as
parenthesis are not required in postfix.
Algorithm:
1) Create a stack to store operands (or values).
2) Scan the given expression and do following for every scanned element.
a) If the element is a number, push it into the stack
b) If the element is an operator, pop operands for the operator from stack. Evaluate
the operator and push the result back to the stack
3) When the expression is ended, the number in the stack is the final answer
Example:
309
// Java program to evaluate value the postfix expression
import java.io.*;
import java.util.Stack;
public class Test
{
// Method to evaluate value of a postfix expression
static int evaluatePostfix(String exp)
{
//Create an empty stack
Stack<Integer> stack=new Stack<>();
// Scan all characters one by one
for(int i=0;i<exp.length();i++)
{
char c=exp.charAt(i);
// If the scanned character is an operand, push it to the stack.
if (Character.isDigit(c))
stack.push(c - '0');
else
{
// If the scanned character is an operator, pop two elements from the stack
int x = stack.pop();
int y = stack.pop();
switch(c)
{
case '+':
stack.push(y + x);
break;
case '-':
stack.push(y - x);
break;
case '*':
stack.push(y * x);
break;
case '/':
stack.push(y / x);
break;
}
}
}
return stack.pop();
}
public static void main(String args[]) throws IOException
{
String exp;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the Postfix Expression");
exp=br.readLine();
System.out.println("Postfix Evaluation: "+evaluatePostfix(exp));
}
}
Output:
Enter the Postfix Expression
310
138×+
Postfix Evaluation: 25
17.7 Conversion of infix to postfix expression
❖ Infix expressions are the expression where operators are written in between every pair of
operands. It is the usual way to write an expression. For Ex: An expression like A + B is Infix.
❖ Postfix expressions are the expressions where operands precede operators. Here operators are
written after operands. The Expression AB+ is Postfix and is the Postfix representation of the
above shown A+B. The evaluation order is from left to right.
Algorithm:
1. Scan the infix expression from left to right.
2. If the scanned character is an operand, output it.
3. Else,
i) If the precedence of the scanned operator is greater than the precedence of the operator in
the stack (or the stack is empty or the stack contains a ‘(‘ ), push it.
❖ Else,
❖ ii) Pop all the operators from the stack which are greater than or equal to in precedence
than that of the scanned operator. After doing that Push the scanned operator to the stack.
(If we encounter parenthesis while popping then stop there and push the scanned operator
in the stack.)
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop the stack and output it until a ‘(‘is encountered, and discard
both the parenthesis.
6. Repeat steps 2-6 until infix expression is scanned.
7. Print the output
8. Pop and output from the stack until it is not empty.
Example:
char peek()
{
return a[top];
}
312
}
public class InfixToPostfix
{
static Stack operators = new Stack();
public static void main(String argv[]) throws IOException
{
String infix;
BufferedReader br = new BufferedReader (new InputStreamReader(System.in));
System.out.print("\nEnter the infix expression you want to convert: ");
infix = br.readLine();
/ System.out.println("Postfix expression for the given infix expression is:" + toPostfix(infix));
}
private static String toPostfix(String infix)
//Converts an infix expression to postfix
{
char symbol;
String postfix = "";
for(int i=0;i<infix.length();++i)
{
symbol = infix.charAt(i);
//If it's an operand, add it to the string
if (Character.isLetter(symbol))
postfix = postfix + symbol;
else if (symbol=='(')
/ {
operators.push(symbol);
}
else if (symbol==')')
{
while (operators.peek() != '(')
{
postfix = postfix + operators.pop();
}
operators.pop();
}
else
{
while (!operators.isEmpty() && !(operators.peek()=='(') && prec(symbol) <=
prec(operators.peek()))
postfix = postfix + operators.pop();
operators.push(symbol);
}
}
while (!operators.isEmpty())
postfix = postfix + operators.pop();
return postfix;
}
static int prec(char x)
{
if (x == '+' || x == '-')
return 1;
313
if (x == '*' || x == '/' || x == '%')
return 2;
return 0;
}
}
Output:
Enter the Infix Expression
A*(B-C)/D+E
The Infix Expression is: A*(B-C)/D+E
The Postfix of the given Infix Expression is: ABC-*D/E+
Exercises:
1. Define stack.
2. Explain the various operations that can be performed on stack.
3. Write a Java program to implement the stack operations using arrays.
4. Write a Java program to implement the stack operations using linked lists.
5. Explain briefly about the applications of stack.
6. Dsiscus in detail about infix, prefix and postfix expression with an example.
7. Write a Java program to convert the given infix expression to postfix form.
*************************
************************************************************
Chapter 18 Queues
************************************************************
18.1 Introduction
314
❖ Queue is a Linear Data Structure.
❖ It is used for temporary storage of data values.
❖ Queue is a First-In-First- Out (FIFO) data structure where the first item inserted is the
first to be removed.
❖ A new element is added at one end called rear end.
❖ The existing elements are deleted from the other end called front end.
18.2 Queue ADT
“A queue is an ordered list in which all insertions take place at the REAR end deletions take place
at another end called FRONT”. Queues are sometimes referred to as First-In-First-Out (FIFO) lists.
3. If the queue is not full, then increment the tail and add the element.
Example 1:
// Java program to implement a queue using an array
import java.io.*;
import java.util.*;
class Queue
{
int front, rear, size=100;
int queue=new int[size];
Queue()
{
front = rear = 0;
}
// Function to insert an element at the rear of the queue
316
void Enqueue(int data)
{
// Check queue is full or not
if (size == rear)
{
System.out.println("\nQueue is full\n");
return;
}
// Insert element at the rear
else
{
queue[rear] = data;
rear++;
}
return;
}
// Function to delete an element from the front of the queue
void Dequeue()
{
// If queue is empty
if (front == rear)
{
System.out.println("\nQueue is empty\n");
return;
}
// Shift all the elements from index 2 till rear to the right by one
else
{
for (int i = 0; i < rear - 1; i++)
{
queue[i] = queue[i + 1];
}
// Store 0 at rear indicating there's no element
if (rear < size)
queue[rear] = 0;
// Decrement rear
rear--;
}
return;
}
// Print front of queue
void peek()
{
if (front == rear)
{
System.out.println("\nQueue is Empty\n");
return;
317
}
System.out.println("\nFront Element is: %d", queue[front]);
return;
}
}
// Print queue elements
void Display()
{
int i;
if (front == rear)
{
System.out.println("\nQueue is Empty\n");
return;
}
// Traverse front to rear and print elements
System.out.println(“The Queue elements are”)
for (i = front; i < rear; i++)
{
System.out.println(queue[i]+” “);
}
return;
}
public class Queue_Arr
{
public static void main(String args[) throws IOException
{
Scanner sc = new Scanner(System.in);
Queue q = new Queue();
System.out.println("Queue Implementation Using Array\n");
char ch;
do
{
System.out.println("Queue Operations");
System.out.println("1. Insert");
System.out.println("2. Delete");
System.out.println("3. Peek");
System.out.println("4. Display");
System.out.println("5. Exit");
System.out.println(“Enter your choice:”);
int choice = sc.nextInt();
switch (choice)
{
case 1 :
System.out.println("Enter the element to insert");
int x=sc.nextInt();
q.Enqueue( x);
q.display();
318
break;
case 2 :
System.out.println("Removed Element = "+q.Dequeue());
q.display();
break;
case 3 :
System.out.println("Peek Element = "+ q.peek());
q.display();
break;
case 4 :
q.display();
break;
case 5 :
exit(0);
break;
default :
System.out.println("Wrong Choice. Try again. \n ");
break;
}
System.out.println("\nDo you want to continue? (Type Y or N) \n");
ch = sc.next().charAt(0);
}
while (ch == 'Y'|| ch == 'y');
}
}
Output:
Queue Implementation Using Array
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
1
Enter the element to insert
10
The Queue elements are
10
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
319
4. Display
5. Exit
Enter your choice
1
Enter the element to insert
20
The Queue elements are
10 20
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
1
Enter the element to insert
30
The Queue elements are
10 20 30
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
2
Removed Element = 10
The Queue elements are
10 20
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
3
Peek Element = 10
The Queue elements are
10 20
Do you want to continue? (Type Y or N)
320
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
4
The Queue elements are
10 20
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
5
Do you want to continue? (Type Y or N)
N
2) Linked List implementation of Queue
❖ Queue is abstract data type which demonstrates First In First Out (FIFO) behavior.
❖ In a linked queue, each node of the queue consists of two parts i.e. data part and the link part.
Each element of the queue points to its immediate next element in the memory.
❖ Insertion and deletions are performed at rear and front end respectively. If front and rear both
are NULL, it indicates that the queue is empty.
❖ The linked representation of queue is shown in the following figure.
321
❖ Firstly, we need to check either the list is empty or not.
❖ The condition front == NULL becomes true if the list is empty, in this case, we simply write
underflow on the console and make exit.
❖ Otherwise, we will delete the element that is available in the front. For this purpose, copy the
node pointed by the front into node ptr. Now, shift the front element, point to its next node and
free the node pointed by the node ptr.
Example:
//Java program to implement the Queue Operations using Singly Linked Lists
//QueueList.java
import java.io.*;
class Node
{
public int data;
public Node next;
public Node(int x)
{
data=x;
}
public void displayNode()
{
System.out.print(data+" ");
}
}
class LinkedQueue
{
private Node first;
private Node last;
public LinkedQueue()
{
first=null;
322
last=null;
}
public void insertLast(int x)
{
Node newNode=new Node(x);
newNode.next=null;
if (isEmpty())
first=newNode;
else
last.next=newNode;
last=newNode;
}
public int deleteFirst()
{
int t=first.data;
if (first.next==null)
last=null;
first=first.next;
return t;
}
public int peekFirst()
{
return(first.data);
}
public boolean isEmpty()
{
return(first==null);
}
public void displayList()
{
Node current=first;
while(current!=null)
{
current.displayNode();
current=current.next;
}
}
}
class Queue
{
private LinkedQueue lq;
public Queue()
{
lq=new LinkedQueue();
}
323
public void insert(int x)
{
lq.insertLast(x);
System.out.println("Inserted");
}
public int delete()
{
return lq.deleteFirst();
}
public boolean isQueueEmpty()
{
return lq.isEmpty();
}
public void display()
{
lq.displayList();
}
public int peek()
{
return lq.peekFirst();
}
}
class QueueList
{
public static void main(String args[]) throws IOException
{
Queue q=new Queue();
int ch, d;
while(true)
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("MENU");
System.out.println("---------");
System.out.println("1. Insert");
System.out.println("2. Delete");
System.out.println("3. Peek");
System.out.println("4. Display");
System.out.println("5. Exit");
System.out.println("Enter Your Choice\n");
ch=Integer.parseInt(br.readLine());
if(ch==5)
break;
else
{
switch(ch)
{
case 1:
324
System.out.println("Enter the number of elements");
int n=Integer.parseInt(br.readLine());
System.out.println("Enter the elements:\n");
for(int i=0; i<n; i++)
{
d=Integer.parseInt(br.readLine());
q.insert(d);
}
break;
case 2:
if(q.isQueueEmpty())
System.out.println("Queue is Empty ");
else
{
d=q.delete();
System.out.println("Deleted Data:- "+d);
}
break;
case 3:
if(q.isQueueEmpty())
System.out.print("Queue is Empty ");
else
{
d=q.peek();
System.out.println("First Item: "+d);
}
break;
case 4:
if(q.isQueueEmpty())
System.out.println("Queue is Empty ");
else
{
System.out.println("Queue elements are ");
q.display();
}
break;
default:
System.out.println("Invalid Choice ");
}
}
System.out.println(" ");
}
}
}
Output:
MENU
325
----------
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter Your Choice:
1
Enter the number of elements
5
Enter the elements:
3
Inserted
6
Inserted
7
Inserted
12
Inserted
16
Inserted
MENU
----------
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter Your Choice:
4
Queue elements are
3 6 7 12 16
MENU
----------
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter Your Choice:
2
Deleted Data: 3
MENU
----------
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter Your Choice:
4
Queue elements are
6 7 12 16
MENU
326
----------
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter Your Choice:
3
First Item: 6
MENU
----------
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter Your Choice:
4
Queue elements are
6 7 12 16
MENU
----------
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter Your Choice:
5
18.5 Types of Queues
• There are three types of Queues:
1. Circular Queue
2. Priority Queue
3. Dequeue (Double Ended Queue)
1. Circular Queues
❖ A circular queue is similar to a linear queue as it is also based on the FIFO (First-In-First- Out)
principle except that the last node is connected to the first node.
❖ Circular queue is also called as Ring Buffer.
❖ It is an abstract data type.
❖ Circular queue contains a collection of data which allows insertion of data at the end of the
queue and deletion of data at the beginning of the queue.
❖ Traffic light functioning is the best example for circular queues. The colors in the traffic light
follow a circular pattern.
327
Figure 18.5: Circular Queue
2. Priority Queues
❖ A priority queue is an abstract data type which is like a regular queue or stack data structure, but
where additionally each element has a “priority” associated with it.
❖ It is a collection of elements where elements are stored according to their priority levels.
❖ In a priority queue, insertion is performed in the order of arrival and deletion is performed based
on the priority.
❖ While removing an element from a priority queue, the data item with the highest priority is
removed first.
❖ Two elements of same priority are processed first-come-first-served basis.
3. Dequeue
❖ Dequeue stands for double ended queue.
❖ Elements can be inserted or deleted at either end.
❖ It is also known as head-tail linked list.
• Queues are used in asynchronous transfer of data (where data is not being transferred at the same
rate between two processes) for e.g. Pipes, File IO, Sockets.
• CPU Scheduling and Disk Scheduling.
• Round Robin scheduling technique is implemented using queue
• All types of customer service (like railway reservation) centers are designed using the concept
of queues.
• Queues are used in operating systems for handling interrupts.
Exercises:
1. Define queue.
328
2. List out the operations on queue.
3. Write a Java program to implement the queue operations using an array.
4. How linked list is implemented on queue?
5. Write a Java program to implement the queue using linked list.
6. Explain in detail about the various types of queues.
7. Explain briefly about the applications of queues.
**************************
UNIT – V
************************************************************
Chapter 19 Trees
************************************************************
19.1 Introduction to Trees
❖ A tree is a nonlinear data structure that consists of nodes connected by edges.
329
❖ Each node contains some data and a link or reference to other nodes that can be called children.
❖ A tree can be empty with no nodes or a tree is a structure consisting of one node called the root
and zero or one or more subtrees.
❖ A tree is a connected graph without any circuit.
Example:
• There is one and only one path between every pair of vertices in a tree.
• A tree with n vertices has exactly (n-1) edges.
• A graph is a tree if and only if it is minimally connected.
• Any connected graph with n vertices and (n-1) edges is a tree.
Applications of Trees
1. Manipulate hierarchical data.
2. Make information easy to search (see tree traversal).
3. Manipulate sorted lists of data.
4. As a workflow for compositing digital images for visual effects.
5. Router algorithms.
6. Form of a multi-stage decision-making.
Tree Terminology
❖ The important terms related to tree data structure are-
1. Root Node
❖ The first node from where the tree originates is called as a root node.
❖ In any tree, there must be only one root node..
Example:
330
2. Edge
❖ The connecting link between any two nodes is called as an edge.
❖ In a tree with n number of nodes, there are exactly (n-1) number of edges.
Example:
3. Parent Node
❖ The node which has one or more children is called as a parent node.
❖ In a tree, a parent node can have any number of child nodes.
Example:
Here,
• Node A is the parent of nodes B and C
• Node B is the parent of nodes D, E and F
• Node C is the parent of nodes G and H
• Node E is the parent of nodes I and J
• Node G is the parent of node K
4. Child Node
❖ The node which is the immediate successor of a node is called the child node of that node.
❖ All the nodes except root node are child nodes.
Example:
Here,
331
• Nodes B and C are the children of node A
• Nodes D, E and F are the children of node B
• Nodes G and H are the children of node C
• Nodes I and J are the children of node E
• Node K is the child of node G
5. Siblings
❖ Children of the same parent node are called siblings.
❖ In other words, nodes with the same parent are sibling nodes.
Example:
Here,
• Nodes B and C are siblings
• Nodes D, E and F are siblings
• Nodes G and H are siblings
• Nodes I and J are siblings
6. Degree of a Node
❖ The Degree of a node is the total number of children of that node.
❖ The degree of a tree is the degree of its root.
❖ The degree of a leaf node must be 0.
Example:
Here,
• Degree of node A = 2
• Degree of node B = 3
• Degree of node C = 2
• Degree of node D = 0
• Degree of node E = 2
• Degree of node F = 0
• Degree of node G = 1
332
• Degree of node H = 0
• Degree of node I = 0
• Degree of node J = 0
• Degree of node K = 0
7. Internal Node
❖ The node which has at least one child is called as an internal node.
❖ Internal nodes are also called as non-terminal nodes.
❖ Every non-leaf node is an internal node.
Example:
Example:
333
10. Height
❖ Total number of edges that lies on the longest path from any leaf node to a particular node is
called as height of that node.
❖ The Height of a tree is the height of the root node.
❖ Height of all leaf nodes = 0
Example:
Here,
• Height of node A = 3
• Height of node B = 2
• Height of node C = 2
• Height of node D = 0
• Height of node E = 1
• Height of node F = 0
• Height of node G = 1
• Height of node H = 0
• Height of node I = 0
• Height of node J = 0
• Height of node K = 0
11. Depth
❖ Total number of edges from root node to a particular node is called as depth of that node.
❖ Depth of a tree is the total number of edges from root node to a leaf node in the longest path.
❖ Depth of the root node = 0
❖ The terms “level” and “depth” are used interchangeably.
Example:
Here,
• Depth of node A = 0
334
• Depth of node B = 1
• Depth of node C = 1
• Depth of node D = 2
• Depth of node E = 2
• Depth of node F = 2
• Depth of node G = 2
• Depth of node H = 2
• Depth of node I = 3
• Depth of node J = 3
• Depth of node K = 3
12. Subtree
❖ In a tree, each child from a node forms a subtree recursively.
❖ Every child node forms a subtree on its parent node.
Example:
13. Forest
❖ A forest is a set of disjoint trees.
Example:
335
❖ It is a method of placing and locating the records in a database, especially when all the data is
known to be in random access memory (RAM).
Example:
Example:
336
Figure 19.4: Complete Binary Tree
3. Skewed Binary Tree
❖ A skewed binary tree is a binary tree of n nodes such that its depth is (n-1).
❖ In a skewed binary tree, all nodes except one have only one child node. The remaining node has
no child.
❖ In a left skewed tree, most of the nodes have the left child without corresponding right child.
❖ In a right skewed tree, most of the nodes have the right child without corresponding left child.
Example:
Property-01:
337
Minimum number of nodes in a binary tree of height H= H + 1
Example:
❖ To construct a binary tree of height = 4, we need at least 4 + 1 = 5 nodes.
Property-02:
Example:
Maximum number of nodes in a binary tree of height 3= 23+1 – 1
= 16 – 1
= 15 nodes
Thus, in a binary tree of height = 3, maximum number of nodes that can be inserted = 15.
Total Number of leaf nodes in a Binary Tree= Total Number of nodes with 2 children + 1
Example:
Consider the following binary tree-
Here,
• Number of leaf nodes = 3
• Number of nodes with 2 children = 2
Clearly, number of leaf nodes is one greater than number of nodes with 2 children.
338
This verifies the above relation.
Property-04:
Example:
=4
Thus, in a binary tree, maximum number of nodes that can be present at level-2 = 4.
339
Figure 19.8: Location Number of an Array in a Tree
❖ Location number of an array is used to store the size of the tree. The first index of an array that
is '0', stores the total number of nodes.
❖ All nodes are numbered from left to right level by level from top to bottom. In a tree, each node
having an index i is put into the array as its ithelement.
❖ The above figure shows how a binary tree is represented as an array. Value '7' is the total number
of nodes. If any node does not have any children, null value is stored at the corresponding index
of the array.
341
Application
• In-order traversal is used to get infix expression of an expression tree.
2. Pre-order Traversal
❖ Pre-order traversal visits first the root node, then the left sub-tree, and finally the right sub-tree.
Algorithm
1. Visit the root.
2. Traverse the left sub-tree.
3. Traverse the right sub-tree.
(Root → Left → Right)
Example:
Consider the following example.
Applications
❖ Pre-order traversal is used to get prefix expression of an expression tree.
❖ Pre-order traversal is used to create a copy of the tree.
3. Post-order Traversal
❖ Post-order traversal visits the left sub-tree, the right sub-tree, and the root node at the end.
Algorithm
1. Traverse the left sub-tree.
2. Traverse the right sub-tree.
3. Visit the root
(Left → Right → Root)
Example:
342
Applications
❖ Post-order traversal is used to get postfix expression of an expression tree.
❖ Post-order traversal is used to delete the tree.
❖ This is because it deletes the children first and then it deletes the parent.
Application
❖ Level order traversal is used to print the data in the same order as stored in the array
representation of a complete binary tree.
Binary Tree Implementation
343
}
public BTNode(int n) //Constructor
{
left = null;
right = null;
data = n;
}
// Function to set left node
public void setLeft(BTNode n)
{
left = n;
}
// Function to set right node
public void setRight(BTNode n)
{
right = n;
}
// Function to get left node
public BTNode getLeft()
{
return left;
}
// Function to get right node
public BTNode getRight()
{
return right;
}
// Function to set data to node
public void setData(int d)
{
data = d;
}
// Function to get data from node
public intgetData()
{
return data;
}
}
class BT
{
private BTNode root;
public BT() //Constructor
{
root = null;
}
// Function to check if tree is empty
public boolean isEmpty()
344
{
return root == null;
}
// Functions to insert data
public void insert(int data)
{
root = insert(root, data);
}
// Function to insert data recursively
private BTNode insert(BTNode node, int data)
{
if (node == null)
node = new BTNode(data);
else
{
if (node.getRight() == null)
node.right = insert(node.right, data);
else
node.left = insert(node.left, data);
}
return node;
}
// Function to count number of nodes
public int countNodes()
{
return countNodes(root);
}
// Function to count number of nodes recursively
private int countNodes(BTNode r)
{
if (r == null)
return 0;
else
{
int l = 1;
l+=countNodes(r.getLeft());
l+=countNodes(r.getRight());
return l;
}
}
// Function to search for an element
public boolean search(intval)
{
return search(root, val);
}
// Function to search for an element recursively
private boolean search(BTNode r, intval)
345
{
if (r.getData() == val)
return true;
if (r.getLeft() != null)
if (search(r.getLeft(), val))
return true;
if (r.getRight() != null)
if (search(r.getRight(), val))
return true;
return false;
}
// Function for inorder traversal
public void inorder()
{
inorder(root);
}
private void inorder(BTNode r)
{
if (r != null)
{
inorder(r.getLeft());
System.out.print(r.getData() +" ");
inorder(r.getRight());
}
}
// Function for preorder traversal
public void preorder()
{
preorder(root);
}
private void preorder(BTNode r)
{
if (r != null)
{
System.out.print(r.getData() +" ");
preorder(r.getLeft());
preorder(r.getRight());
}
}
// Function for postorder traversal
public void postorder()
{
postorder(root);
}
private void postorder(BTNode r)
{
if (r != null)
346
{
postorder(r.getLeft());
postorder(r.getRight());
System.out.print(r.getData() +" ");
}
}
}
public class BinaryTreeTest
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
BT bt = new BT();
System.out.println("Binary Tree Test\n");
char ch;
do
{
System.out.println("Binary Tree Operations");
System.out.println("1. Insert ");
System.out.println("2. Search");
System.out.println("3. Count Nodes");
System.out.println("4. Exit");
System.out.println("Enter your choice");
int choice = sc.nextInt();
switch (choice)
{
case 1 :
System.out.println("Enter the element to insert");
bt.insert(sc.nextInt());
break;
case 2 :
System.out.println("Enter the element to search");
System.out.println("Search Result: "+ bt.search(sc.nextInt() ));
break;
case 3 :
System.out.println("Nodes = "+ bt.countNodes());
break;
case 4 :
System.exit(0);
break;
default :
System.out.println("Wrong Choice \n ");
break;
}
//Display Tree
System.out.print("\nPostOrder : ");
bt.postorder();
347
System.out.print("\nPreOrder : ");
bt.preorder();
System.out.print("\nInOrder : ");
bt.inorder();
System.out.println("\n\nDo you want to continue? (Type Y or N) \n");
ch = sc.next().charAt(0);
}
while (ch == 'Y'|| ch == 'y');
}
}
Output:
Binary Tree Test
PostOrder : 6
PreOrder : 6
InOrder : 6
Do you want to continue? (Type Y or N)
Y
Binary Tree Operations
1. Insert
2. Search
3. Count Nodes
4. Exit
Enter your choice
1
Enter the element to insert
24
PostOrder : 24 6
PreOrder : 6 24
InOrder : 6 24
Do you want to continue? (Type Y or N)
Y
Binary Tree Operations
1. Insert
2. Search
3. Count Nodes
348
4. Exit
Enter your choice
1
Enter the element to insert
19
PostOrder : 19 24 6
PreOrder : 6 19 24
InOrder : 19 6 24
Do you want to continue? (Type Y or N)
Y
Binary Tree Operations
1. Insert
2. Search
3. Count Nodes
4. Exit
Enter your choice
1
Enter the element to insert
94
PostOrder : 94 19 24 6
PreOrder : 6 19 94 24
InOrde r : 19 94 6 24
351
❖ Binary Search Tree is a binary tree where each node contains only smaller values in its
left subtree and only larger values in its right subtree.
❖ The above tree represents binary search tree (BST) where left subtree of every node contains
smaller values and right subtree of every node contains larger value.
❖ Binary Search Tree (BST) is used to enhance the performance of binary tree.
❖ It focuses on the search operation in binary tree.
Note: Every binary search tree is a binary tree, but all the binary trees need not to be binary
search trees.
19.5 Advantages of using Binary Search Tree
❖ Searching become very efficient in a binary search tree since, we get a hint at each step, about
which sub-tree contains the desired element.
❖ The binary search tree is considered as efficient data structure in compare to arrays and linked
lists. In searching process, it removes half sub-tree at every step. Searching for an element in a
binary search tree takes O(log2n) time. In worst case, the time it takes to search an element is
0(n).
❖ It also speed up the insertion and deletion operations as compare to that in array and linked list.
❖ Binary search trees are used in various searching and sorting algorithms. There are many
variants of binary search trees like AVL tree, B-Tree, Red-black tree, etc.
19.6 Operations on Binary Search Tree
❖ There are many operations which can be performed on a Binary Search Tree.
Insert Operation
❖ The Insert operation is used to insert a new node to the Binary Search Tree.
352
❖ This operation starts from the root node
❖ The following algorithm shows the insert operation in Binary Search Tree:
Step 1: Create a new node with a value and set its left and right to NULL.
Step 2: Check whether the tree is empty or not.
Step 3: If the tree is empty, set the root to a new node.
Step 4: If the tree is not empty, check whether a value of new node is smaller or larger than the
node (here it is a root node).
Step 5: If a new node is smaller than or equal to the node, move to its left child.
Step 6: If a new node is larger than the node, move to its right child.
Step 7: Repeat the process until we reach to a leaf node.
Example:
• Consider the following example where key = 40 is inserted in the given BST-
Consider the following example where node with value = 20 is deleted from the BST-
Consider the following example where node with value = 30 is deleted from the BST-
Example:
Consider the following example where node with value = 15 is deleted from the BST-
Method-02:
Example:
Consider the following example where node with value = 15 is deleted from the BST-
Search Operation
354
❖ The Search Operation is used to search whether the given element is present in the Binary
Search Tree or not.
❖ This operation starts from the root node.
❖ The following algorithm shows the search operation in binary search tree:
Step 1: Read the element from the user.
Step 2: Compare this element with the value of root node in a tree.
Step 3: If element and value are matching, display "Node is Found" and terminate the function.
Step 4: If element and value are not matching, check whether an element is smaller or larger than a
node value.
Step 5: If an element is smaller, continue the search operation in left subtree.
Step 6: If an element is larger, continue the search operation in right subtree.
Step 7: Repeat the same process until we found the exact element.
Step 8: If an element with search value is found, display "Element is found" and terminate the
function.
Step 9: If we reach to a leaf node and the search value is not match to a leaf node, display
"Element is not found" and terminate the function.
Example:
Consider key = 45 has to be searched in the given BST-
355
The process of creating BST by using the given elements is shown in the image below.
BST Traversal
❖ A Binary Search Tree is traversed in exactly the same way a binary tree is traversed.
❖ In other words, BST traversal is same as binary tree traversal.
❖ There are 3 kinds of traversals that are done typically over a binary search tree.
1) In-order Traversal
❖ This traversal first goes over the left subtree of the root node then accesses the current node,
followed by the right subtree of the current node. The code represents the base case too, which
says that an empty tree is also a binary search tree.
2) Pre-order Traversal
❖ This traversal first accesses the current node value then traverses the left and right sub-trees
respectively.
3) Post-order Traversal
❖ This traversal puts the root value at last, and goes over the left and right sub-trees first. The
relative order of the left and right sub-trees remains the same. Only the position of the root
changes in all the above mentioned traversals
Example:
Consider the following binary search tree-
356
Now, let us write the traversal sequences for this binary search tree-
Pre-order Traversal:
In-order Traversal:
Post-order Traversal:
❖ There are many types of binary search trees. Some of the BST are AVL Trees, and Red–Black
Trees, Splay Trees etc.
1) AVL Tree
❖ AVL tree is a height balanced tree.
❖ It is a self-balancing binary search tree.
❖ AVL tree is another balanced binary search tree.
❖ It was invented by Adelson-Velskii and Landis.
❖ AVL trees have a faster retrieval.
❖ It takes O(logn) time for addition and deletion operation.
❖ In AVL tree, heights of left and right subtree cannot be more than one for all nodes.
2) Red-Black Tree
3) Splay Tree
357
❖ The splay tree data structure is also binary search tree in which recently accessed element is
placed at the root position of tree by performing some rotation operations.
❖ Here, splaying means the recently accessed node.
❖ It is a self-balancing binary search tree having no explicit balance condition like AVL tree.
❖ It might be a possibility that height of the splay tree is not balanced, i.e., height of both left and
right subtrees may differ, but the operations in splay tree takes order of logN time where n is the
number of nodes.
❖ Splay tree is a balanced tree but it cannot be considered as a height balanced tree because after
each operation, rotation is performed which leads to a balanced tree.
Binary Search Tree (BST) Implementation in Java
//Java Program to implement Binary Search Tree
import java.io.*;
import java.util.*;
class BSTNode
{
BSTNode left, right;
int data;
public BSTNode() //Constructor
{
left = null;
right = null;
data = 0;
}
public BSTNode(int n) //Constructor
{
left = null;
right = null;
data = n;
}
// Function to set left node
public void setLeft(BSTNode n)
{
left = n;
}
// Function to set right node
public void setRight(BSTNode n)
{
right = n;
}
// Function to get left node
public BSTNode getLeft()
{
return left;
}
358
// Function to get right node
public BSTNode getRight()
{
return right;
}
// Function to set data to node
public void setData(int d)
{
data = d;
}
// Function to get data from node
public int getData()
{
return data;
}
}
class BST
{
private BSTNode root;
public BST() //Constructor
{
root = null;
}
// Function to check if tree is empty
public boolean isEmpty()
{
return root == null;
}
// Functions to insert data
public void insert(int data)
{
root = insert(root, data);
}
// Function to insert data recursively
private BSTNode insert(BSTNode node, int data)
{
if (node == null)
node = new BSTNode(data);
else
{
if (data <= node.getData())
node.left = insert(node.left, data);
else
node.right = insert(node.right, data);
}
return node;
359
}
// Functions to delete data
public void delete(int k)
{
if (isEmpty())
System.out.println("Tree Empty");
else if (search(k) == false)
System.out.println("Sorry "+ k +" is not present");
else
{
root = delete(root, k);
System.out.println(k+ " deleted from the tree");
}
}
private BSTNode delete(BSTNode root, int k)
{
BSTNode p, p2, n;
if (root.getData() == k)
{
BSTNode lt, rt;
lt = root.getLeft();
rt = root.getRight();
if (lt == null &&rt == null)
return null;
else if (lt == null)
{
p = rt;
return p;
}
else if (rt == null)
{
p = lt;
return p;
}
else
{
p2 = rt;
p = rt;
while (p.getLeft() != null)
p = p.getLeft();
p.setLeft(lt);
return p2;
}
}
if (k <root.getData())
{
n = delete(root.getLeft(), k);
360
root.setLeft(n);
}
else
{
n = delete(root.getRight(), k);
root.setRight(n);
}
return root;
}
// Function to count number of nodes
public int countNodes()
{
return countNodes(root);
}
// Function to count number of nodes recursively
private int countNodes(BSTNode r)
{
if (r == null)
return 0;
else
{
int l = 1;
l += countNodes(r.getLeft());
l += countNodes(r.getRight());
return l;
}
}
// Functions to search for an element
public boolean search(intval)
{
return search(root, val);
}
// Function to search for an element recursively
private boolean search(BSTNode r, intval)
{
boolean found = false;
while ((r != null) && !found)
{
int rval = r.getData();
if (val<rval)
r = r.getLeft();
else if (val>rval)
r = r.getRight();
else
{
found = true;
break;
361
}
found = search(r, val);
}
return found;
}
// Function for inorder traversal
public void inorder()
{
inorder(root);
}
private void inorder(BSTNode r)
{
if (r != null)
{
inorder(r.getLeft());
System.out.print(r.getData() +" ");
inorder(r.getRight());
}
}
// Function for preorder traversal
public void preorder()
{
preorder(root);
}
private void preorder(BSTNode r)
{
if (r != null)
{
System.out.print(r.getData() +" ");
preorder(r.getLeft());
preorder(r.getRight());
}
}
// Function for postorder traversal
public void postorder()
{
postorder(root);
}
364
3. Search
4. Count Nodes
5. Exit
Enter your choice
1
Enter the element to insert
3
PostOrder : 3 5 8
PreOrder : 8 5 3
InOrder : 3 5 8
Do you want to continue? (Type Y or N)
Y
Binary Search Tree Operations
1. Insert
2. Delete
3. Search
4. Count Nodes
5. Exit
Enter your choice
1
Enter integer element to insert
7
PostOrder : 3 7 5 8
PreOrder : 8 5 3 7
InOrder : 3 5 7 8
Do you want to continue? (Type Y or N)
Y
Binary Search Tree Operations
1. Insert
2. Delete
3. Search
4. Count Nodes
5. Exit
Enter your choice
1
Enter the element to insert
10
PostOrder : 3 7 5 10 8
PreOrder : 8 5 3 7 10
InOrder : 3 5 7 8 10
Do you want to continue? (Type Y or N)
Y
Binary Search Tree Operations
1. Insert
2. Delete
3. Search
4. Count Nodes
365
5. Exit
Enter your choice
1
Enter the element to insert
15
PostOrder : 3 7 5 15 10 8
PreOrder : 8 5 3 7 10 15
InOrder : 3 5 7 8 10 15
Do you want to continue? (Type Y or N)
Y
Binary Search Tree Operations
1. Insert
2. Delete
3. Search
4. Count Nodes
5. Exit
1
Enter the element to insert
2
PostOrder : 2 3 7 5 15 10 8
PreOrder : 8 5 3 2 7 10 15
InOrder : 2 3 5 7 8 10 15
Do you want to continue? (Type Y or N)
Y
Binary Search Tree Operations
1. Insert
2. Delete
3. Search
4. Count Nodes
5. Exit
Enter your choice
4
Nodes = 7
PostOrder : 2 3 7 5 15 10 8
PreOrder : 8 5 3 2 7 10 15
InOrder : 2 3 5 7 8 10 15
Do you want to continue? (Type Y or N)
Y
Exercises:
1. Define Tree.
2. List out the applications of tree.
3. Explain briefly about Tree terminalogy.
4. What are sibilings in a Tree?
5. Define degree in tree terminology.
6. What are Leaf nodes?
368
7. Define Depth of a tree.
8. What is Binary Tree?
9. Explain the various types of Binary Trees in detail.
10. What is skewed binary tree?
11. Discuss some of the operations on Binary Trees.
12. Define BFS.
13. Define DFS.
14. Discuss about Tree Traversal with an example.
15. Write a Java program to implement Binary Tree.
16. Explain in detail about Binary Search Tree.
17. Discuss the operations on BST.
18. Explain Binary Search Tree traversal in detail.
19. Define AVL Tree.
20. Define Splay Tree.
21. Write a Java program to implement Binary Search Tree.
************************
************************************************************
Chapter 20 Graphs
************************************************************
20.1 Introduction
❖ A Graph is a non-linear data structure consisting of nodes and edges. The nodes are also
referred to as vertices and the edges are the lines that connect any two nodes in the graph.
369
❖ A Graph can be defined as G = {V, E} where V is the set of vertices and E is the set of edges.
❖ Cycle is a path that starts and ends at the same index.
❖ A graph with no cycles is called a tree. A tree is an acyclic connected graph.
❖ The degree of a node is the number of edges that are connected with that node.
Example:
❖ Direction denotes the way to reach from one node to another node.
370
Figure 20.2: Directed Graph
371
Figure 20.6: Weekly Connected Graph
2. Strongly Connected Graph: A graph in which nodes can be visited by a single path is called
a strongly connected graph.
❖ A graph that has multiple edges connecting the same pair of nodes. The following figure
represents a multi-graph.
372
Figure 20.10: Dense Graph
vii) Sparse Graph
❖ A graph in which the number of edges is close to the minimal number of edges, the graph is
called the sparse graph. It can be a disconnected graph. The following figure represents a sparse
graph.
❖ The Adjacency matrix for an undirected graph is always a symmetric matrix which means an
edge (i, j) implies the edge (j, i).
373
Figure 20.13: Adjacency Matrix for aDirected Graph
❖ If the graph s directed, then the intersection M ij will be set to 1 only if there is a clear edge
directed from Vi to Vj.
374
this.vertex = vertex;
matrix = new int[vertex][vertex];
}
public void addEdge(int start, int destination)
{
matrix[start][destination] = 1;
matrix[destination][start] = 1;
}
public void printGraph()
{
System.out.println("Adjacency Matrix: ");
for (int i = 0; i< vertex; i++)
{
for (int j = 0; j <vertex ; j++)
{
System.out.print(matrix[i][j]+ " ");
}
System.out.println();
}
}
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
AdjacencyMatrix adj = new AdjacencyMatrix(4);
int n, s, d;
System.out.println("Enter the start and the destination values");
n=Integer.parseInt(br.readLine());
for (int i=0;i<n;i++)
{
System.out.println("Enter the start");
s=Integer.parseInt(br.readLine());
System.out.println("Enter the destination");
d=Integer.parseInt(br.readLine());
adj.addEdge(s, d);
}
adj.printGraph();
}
}
Output:
376
❖ In the above directed graph the total length of the adjacency lists of the graph is equal to the
number of edges in the graph. In the above graph, there are 9 edges and sum of the lengths of
adjacency lists for this graph = 9.
❖ In the weighted directed graph, each edge has a weight associated with it. So when we represent
this graph with the adjacency list, we have to add a new field to each list node that will denote
the weight of the edge.
378
Enter the destination
3
Enter the source
1
Enter the destination
4
Enter the source
2
Enter the destination
3
Enter the source
3
Enter the destination
4
Vertex 0 is connected to: 4 1
Vertex 1 is connected to: 4 3 2 0
Vertex 2 is connected to: 3 1
Vertex 3 is connected to: 4 2 1
Vertex 4 is connected to: 3 1 0
20.5 Graph Traversal
❖ Graph traversal means visiting each node exactly once. It is a method used to search nodes
in a graph.
❖ There are two techniques used in graph traversal:
1. Depth First Search
2. Breadth First Search
1. Depth First Search
❖ Depth-First Search (DFS) is a technique that is used to traverse a graph.
❖ DFS technique starts with a root node and then traverses the adjacent nodes of the root
node by going deeper into the graph.
❖ In the DFS technique, the nodes are traversed depth-wise until there are no more children to
explore.
❖ Once we reach the leaf node (no more child nodes), the DFS backtracks and starts with other
nodes and carries out traversal in a similar manner.
❖ DFS technique uses a stack data structure to store the nodes that are being traversed.
❖ Following is the algorithm for the DFS technique.
Algorithm
Step 1: Start with the root node and insert it into the stack
Step 2: Pop the item from the stack and insert into the ‘visited’ list
Step 3: For node marked as ‘visited’ (or in visited list), add the adjacent nodes of this node that are
not yet marked visited, to the stack.
Step 4: Repeat steps 2 and 3 until the stack is empty.
379
Example:
//Java Program to implement the Depth First Search for a Graph
import java.io.*;
import java.util.*;
public class DepthFirstSearch
{
// Function to perform depth first search
static void depthFirstSearch(int[][] matrix, int source)
{
boolean[] visited = new boolean[matrix.length];
visited[source-1] = true;
Stack<Integer> stack = new Stack<>();
stack.push();
int i, x;
System.out.println("The depth first order is");
System.out.println(source);
while(!stack.isEmpty())
{
x = stack.pop();
for(i=0; i<matrix.length; i++)
{
if(matrix[x-1][i] == 1 && visited[i] == false)
{
stack.push(x);
visited[i] = true;
System.out.println(i+1);
x = i+1;
i = -1;
}
}
}
}
// Main Program
public static void main(String args[]) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int vertices;
System.out.println("Enter the number of vertices in the graph");
vertices = Integer.parseInt(br.readLine());
int[][] matrix = new int[vertices][vertices];
System.out.println("Enter the adjacency matrix");
for(int i=0; i<vertices; i++)
{
for(int j=0; j<vertices; j++)
380
{
matrix[i][j] = Integer.parseInt(br.readLine());
}
}
int source;
System.out.println("Enter the source vertex");
source = Integer.parseInt(br.readLine());
depthFirstSearch(matrix,source);
}
}
Output:
Enter the number of vertices in the graph
3
Enter the adjacency matrix
0
0
0
1
0
1
1
1
1
Enter the source vertex
3
3
1
2
Applications of DFS
1) Detect a cycle in a graph: DFS facilitates to detect a cycle in a graph when we can backtrack to
an edge.
2) Path Finding: As we have already seen in the DFS illustration, given any two vertices we can
find the path between these two vertices.
3) Minimum spanning tree and shortest path: If we run the DFS technique on the non-weighted
graph, it gives us the minimum spanning tree and the shorted path.
4) Topological Sorting: Topological sorting is used when we have to schedule the jobs. We have
dependencies among various jobs. We can also use topological sorting for resolving
dependencies among linkers, instruction schedulers, data serialization, etc.
2. Breadth First Search
❖ Breadth-first (BFS) technique uses a queue to store the nodes of the graph.
381
❖ In BFS we traverse the graph breadth-wise. This means we traverse the graph level wise.
❖ When we explore all the vertices or nodes at one level we proceed to the next level.
Algorithm
Step 1: Begin with the root node and insert it into the queue.
Step 2: Repeat steps 3 and 4 for all nodes in the graph.
Step 3: Remove the root node from the queue, and add it to the Visited list.
Step 4: Now add all the adjacent nodes of the root node to the queue and repeat steps 2 to 4 for
each node.[END OF LOOP]
Step 6: EXIT
Example:
//Java Program to implement Breadth First Search on a graph non-recursively
import java.io.*;
import java.util.*;
public class BreadthFirstSearch
{
// Function to perform breadth first search
static void breadthFirstSearch(int[][] matrix, int source)
{
boolean[] visited = new boolean[matrix.length];
visited[source-1] = true;
Queue<Integer> queue = new LinkedList<>();
queue.add(source);
System.out.println("The breadth first order is");
while(!queue.isEmpty())
{
System.out.println(queue.peek());
int x = queue.poll();
int i;
for(i=0; i<matrix.length;i++)
{
if(matrix[x-1][i] == 1 && visited[i] == false)
{
queue.add(i+1);
visited[i] = true;
}
}
}
}
// Main Program
public static void main(String args[]) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int vertices;
382
System.out.println("Enter the number of vertices in the graph");
vertices = Integer.parseInt(br.readLine());
int[][] matrix = new int[vertices][vertices];
System.out.println("Enter the adjacency matrix");
for(int i=0; i<vertices; i++)
{
for(int j=0; j<vertices; j++)
{
matrix[i][j] = Integer.parseInt(br.readLine());
}
}
int source;
System.out.println("Enter the source vertex");
source = Integer.parseInt(br.readLine());
breadthFirstSearch(matrix, source);
}
}
Output:
Enter the number of vertices in the graph
3
Enter the adjacency matrix
0
0
0
1
0
1
1
1
1
Enter the source vertex
2
The breadth first order is
2
1
3
Applications of BFS
1) Garbage Collection: One of the algorithms used by the garbage collection technique to copy
Garbage collection is “Cheney’s algorithm”. This algorithm uses a breadth-first traversal
technique.
2) Broadcasting in Networks: Broadcasting of packets from one point to another in a network is
done using the BFS technique.
383
3) GPS Navigation: We can use the BFS technique to find adjacent nodes while navigating using
GPS.
4) Social Networking Websites: BFS technique is also used in social networking websites to find
the network of people surrounding a particular person.
5) Shortest path and minimum spanning tree in un-weighted graph: In the unweighted graph,
the BFS technique can be used to find a minimum spanning tree and the shortest path between
the nodes.
20.6 Dijkstra's Algorithm
❖ Dijkstra's algorithm is an algorithm for finding the shortest paths between nodes in
a graph.
❖ It is a generalization of the BFS algorithm.
❖ It was conceived by computer scientist Edsger W. Dijkstra in 1956 and published three years
later.
❖ This algorithm uses the greedy method as it always picks the next closest vertex to the source.
Dijkstra Algorithm Details
❖ Any vertex can be selected as a source vertex and distance between a source vertex to itself is
zero.
❖ Initially, we assume all the other vertices are at a distance of infinity.
❖ Next, we find the direct neighbouring vertex of the source vertex which is at a minimum distance.
Let us assume, a vertex has 2 different neighbouring vertexes A and B at a distance of 2 and 4
then the minimum distance vertex is A in this case.
❖ We mark this vertex as a visited vertex and calculate the distance of each direct neighbouring
vertex.
❖ If the sum of the distance of minimum vertex (d[u]) and cost of edge to neighbouring vertex(c[u,
v]) is less than the distance of v(d[v]), then we update the distance of neighbouring vertex as the
sum of the distance of minimum vertex (d[u]) and cost of edge to neighbouring vertex(c[u, v]).
❖ if(d[u] + c[u, v] < d[v]) -> d[v] = d[u] + c[u, v]
❖ This algorithm always selects the shortest path and updates another vertex if above condition
matches.
❖ We repeat this process until we visit all the vertex of a given graph.
Example:
Output:
388
PRACTICAL - III DATA STRUCTURES USING JAVA LAB
OBJECTIVES:
OUTCOMES:
LIST OF EXERCISES:
1. Write a Java program to implement the Stack ADT using a singly linked list.
2. Write a Java program to implement the Queue ADT using a singly linked list.
4. Write a Java program that reads an infix expression, converts into postfix form.
5. Write a Java program to evaluate the postfix expression (use stack ADT).
8. Write a Java program to search for a key element in a binary search tree.
9. Write a Java program for the implementation of BFS for a given graph.
10. Write a Java program for the implementation of DFS for a given graph.
389
1. Implementation of Stack ADT using Singly Linked List
Aim:
To write a Java program to implement the Stack operations using Singly Linked Lists.
Algorithm:
Step 2: The push() method is used to insert an element on the top of the stack.
Step 3: The pop() method is used to remove the topmost element from the stack.
Step 4: The peek() method is used to display the topmost element from the stack.
Step 5: The display() method is used to display all the elements in the stack.
Program:
MENU
---------
1. Push
2. Pop
3. Peek
4. Display
5. Exit
Enter your choice:
1
Enter the element to push:
11
MENU
---------
1. Push
2. Pop
3. Peek
4. Display
5. Exit
Enter your choice:
1
Enter the element to push:
22
MENU
---------
1. Push
2. Pop
3. Peek
4. Display
5. Exit
Enter your choice
1
Enter the element to push:
33
MENU
---------
1. Push
2. Pop
3. Peek
393
4. Display
5. Exit
Enter your choice:
4
The Stack elements are:
33 22 11
MENU
---------
1. Push
2. Pop
3. Peek
4. Display
5. Exit
Enter your choice
3
The top element is: 33
MENU
---------
1. Push
2. Pop
3. Peek
4. Display
5. Exit
Enter your choice
2
The popped element is: 33
MENU
---------
1. Push
2. Pop
3. Peek
4. Display
5. Exit
Enter your choice
4
The Stack elements are:
22 11
MENU
---------
1. Push
2. Pop
3. Peek
4. Display
5. Exit
Enter your choice
5
394
Result:
Thus, the Java program to implement the Stack operations using Singly Linked List has been
executed successfully.
*******************************************************************************
To write a Java program to implement the Queue operations using Singly Linked Lists.
Algorithm:
Step 2: The insert() method is used to add the element at the rear of the queue.
Step 3: The delete() method is used to remove the element at the front of the queue.
Step 4: The peek() method is used to return the first element at the front of the queue.
Step 5: The display() method is used to display all the elements of the queue.
Program:
395
// Function to set data to current Node
public void setData(int d)
{
data = d;
}
// Function to get link to next node
public Node getLink()
{
return link;
}
// Function to get data from current Node
public int getData()
{
return data;
}
}
class LinkedQueue
{
protected Node front, rear;
public int size;
public LinkedQueue() //Constructor
{
front = null;
rear = null;
size = 0;
}
// Function to check if queue is empty
public boolean isEmpty()
{
return front == null;
}
// Function to get the size of the queue
public int getSize()
{
return size;
}
// Function to insert an element to the queue
public void insert(int data)
{
Node nptr = new Node(data, null);
if (rear == null)
{
front = nptr;
rear = nptr;
}
else
{
396
rear.setLink(nptr);
rear = rear.getLink();
}
size++;
}
// Function to delete the front element from the queue
public int delete()
{
if (isEmpty())
throw new NoSuchElementException("Underflow Exception");
Node ptr = front;
front = ptr.getLink();
if (front == null)
rear = null;
size-- ;
return ptr.getData();
}
// Function to return the front element of the queue
public int peek()
{
if (isEmpty())
throw new NoSuchElementException("Underflow Exception");
return front.getData();
}
// Function to display the queue elements
public void display()
{
System.out.print("\nQueue = ");
if (size == 0)
{
System.out.print("Queue is Empty\n");
return;
}
Node ptr = front;
while (ptr != rear.getLink() )
{
System.out.print(ptr.getData()+" ");
ptr = ptr.getLink();
}
System.out.println();
}
}
public class LinkedQueueImplement
{
public static void main(String args[]) throws IOException
{
Scanner sc = new Scanner(System.in);
397
LinkedQueue lq = new LinkedQueue();
int x;
// Perform Queue Operations
System.out.println("Linked Queue Test\n");
char ch;
do
{
System.out.println("Queue Operations");
System.out.println("1. Insert");
System.out.println("2. Delete");
System.out.println("3. Peek");
System.out.println("4. Display");
System.out.println("5. Exit");
System.out.println("\nEnter your choice");
int choice = sc.nextInt();
switch(choice)
{
case 1 :
System.out.println("Enter the element to insert");
x = sc.nextInt();
lq.insert(x);
lq.display();
break;
case 2 :
System.out.println("Deleted Element = "+ lq.delete());
lq.display();
break;
case 3 :
System.out.println("Front Element = "+ lq.peek());
lq.display();
break;
case 4 :
lq.display();
break;
case 5 :
System.exit(0);
break;
default:
System.out.println("Wrong Choive\n ");
break;
}
System.out.println("\nDo you want to continue? (Type Y or N)");
ch = sc.next().charAt(0);
}
while (ch == 'Y'|| ch == 'y');
}
}
398
Output:
Linked Queue Test
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
1
Enter the element to insert
24
Queue = 24
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
1
Enter the element to insert
5
Queue = 24 5
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
3
Front Element = 24
Queue = 24 5
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
399
Enter your choice
2
Deleted Element = 24
Queue = 5
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
4
Queue = 5
Do you want to continue? (Type Y or N)
Y
Queue Operations
1. Insert
2. Delete
3. Peek
4. Display
5. Exit
Enter your choice
5
Do you want to continue? (Type Y or N)
N
Result:
Thus, the Java program to implement the Queue operations using Linked List has been executed
successfully.
***************************************************************************
To write a Java program to implement the Circular Queue using Linked Lists.
Algorithm:
400
Program:
402
case 4 :
System.exit(0);
default :
System.out.println("\nWrong Choice !");
break;
}
}
while(ch!=4);
}
}
Output:
Circular Queue Operations
1. Add
2. Delete
3. Display
4. Exit
Enter Your Choice: 1
Enter the element to add:
10
Circular Queue Operations
1. Add
2. Delete
3. Display
4. Exit
Enter Choice: 1
Enter the element to add:
20
Circular Queue Operations
1. Add
2. Delete
3. Display
4. Exit
Enter Choice: 3
The Circular Queue elements are: 10 20
Circular Queue Operations
1. Add
2. Delete
3. Display
4. Exit
Enter Choice: 2
Item deleted from the queue is: 10
Circular Queue Operations
1. Add
2. Delete
3. Display
403
4. Exit
Enter Choice: 4
Result:
Thus, the Java program to implement the Circular Queue using Arrays has been executed
successfully.
***************************************************************************
To write a Java program to convert the given Infix expression to Postfix form using Stack.
Algorithm:
Step 1: Start the execution.
Step 2: Scan the infix notation from left to right one character at a time.
Step 3: If the next symbol scanned as an operand, append it to the postfix string.
i. Pop and append to the postfix string every operator on the stack that:
Step 6: If a right parenthesis is scanned, all operators down to the most recently scanned left
parenthesis must be popped and appended to the postfix string. Furthermore, the pair of
parentheses must be discarded.
Step 7: When the infix string is fully scanned, the stack may still contain some operators. All the
remaining operators should be popped and appended to the postfix string.
Program:
while (!operators.isEmpty())
postfix = postfix + operators.pop();
return postfix;
}
static int prec(char x)
{
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/' || x == '%')
return 2;
return 0;
}
}
Output:
Enter the Infix Expression
A*(B-C)/D+E
The Postfix of the given Infix Expression is: ABC-*D/E+
Result:
Thus, the Java program to convert the given Infix Expression to postfix form using Stack has
been executed successfully.
***************************************************************************
406
5. Java program to evaluate the Postfix Expression using Stack
Aim:
To write a Java program to evaluate the given Postfix Expression using Stack.
Algorithm:
407
case '*':
stack.push(y * x);
break;
case '/':
stack.push(y / x);
break;
}
}
}
return stack.pop();
}
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the Postfix Expression");
String exp=br.readLine();
System.out.println("Postfix Evaluation: "+evaluatePostfix(exp));
}
}
Output:
Enter the Postfix Expression
138×+
Postfix Evaluation: 25
Result:
Thus, the Java program to evaluate the Postfix expression using stack has been executed
successfully.
******************************************************************************
408
6. Java Program to insert an element into the Binary Search Tree
Aim:
To write a Java Program to insert an element into the Binary Search Tree.
Algorithm:
Step 3: Using for loop, read the node elements one by one.
Step 4: If the value of the new node is less than the root node then, it will be inserted to the left
subtree.
Step 5: If the value of the new node is greater than root node then, it will be inserted to the right
subtree.
Step 6 : On reaching the end node, insert the value left (if the value is smaller than current node
value), else right.
Program:
Thus, the Java program to insert an element into the Binary Search Tree has been executed
successfully.
***************************************************************************
411
7. Java program to delete an element from a binary search tree
Aim:
Algorithm:
Step 3 : Using for loop, read the node elements one by one.
Step 4 : If the value of the new node is less than the root node then, it will be inserted to the left
subtree.
Step 5 : If the value of the new node is greater than root node then, it will be inserted to the right
subtree.
Step 6 : On reaching the end node, insert the value left (if the value is smaller than current node
value), else right.
ii) Node to be deleted has only one child: Copy the child to the node and delete the
child
iii) Node to be deleted has two children: Find inorder successor of the node. Copy
contents of the inorder successor to the node and delete the inorder successor.
Note that inorder predecessor can also be used.
Program:
Output:
Enter the total nodes
6
Enter the node elements
50
30
20
40
70
60
Inorder traversal of the given tree
20 30 40 50 60 70
Enter the node to be deleted
20
Binary Search Tree after deleting a node
30 40 50 60 70
Result:
Thus, the Java program to delete an element from the Binary Search Tree has been executed
successfully.
415
8. Java program to search for a key element in a binary search tree
Aim:
Algorithm:
Step 3 : Using for loop, read the node elements one by one.
Step 4 : If the value of the new node is less than the root node then, it will be inserted to the left
subtree.
Step 5 : If the value of the new node is greater than root node then, it will be inserted to the right
subtree.
Step 6 : On reaching the end node, insert the value left (if the value is smaller than current node
value), else right.
Step 10: Else if key < root, traverse the left subtree.
Step 12: Repetitively compare subtree elements until the key is found or the end of the tree is
reached.
Step 13: If the element to search is found anywhere, return true, else return false.
Program:
416
root = null;
}
static class Node
{
int value;
Node left;
Node right;
Node(int value)
{
this.value = value;
left = null;
right = null;
}
public void displayData()
{
System.out.print(value + " ");
}
}
public void insert(int i)
{
root = insert(root, i);
}
//Inserting node - recursive method
public Node insert(Node node, int value)
{
if(node == null)
{
return new Node(value);
}
// Move to the left if passed value is less than the current node
if (value <node.value)
{
node.left = insert(node.left, value);
}
// Move to the right if passed value is greater than the current node
else
if (value >node.value)
{
node.right = insert(node.right, value);
}
return node;
}
// Search node in binary search tree
public Node find(int searchedValue)
{
Node current = root;
417
while(current.value != searchedValue)
{
if(searchedValue<current.value)
// Move to the left if searched value is less
current = current.left;
else
// Move to the right if searched value is >=
current = current.right;
if (current == null)
{
return null;
}
}
return current;
}
// For traversing in order
public void inOrder(Node node)
{
if(node != null)
{
inOrder(node.left);
node.displayData();
inOrder(node.right);
}
}
// Preorder traversal
public void preOrder(Node node)
{
if(node != null)
{
node.displayData();
preOrder(node.left);
preOrder(node.right);
}
}
// Postorder traversal
public void postOrder(Node node)
{
if(node != null)
{
postOrder(node.left);
postOrder(node.right);
node.displayData();
}
}
418
//Main Program
public static void main(String args[]) throws IOException
{
BinarySearchTree bst = new BinarySearchTree();
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n, x, s;
System.out.println("Enter the total nodes");
n=Integer.parseInt(br.readLine());
System.out.println("Enter the node elements");
for (int i=1;i<=n;i++)
{
x=Integer.parseInt(br.readLine());
bst.insert(x);
}
System.out.println("Inorder traversal of binary search tree");
bst.inOrder(bst.root);
System.out.println();
System.out.println("Preorder traversal of binary search tree");
bst.preOrder(bst.root);
System.out.println();
System.out.println("Postorder traversal of binary searcg tree");
bst.postOrder(bst.root);
System.out.println();
System.out.println("Enter the element to search");
s=Integer.parseInt(br.readLine());
Node node = bst.find(s);
System.out.println((node == null)? "Node not found": String.valueOf(node.value));
}
}
Output:
Enter the total nodes
6
Enter the node elements
50
70
15
35
Enter the element to search
16
Inorder traversal of binary tree
15 35 50 70
Preorder traversal of binary tree
50 15 35 70
Postorder traversal of binary tree
35 15 70 50
Node not found
419
Result:
Thus, the Java program to search an element in a Binary Search Tree has been executed
successfully.
***************************************************************************
Aim:
Algorithm:
Step 5 : Find neighbors of node with the help of adjacency matrix and check if node is
Program:
// 9. BFS_Graph.java
import java.io.*;
import java.util.*;
public class BFS_Graph
{
final int TRUE = 1;
final int FALSE = 0;
final int MAX = 20;
int [][] G = new int [MAX][MAX];
int [] visited = new int [MAX];
int [] q = new int [MAX];
int n, v1, v2;
int front, rear;
BFS_Graph()
{
System.out.println("Enter the number of nodes");
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i=1;i<=n;i++)
visited[i] = FALSE;
420
for (v1=1;v1<=n;v1++)
{
for (v2=1;v2<=n;v2++)
G[v1][v2] = FALSE;
}
front = rear = -1;
}
void CreateGraph()
{
char ans;
System.out.println("Enter the edges with vertex no. starting from 1");
do
{
System.out.println("Enter the vertices v1 & v2:");
Scanner sc = new Scanner(System.in);
v1 = sc.nextInt();
v2 = sc.nextInt();
if (v1 > n || v2 > n)
System.out.println("Invalid Vertex Number");
else
{
G[v1][v2] = TRUE;
G[v2][v1] =TRUE;
}
System.out.println("Want to add more edges (y/n)?");
ans = sc.next().charAt(0);
}
while (ans == 'Y' || ans == 'y');
}
void Adjacency_Matrix()
{
System.out.println("Adjacency Matrix for the Graph is");
for (int v1=1;v1<=n;v1++)
{
for (int v2=1;v2<=n;v2++)
System.out.print(G[v1][v2] + " ");
System.out.println();
}
}
void bfs(int v)
{
int i;
visited[v] = TRUE;
q[++rear] = v;
while (front != rear)
{
v = q[++front];
421
System.out.println(v +" ");
for (i=1;i<=n;i++)
{
if (G[v][i] == TRUE && visited[i] == FALSE)
{
q[++rear] = i;
visited[i] = TRUE;
}
}
}
}
public static void main(String args[])
{
System.out.println("Implementation of BFS for a given graph");
BFS_Graph g = new BFS_Graph();
g.CreateGraph();
g.Adjacency_Matrix();
System.out.println("Breadth First Traversal for the above graph is");
g.bfs(1);
}
}
Output:
Implementation of BFS for a given graph
Enter the number of nodes
4
Enter the edges with vertex no. starting from 1
Enter the vertices v1 & v2:
1
2
Want to add more edges (y/n)?
y
Enter the vertices v1 & v2:
1
3
Want to add more edges (y/n)?
y
Enter the vertices v1 & v2:
1
4
Want to add more edges (y/n)?
422
y
Enter the vertices v1 & v2:
2
3
Want to add more edges (y/n)?
n
Adjacency Matrix for the Graph is
0111
1010
0100
1000
Depth first traversal for the above graph is
1
2
3
4
Result:
Thus, the Java program to implement the Breadth First Search for a graph has been executed
successfully.
*******************************************************************************
Aim:
Algorithm:
Step 5: Pop the element from the stack and print the element.
Step 6: For every adjacent and unvisited node of current node, mark the node and insert it in the
stack.
423
Program:
Thus, the Java program to implement the Depth First Search for a graph has been executed
successfully.
*******************************************************************************
426