Java Foundation With Data Structures Lecture 2: Getting Started
Java Foundation With Data Structures Lecture 2: Getting Started
a) About Eclipse
A new Java class can be created using the New Java Class wizard. The Java Class
wizard can be invoked in different ways –
1. By clicking on the File menu and selecting New → Class, or
2. By right clicking in the package explorer and selecting New → Class, or
3. By clicking on the class drop down button and selecting class.
Note : W e will understand what classes are when we will study Object Oriented
Programming. For now you can assume them as a file. Also name of class and
.java file inside which we have this class should be same.
b) About Main
1. This is the line at which the program will begin executing. This statement
is similar to start block in flowcharts. All Java programs begin execution
by calling main()
2. We will understand what public, static, void mean in subsequent
lectures. For now we should assume that we have to write main as it is.
3. The curly braces {} indicate start and end of main.
c) print / println
Output:
Hello World
Programming is fun
Variables
a) Add two numbers
Output:
15
Here, we used variables to store values of two integers and their sum. Thus, a
variable is a basic unit of storage in a Java program.
Here, type is one of Java’s primitive datatypes. The variable_name is the name of
a variable. We can initialize the variable by specifying an equal sign and a value
(Initialization is optional). However, the compiler never assigns a default value to
an uninitialized local variable in Java.
While writing variable names you should be careful and follow the rules for
naming them. Following are the rules for writing variable names -
1. All variable names may contain uppercase and lowercase letters (a-z, A-Z),
underscore ( _ ), dollar sign ($) and the digits 0 to 9. The dollar sign character
is not intended for general use. No spaces and no other special characters
are allowed.
2. The variable names must not begin with a number.
3. Java is case-sensitive. Uppercase characters are distinct from lowercase
characters.
4. A Java keyword (reserved word) cannot be used as a variable name.
Based on the data type of a variable, the operating system allocates memory and
decides what can be stored in the reserved memory. Therefore, by assigning
different data types to variables, we can store integers, decimals, or characters in
these variables.
Example Code:
Taking Input
a) Scanner
The Java Scanner class breaks the input into tokens using a delimiter that is
whitespace by default. It provides many ways to read and parse various
primitive values.
In order to use scanner you have to write this import statement at the top –
import java.util.Scanner;
Example Code:
// Create a Scanner
Scanner s = new Scanner(System.in);
a = s.nextInt();
b = s.nextInt();
c = a + b;
System.out.println("Sum of entered integers = "+c);
}
}
Sample Input:
10 5
Output:
15
Here, s.nextInt() scans and returns the next token as int. A token is part of entered
line that is separated from other tokens by space, tab or newline. So when input
line is: “10 5” then s.nextInt() returns the first token i.e. “10” as int and s.nextInt()
again returns the next token i.e. “5” as int.
b) Code for calculating simple interest taking input from user
Example Code:
import java.util.Scanner;
Sample Input:
2500.0 6.0 5.0
Output:
750.0
import java.util.Scanner;
public class ScannerDemo1 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
char ch = s.next().charAt(0); // character input
System.out.println("input character = " +ch);
}
}
Sample Input:
k
Output:
input character = k
Sample Input:
Coding Ninjas
Output:
Coding
Here, s.next() returns the next token as String. A token is part of entered line that
is separated from other tokens by space, tab or newline. So when input line is -
“Coding Ninjas” then s.next() returns the first token i.e. “Coding”.
METHOD DESCRIPTION
public String next() It returns the next token from the Scanner.
public String nextLine() It moves the Scanner position to the next line
and returns the value as a string.
public byte nextByte() It scans the next token as a byte.
public short nextShort() It scans the next token as a short value.
public int nextInt() It scans the next token as an int value.
public long nextLong() It scans the next token as a long value.
public float nextFloat() It scans the next token as a float value.
public double It scans the next token as a double value.
nextDouble()
Example code:
Sample Input:
100 Hello World
Output:
100
Hello World
Here, s.nextInt() scans and returns the next token as int. A token is part of entered
line that is separated from other tokens by space, tab or newline. So when input
line is - “100 Hello World” then s.nextInt() returns the first token as int i.e. “100”
and s.nextLine() returns remaining part of line i.e “ (space)Hello World”
The most commonly used integer type is int which is a signed 32-bit type.
When you store an integer, its corresponding binary value is stored. The way
integers are stored differs for negative and positive numbers. For positive
numbers the integral value is simple converted into binary value and for negative
numbers their 2’s compliment form is stored.
Let’s discuss How are Negative Numbers Stored?
1. There is only one representation for the number zero in 2's complement,
instead of two representations in sign-magnitude and 1's complement.
Example:
int i = -4;
Steps to calculate Two’s Complement of -4 are as follows:
Thus, integer -4 is represented by the binary sequence (1111 1111 1111 1111
1111 1111 1111 1100) in Java.
In Java, any value declared with decimal point is by default of type double (which
is of 8 bytes). If we want to assign a float value (which is of 4 bytes), then we must
use ‘f’ or ‘F’ literal to specify that current value is “float”.
Example:
float float_val = 10.4f; //float value
double val = 10.4; //double value
Example code:
When we add int to char, we are basically adding two numbers i.e. one
corresponding to the integer and other is corresponding code for the char.
Example code:
Output:
98
Here, we added a character and an int, so it added the ASCII value of char ‘a’ i.e
97 and int 1. So, answer will be 98.
Similar logic applies to adding two chars as well, when two chars are added their
codes are actually added i.e. ‘a’ + ‘b’ wil give 195.
Typecasting
Example code:
double d = 100.04;
long l2 = (long)d; //explicit type casting
System.out.println(i);
System.out.println(l1);
System.out.println(d);
System.out.println(l2);
}
Output:
100
100
100.04
100
Operators
a) Arithmetic operators
Arithmetic operators are used in mathematical expression in the same way that
are used in algebra.
OPERATOR DESCRIPTION
+ Adds two operands
- Subtracts second operand from first
* Multiplies two operands
/ Divides numerator by denominator
% Calculates Remainder of division
b) Relational operators
Relational Operators are the operators that used to test some king of relation
between two entities. The following table lists the relation operators supported
by Java.
OPERATOR DESCRIPTION
== Check if two operands are equal
!= Check if two operands are not equal.
> Check if operand on the left is greater than operand on
the right
< Check if operand on the left is smaller than right
operand
>= Check if left operand is greater than or equal to right
operand
<= Check if operand on left is smaller than or equal to right
operand
c) Logical operators
OPERATOR DESCRIPTION
&& al AND
|| al OR
! al NOT
Example:
Suppose a = true and b= false, then:
(a && b) is false
(a || b) is true
(!a) is false
Java Foundation with Data Structures
Lecture 4 : Loops, Keywords, Associativity and Precedence
for loop
Loop statements allows us to execute a block of statements several number of
times depending on certain condition. for loop is kind of loop in which we give
initialization statement, test expression and update statement can be written in
one line.
Example Code :
In for loop its not compulsory to write all three statements i.e.
initializationStatement, test_expression and u pdateStatement. We can skip one
or more of them (even all three)
OR
public static v oid main(String[] args) {
int i = 1; //initialization is done outside the for loop
for(; i < =5; ) {
System.out. println(i);
i++; // update Statement written here
}
}
Output:
0
1
2
Output:
0
1
2
Example code 3: Condition expression removed , thus making our loop infinite –
Example code 4:
We can remove all the three expression, thus forming an infinite loop-
We can initialize multiple variables, have multiple conditions and multiple update
statements inside a for loop. We can separate multiple statements using
comma, but not for conditions. They need to be combined using logical
operators.
Example code:
Output:
04
13
22
31
40
Output:
1
2
3
4
5
Output:
1
2
3
4
5
When there are two more loops inside one another. Break from innermost loop
will just exit that loop.
Example Code 1:
Example Code 2:
public static void main(String[] args) {
int i=1;
while (i <=3) {
System.out. println(i);
int j=1;
while (j <= 5)
{
System.out. println(“in”);
if(j==1)
{
break;
}
j++;
}
i++;
}
}
Output:
1
in…
2
in…
3
in…
❖ Continue
The continue keyword can be used in any of the loop control structures. It causes
the loop to immediately jump to the next iteration of the loop.
Output:
1
2
4
5
Output:
1
2
4
5
Scope of variables
Scope of variables is the curly brackets {} inside which they are defined. Outside
which they aren’t known to the compiler. Same is for all loops and conditional
statement (if).
Example:
public static void main(String[] args) {
for (int i=0; i<5; i++) {
int j=2; // Scope of i and j are both inside the loop they can’t be used outside
}
while(test_expression) {
// Scope of variable defined in loop
}
if(test_expression) {
// Scope of variable defined in the conditional statement
}
Explanation
Pre-increment and pre-decrement operators’ increments or decrements the value
of the object and returns a reference to the result.
Post-increment and post-decrement creates a copy of the object, increments or
decrements the value of the object and returns the copy from before the
increment or decrement.
Post-increment(a++):
This increases value by 1, but uses old value of a in any statement.
Pre-increment(++a):
This increases value by 1, and uses increased value of a in any statement.
Post-decrement(a--):
This decreases value by 1, but uses old value of a in any statement.
Pre-decrement(++a):
This decreases value by 1, and uses decreased value of a in any statement.
}
Output:
1120
2020
Bitwise Operators
Bitwise operators are used to perform operations at bit level. Following is the
summary of various bitwise operations:
Example Code:
c = a >>> 2
; // 4 = 00100
System.out.println("a >>> 2 = " + c );
}
Output
a & b = 16
a | b = 31
a ^ b = 15
~a = -20
a << 2 = 76
a >> 2 = 4
a >>> 2 = 4
1) Associativity is only used when there are two or more operators of same
precedence.
The point to note is associativity doesn’t define the order in which operands of a
single operator are evaluated. For example, consider the following program,
associativity of the + operator is left to right, but it doesn’t mean f1() is always
called before f2(). The output of following program is in-fact compiler dependent.
// Associativity is not used in the below program. Output is compiler dependent.
static int x = 0;
public static int F1() {
x = 5;
return x;
}
public static int F2() {
x = 10;
return x;
}
public static void main(String[] args) {
int p = F1() + F2();
System.out.println(x);
}
Following is the Precedence table along with associativity for different operators.
Defining Function
return_type function_name(parameter 1, parameter 2, ………) {
statements;
}
● return type: A function may return a value. The return type of the
function is the data type of the value that function returns. Sometimes
function is not required to return any value and still performs the
desired task. The return type of such functions is void.
Example:
Following is the example of a function that sum of two numbers. Here input to
the function are the numbers and output is their sum.
1. public static int findSum( int a, int b
){
2. int sum = a + b;
3. return sum;
4. }
Function Calling
Now that we have read about how to create a function lets see how to call the
function. To call the function you need to know the name of the function and
number of parameters required and their data types and to collect the
returned value by the function you need to know the return type of the
function.
Example
Output:
30
IMPORTANT POINTS:
● Number of parameter and their data type while calling must match with
function signature. Consider the above example, while calling function
findSum () the number of parameters are two and both the parameter
are of integer type.
● It is okay not to collect the return value of function. For example, in the
above code to find the sum of two numbers it is right to print the return
value directly.
“System.out. print(c);”
● void return type functions: These are the functions that do not return
any value to calling function. These functions are created and used to
perform specific task just like the normal function except they do not
return a value after function executes.
Following are some more examples of functions and their use to give you a
better idea.
Consider the following code where there is a function called findsum which
calculates and returns sum of two numbers.
For Example: In above code entry point of the function findSum () is at line
number 3. So when at line number 9 the function call occurs the control goes
to line number 3, then after the statements in the function findSum () are
executed the programme control comes back to line number 9.
Benefits of functions
● Modularisation
● Easy Debugging: It is easy to find and correct the error in function as
compared to raw code without function where you must correct the
error (if there is any) everywhere the specific task of the function is
performed.
● Neat code: A code created with function is easy to read and dry run.
Output
5
In the above code the variable a declared inside the block after if statement is
a local variable for this block.
Lifetime of a Variable
The lifetime of a variable is the time period for which the declared variable has
a valid memory. Scope and lifetime of a variable are two different concepts,
scope of a variable is part of a programme for which this variable is accessible
whereas lifetime is duration for which this variable has a valid memory.
Loop variable
Loop variable is a variable which defines the loop index for each iteration.
Example
“for (int i = 0; i < 3; i++) { // variable i i s the loop variable
…….;
……..;
statements;
} “
For this example, variable i is the loop variable.
Pass by value:
When the parameters are passed to a function by pass by value method, then
the formal parameters are allocated to a new memory. These parameters have
same value as that of actual parameters. Since the formal parameters are
allocated to new memory any changes in these parameters will not reflect to
actual parameters.
Example:
//Function to increase the parameters value
1. public static v oid increase(int x, int y){
2. x++;
3. y = y + 2;
4. System.out. println(x + ":" + y); // x and y are formal
parameters
5. }
6. public static v oid main(String[] args) {
7. int a = 10;
8. int b = 20;
9. increase(a,b);
10. System.out. println(a + ":" + b); // a and b are actual
parameters
11.
12.}
Output:
11: 22
10: 20
For the above code, changes in the values of x and y are not reflected to a and
b because x and y are formal parameters and are local to function increment so
any changes in their values here won’t affect variables a and b inside main.
String
class
provides
an
inbuilt
method
to
determine
the
length
of
the
Java
String.
For
example:
String
class
provides
an
inbuilt
method
to
get
the
index
of
a
character
in
Java
String.
For
example:
Similar
to
the
above
question,
given
the
index,
how
do
I
know
the
character
at
that
location?
Simple
one
again!!
Use
the
“charAt”
method
and
provide
the
index
whose
character
you
need
to
find.
Use
“compareToIgnoreCase”
in
case
you
don’t
want
the
result
to
be
case
sensitive.
The
result
will
have
the
value
0
if
the
argument
string
is
equal
to
this
string;
a
value
less
than
0
if
this
string
is
lexicographically
less
than
the
string
argument;
and
a
value
greater
than
0
if
this
string
is
lexicographically
greater
than
the
string
argument.
Use
the
method
“contains”
to
check
if
a
string
contains
another
string
and
specify
the
characters
you
need
to
check.
Returns
true
if
and
only
if
this
string
contains
the
specified
sequence
of
char
values.
String
str
=
"test
string";
System.out.println("Contains
sequence
ing:
"
+
str.contains("ing"));
This
method
is
used
to
find
whether
a
string
ends
with
particular
prefix
or
not.
Returns
true
if
the
character
sequence
represented
by
the
argument
is
a
suffix
of
the
character
sequence
represented
by
this
object.
Java
String
Replace,
replaceAll
and
replaceFirst
methods.
You
can
specify
the
part
of
the
String
you
want
to
replace
and
the
replacement
String
in
the
arguments.
Use
the
“toLowercase()”
or
“ToUpperCase()”
methods
against
the
Strings
that
need
to
be
converted.
Topic
:
Object
Oriented
Programming
1. Objects are the real world entities about which we code. Objects have
properties and they perform functions. For example in a student management
system the real world entities about which the system revolves are – students,
instructor, course, batch etc.
2. A Class is a template or a blue print and the objects are specific copies of it.
For example a Vehicle class might look like :
Here this is a keyword that refers to current object, So this.price refers to the
data member (i.e. price) of this object and not the argument variable price.
One important point to note here is that as soon as we create our
constructor the default constructor goes off.
Now when we have defined the above constructor and if it is the only
constructor in the class, then we can’t create any object of Vehicle without
giving its price. In a way we can actually restrict users that they can’t create a
vehicle without giving its price.
We can have more than one constructors within the same class (i.e
constructor overloading), which constructor will be called will be decided on
runtime depending on the type and number of arguments specified while
creating the object.
3. Modifiers
1. Static and Non-Static : Static properties are those that belong to the
class rather each specific object. So their separate copies aren’t
created. They are shared by all the objects of the class. You need to
write static keyword before it in order to make it static.
For e.g :
2. Access Modifiers
3. Protected : It is accessible within the same package and outside
the package but only through inheritance.
4. Public : It is accessible everywhere.
Components Of OOPS
1. Encapsulation - Binding (or wrapping) code and data together into a single
unit i.e a class is known as encapsulation. It lets us hide the implementation
details using different access modifiers. Also it lets us change the implementation
without breaking the code of users.
Here car (sub class) extends Vehicle (base class / super class) since every car
is a vehicle. So car will now have all the properties and functions that a vehicle
has except the private fields of vehicle class(since they are not inherited , but
they can be accessed via functions of base class that aren’t private).
• What if both the base class and sub class have function with same signature
i.e same name and arguments ? Say even car has a printDescription function
as in vehicle.
then
Car c = new Car();
c.printDescription(); // This will call car’s printDescription
then Car, which extends Vehicle needs to have a constructor that passes value
to the vehicle constructor which is implicitly called when we create an object
of car.
3.1. Ability of a variable to take different forms – A base class’ reference can refer
to the object of its sub class i.e we can do something like this –
Since every car is a vehicle so a vehicle(i.e. reference of type vehicle) can
refer to a car. And not just the car, reference “v” here can refer to object
of any other class that extends vehicle. But through this refernce “v” we
can access only those properties of car which even a vehicle has i.e.
3.2. Overriding the base class functions(Virtual Functions) – We have already seen
its example above in inheritance. When both base class and sub class have
functions of same signature then base class’ function is overriden by the
subclass’ function.
Amongst these three add functions which add will be called finally, will
be decided on runtime based on the type of parameters.
Constructor overloading is similar to function overloading. At runtime
while creating an object the number and type of parameters passed will
decide that which constructor will be called.
public Vehicle(){
}!
3.4. Ability of a function to work with parameters of subtypes – This one is just an
extension of first type.
This print function expects a vehicle, so we can pass a car(or object of any
of its subtype) to it i.e.
Exceptions
Types of Exception
Exception Handling
Try block - The code which can cause an exception is enclosed within try block.
Catch block - The action to be taken when an exception has occurred is done in
catch block. It must be used after the try block only.
Finally block - Java finally block is a block that is used to execute important
code such as closing connection, stream etc. Java finally block is always executed
whether exception is handled or not.
Note :
1. Whenever an exception occurs statements in the try block after the
statement in which exception occurred are not executed
2. For each try block there can be zero or more catch blocks, but only one
finally block.
A user defined exception is a sub class of the exception class. For creating an
exception you simply need to extend Exception class as shown below :
Throwing an Exception
Sometimes, it's appropriate for code to catch exceptions that can occur within it. In
other cases, however, it's better to let a method further up the call stack handle the
exception. For example if input to the factorial method is a negative number, then it
makes more sense for the factorial to throw an exception and the method that has
called factorial method to handle the exception.
Here is the code for the factorial method :
Java
Foundation
with
Data
Structures
Topic:
Recursion
Recursion
a. What
is
Recursion?
In
previous
lectures,
we
used
iteration
to
solve
problems.
Now,
we’ll
learn
about
recursion
for
solving
problems
which
contain
smaller
sub-‐problems
of
the
same
kind.
Recursion
in
computer
science
is
a
method
where
the
solution
to
a
problem
depends
on
solutions
to
smaller
instances
of
the
same
problem.
By
same
nature
it
actually
means
that
the
approach
that
we
use
to
solve
the
original
problem
can
be
used
to
solve
smaller
problems
as
well.
So
in
other
words
in
recursion
a
function
calls
itself
to
solve
smaller
problems.
Recursion
is
a
popular
approach
for
solving
problems
because
recursive
solutions
are
generally
easier
to
think
than
their
iterative
counterparts
and
the
code
is
also
shorter
and
easier
to
understand.
b. How
Does
Recursion
Work?
We
can
define
the
steps
of
a
recursive
solution
as
follows:
1. Base
Case:
A
recursive
function
must
have
a
terminating
condition
at
which
the
function
will
stop
calling
itself.
Such
a
condition
is
known
as
a
base
case.
2. Recursive
Call:
The
recursive
function
will
recursively
invoke
itself
on
the
smaller
version
of
problem.
We
need
to
be
careful
while
writing
this
step
as
it
is
important
to
correctly
figure
out
what
your
smaller
problem
is
on
whose
solution
the
original
problem’s
solution
depends.
3. Small
Calculation:
Generally
we
perform
a
some
calculation
step
in
each
recursive
call.
We
can
perform
this
calculation
step
before
or
after
the
recursive
call
depending
upon
the
nature
of
the
problem.
It
is
important
to
note
here
that
recursion
uses
stack
to
store
the
recursive
calls.
So,
to
avoid
memory
overflow
problem,
we
should
define
a
recursive
solution
with
minimum
possible
number
of
recursive
calls
such
that
the
base
condition
is
achieved
before
the
recursion
stack
starts
overflowing
on
getting
completely
filled.
Now,
let
us
look
at
an
example
to
calculate
factorial
of
a
number
using
recursion.
Example
Code
1:
public
class
Solution{
public
static
int
fact(int
n)
{
if(n==0)
//Base
Case
{
return
1;
}
return
n
*
fact(n-‐1);
//Recursive
call
with
small
calculation
}
public
static
void
main()
{
int
num;
Scanner
s
=
new
Scanner(Syatem.in);
num
=
s.nextInt();
System.out.println(fact(num));
return
0;
}
}
Output:
120
//For
num=5
Explanation:
Here,
we
called
factorial
function
recursively
till
number
became
0.
Then,
the
statements
below
the
recursive
call
statement
were
executed.
We
can
visualize
the
recursion
tree
for
this
function,
where
let
n=5,
as
follows:
fact(5)
finally
returns
5
*
24
=
120
to
the
code
which
called
the
function
fact(n)
fact(5)
Returns
4
*
6
=
24
fact(4)
Returns
3
*
2
=
6
fact(3)
Returns
2
*
1
=
2
fact(2)
Returns 1 * 1 = 1
fact(1)
Returns
1
fact(0)
We
are
calculating
the
factorial
of
n=5
here.
We
can
infer
that
the
function
recursively
calls
fact(n)
till
n
becomes
0,
which
is
the
base
case
here.
In
the
base
case,
we
returned
the
value
1.
Then,
the
statements
after
the
recursive
calls
were
executed
which
returned
n*fact(n-‐1)
for
each
call.
Finally,
fact(5)
returned
the
answer
120
to
main()
from
where
we
had
invoked
the
fact()
function.
Now,
let
us
look
at
another
example
to
find
nth
Fibonacci
number
.
In
Fibonacci
series
to
calculate
nth
Fibonacci
number
we
can
use
the
formula
F(n)
=
F(n
–
1)
+
F(n
–
2)
i.e.
nth
Fibonacci
term
is
equal
to
sum
of
n-‐1
and
n-‐2
Fibonacci
terms.
So
let’s
use
this
to
write
recursive
code
for
nth
Fibonacci
number.
Example
Code
2:
//
Recursive
function:
int
fibo(int
n)
{
if(n==0
||
n==1)
{
//Base
Case
return
n;
}
int
a
=
fibo(n-‐1);
//Recursive
call
int
b
=
fibo(n-‐2);
//Recursive
call
return
a+b;
//Small
Calculation
and
return
statement
}
Explanation:
As
we
are
aware
of
the
Fibonacci
Series
(0,
1,
1,
2,
3,
5,
8,…
and
so
on),
let
us
assume
that
the
index
starts
from
0,
so,
5th
Fibonacci
number
will
correspond
to
5;
6th
Fibonacci
number
will
correspond
to
8;
and
so
on.
Here,
in
recursive
Fibonacci
function,
we
have
made
two
recursive
calls
which
are
depicted
as
follows:
fibo(n)
fibo(n-‐1)
fibo(n-‐2)
Note:
One
thing
that
we
should
be
clear
about
is
that
both
recursive
calls
don’t
happen
simultaneously.
First
fibo(n-‐1)
is
called,
and
only
after
we
have
its
result
and
store
it
in
“a”
we
move
to
next
statement
to
calculate
fibo(n
–
2).
It
is
interesting
to
note
here
that
the
concept
of
recursion
is
based
on
the
mathematical
concept
of
PMI
(Principle
of
Mathematical
Induction).
When
we
use
PMI
to
prove
a
theorem,
we
have
to
show
that
the
base
case
(usually
for
x=0
or
x=1)
is
true
and,
the
induction
hypothesis
for
case
x=k
is
true
must
imply
that
case
x=k+1
is
also
true.
We
can
now
understand
how
the
steps
which
we
followed
in
recursion
are
based
on
the
induction
steps,
as
in
recursion
also,
we
have
a
base
case
while
the
assumption
corresponds
to
the
recursive
call.