0% found this document useful (0 votes)
15 views458 pages

Sodapdf

The document provides an overview of programming languages, focusing on their syntax and semantics, as well as the differences between statically and dynamically typed languages. It discusses Java's features, including its various editions, the importance of the main method, command line arguments, and the concept of packages. Additionally, it covers naming conventions and tokens in Java programming.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views458 pages

Sodapdf

The document provides an overview of programming languages, focusing on their syntax and semantics, as well as the differences between statically and dynamically typed languages. It discusses Java's features, including its various editions, the importance of the main method, command line arguments, and the concept of packages. Additionally, it covers naming conventions and tokens in Java programming.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 458

javaravishanker@gmail.

com

30-OCT-23

What is language ?
------------------
A language is a communication media through which we can communicate with each other.

Any language contains two important things

1) Syntax (Rules)
2) Semantics (Structure OR Meaning)

English langugae translation :


--------------------------------
Subject + verb + Object (Syntax)

He is a boy. (Valid)

He is a box. (Invalid)

Example of Progamming Language :


----------------------------------------
int a = 10;
int b = 0;
int c = a/b; //Exception

Note :-
Syntax of the programming language is taken care by compiler.
compiler generates errors if a user does not follow the syntax of the programming language.

Semantics is taken care by our runtime Environment (JVM). It generates Exception if a user does not
follow the semantics.
(Code is meaningless)
------------------------------------------------------------------
31-10-2023
----------
Statically(Strongly) typed language :-
---------------------------------------
The languages where data type is compulsory before initialization of a variable are called statically typed
language.

In these languages we can hold same kind of value during the execution of the program.

Ex:- C,C++,Core Java, C#

Dynamically(Loosly) typed language :-


-------------------------------------------
The languages where data type is not compulsory and it is optional before initialization of a variable then
it is called dynamically typed language.

In these languages we can hold different kind of value during the execution of the program.
Ex:- Visual Basic, Javascript, Python

public class Test


{
public static void main(String[] args)
{
var x = 90; //java 10
x = 67;
System.out.println(x);

}
}
------------------------------------------------------------------
Different flavors of Java :
----------------------------
In java we have total 4 flavors

1) JSE (Java Standard Edition) -> Core Java

2) JEE (Java Enterprise Edition) -> Advanced Java

3) JME (Java Micro/Mobile Edition) -> Android Java

4) JAVA FX -> It is out dated, by using java FX we can develop GUI


applications.
----------------------------------------------------------------
01-11-2023
-----------
What is the difference between Stand alone programs and web related programs

Standalone Application
--------------------------
If the creation(development), compilation and execution of the program, everthing is done in a single
system then it is called stand-alone program.
Eg:- C, C++, Java, C# and so on.

Stand alone programs are also known as Software OR Desktop application.

Web - related Application :-


--------------------------------
If creation of the program, compilation of the program and execution of the program, Everything is done
on different places then it is called web related program.
Eg:- Advanced Java, PHP, ASP.NET, Python

Web related programs are also known as websites or web application.


--------------------------------------------------------------------
What is a function :-
-----------------------
A function is a self defined block for any general purpose, calculation or printing some data.

The major benefits with function are :-


-------------------------------------------
1) Modularity :- Dividing the bigger modules into number of smaller modules where each module will
perform its independent task.

2) Easy understanding :- Once we divide the bigger task into number of smaller tasks then it is easy to
understand the entire code.
3) Reusability :- We can reuse a particular module so many number of times so It enhances the
reusability nature.

Note :- In java we always reuse our classes.(WORA)

4) Easy Debugging :- Debugging means finding the errors, With function It is easy to find out the errors
because each module is independent with another module.
-------------------------------------------------------------------
Why we pass parameter to a function :-
--------------------------------------------
We pass parameter to a function for providing more information regrading the function.

Eg:-

public void deposit(int amount)


{
}

public void sleep(int hours)


{
}
-------------------------------------------------------------------
Why functions are called method in java?
----------------------------------------------
In C++ there is a facility to write a function inside the class as well as outside of the class by using ::
(Scope resolution Operator), But in java all the functions must be declared inside the class only.

That is the reason member functions are called method in java.

Variable --> Field


function ---> Method
-------------------------------------------------------------------
02-11-2023
-----------
Why java become so popular in the IT Industry ?
-----------------------------------------------------
The role of compiler :
-------------------------
a) Compiler are used to check the syntax.
b) It also check the compatibility issues(LHS = RHS)
c) It converts the source code into machine code.

Java code :
-------------
a) Java programs must be saved having extension .java

b) java compiler(javac) is used to compile our code.

c) After successful compilation we are getting .class file (bytecode)

d) This .class file we submit to JVM for execution prupose (for executing my java code)

JVM :- It stands for Java Virtual Machine. It is a software in the form of interpreter written in ’C’
language.
Every browser contains JVM, Those browsers are known as JEB (Java Enabled Browsers) browsers.
------------------------------------------------------------------
C and C++ programs are platform dependent programs that means the .exe file created on one machine
will not be executed on the another machine if the system configuration is different.

That is the reason C and C++ programs are not suitable for website development.

Where as on the other hand java is a platform independent language. Whenever we write a java program,
the extension of java program must be .java.

Now this .java file we submit to java compiler (javac) for compilation process. After successful compilation
the compiler will generate a very special machine code file i.e .class file (also known as bytecode). Now
this .class file we submit to JVM for execution purpose.

The role of JVM is to load and execute the .class file. Here JVM plays a major role because It converts
the .class file into appropriate machine code instruction (Operating System format) so java becomes
platform independent language and it is highly suitable for website development.

Note :- We have different JVM for different Operating System that means JVM is platform dependent
technology where as Java is platform Independent technology.
-------------------------------------------------------------------
What is the difference between the bit code and byte code.
----------------------------------------------------------
Bit code is directly understood by Operating System but on the other hand byte code is understood by
JVM, JVM is going to convert this byte code into machine understandable format.
-------------------------------------------------------------------
03-11-2023
----------

1) Single line Comment (//)

2) Multiline Comment (/* ------------------------------- */)

3) Documentation Comment (/** -------------------------- */)

/**
Name of the Project : Online Shopping
Date created :- 12-12-2021
Last Modified - 16-01-2022
Author :- Ravishankar
Modules : - 10 Modules
*/
------------------------------------------------------------------
WAP in java to display welcome message :
----------------------------------------
public class Welcome
{
public static void main(String[] args)
{
System.out.println("Hello Batch 27");
}
}

Note :-
1) In java whenever we write a program we need at least a main method which takes String array as an
argument.

2) In java the execution of the program always starts and ends with main method.

----------------------------------------------------------------
Description of main() method :
-----------------------------------
public :-
--------
public is an access modifier in java. The main method must be declared as public otherwise JVM cannot
execute our main method or in other words JVM can’t enter inside the main method for execution of the
program.

If main method is not declared as public then program will compile but it will not be executed by JVM.

Note :- From java compiler point of view there is no rule to declare our methods as public.

static :-
--------
In java our main method is static so we need not to create an object to call the main method.

If a method is declared as a static then we need not to create an object to call that method. We can
directly call the static methods with the help of class name.

If we don’t declare the main method as static method then our program will compile but it will not be
executed by JVM.
------------------------------------------------------------------
void :-
-------
It is a keyword. It means no return type. Whenever we define any method in java and if we don’t want to
return any kind of value from that particular method then we should write void before the name of the
method.

Eg:

public void input() public int accept()


{ {
} return 15;
}

Note :- In the main method if we don’t write void or any other kind of return type then it will generate a
compilation error.

In java whenever we define a method then compulsory we should define return type of method.(Syntax
rule)
-------------------------------------------------------------------
04-11-20230
------------
main() :-
----------
It is a user-defined method because a user is responsible to define some logic inside the main method.

main() method is very important method because every program execution will start from main() method
only, as well as the execution of the program ends with main() method only.
We can write multiple main methods in our class but argument must be different. JVM will always search
the main method which takes String array as a parameter.
-----------------------------------------------------------------
Command Line Argument (Introduction only) :-
-------------------------------------------
Whenever we pass an argument/parameter to the main method then it is called Command Line
Argument.

The argument inside the main method is String because String is a alpha-numeric collection of character
so, It can accept numbers,decimals, characters, combination of number and character.

That is the reason java software people has provided String as a parameter inside the main
method.(More Wider scope to accept the value)
------------------------------------------------------------------
System.out.println() :-
-------------------------
It is an output statement in java, By using System.out.println() statement we can print anything on the
console.

In System.out.println(), System is a predefined class available in java.lang package, out is a reference


variable of PrintStream class available in java.io package and println() is a predfined method available in
PrintStream class.

In System.out, .(dot) is a member access operator. It is called as period. It is used to access the member
of the class.
-------------------------------------------------------------------
WAP in java to add two numbers :
--------------------------------

public class Addition


{
public static void main(String[] args)
{
int x = 120;
int y = 220;
int z = x + y;
System.out.println(z);
}
}

In this program we are getting the result but it is not


user-friendly, to provide user-friendly message we should re-write the program

public class AdditionWithMessage


{
public static void main(String[] args)
{
int x = 12;
int y = 24;
int z = x + y;
System.out.println("Sum is :"+z);
}
}
-------------------------------------------------------------------
//Addition of two number without 3rd variable
public class Sum
{
public static void main(String[] args)
{
int x = 12;
int y = 15;
System.out.println("Sum is :"+x+y); //Sum is : 1215
System.out.println(+x+y); //27
System.out.println(""+x+y); //1215
System.out.println("Sum is :"+(x+y));//Sum is : 27

}
}
-------------------------------------------------------------------
Interview Question :
--------------------
package com.nit;

public class Demo


{
public static void main(String x[])
{
String str = 40 + 40 + "Nit"+ 90 + 90; //80NIT9090
System.out.println(str);
}

}
------------------------------------------------------------------
Command Line Argument :
-----------------------
Whenever we pass any argument to the main method then it is called Command Line Argument.

By using Command Line Argument we can pass some value at runtime.

The advantage of Command Line Argument is single time compilation


and number of times execution.

public class Command


{
public static void main(String[] args)
{
System.out.println(args[0]);
}
}

javac Command.java (Compilation)


java Command Virat Rohit Bumrah

Here Virat position is 0, Rohit is in 1 and Bumrah is in 2nd position so it will print Virat.
-------------------------------------------------------------------------
package com.ravi.command;

public class CommandName


{
public static void main(String[] args)
{
System.out.println(args[0]);
}

javac CommandName.java
java CommandName 12 89 90

It will print 12
--------------------------------------------------------------------------
package com.ravi.command;

public class CommandName


{
public static void main(String[] args)
{
System.out.println(args[0]);
}

javac CommandName.java
java CommandName Sachin Ramesh Tendulkar

It will print Sachin

But I want to print Sachin Ramesh Tendulkar

javac CommandName.java
java CommandName "Sachin Ramesh Tendulkar"

It will print Sachin Ramesh Tendulkar


-------------------------------------------------------------------------
WAP in java to add two numbers by using Command Line Argument :
----------------------------------------------------------------
package com.ravi.command;

public class CommandAddition


{
public static void main(String[] args)
{
System.out.println(args[0]+args[1]);

javac CommandAddition.java
java CommandAddition 123 123

It will print 123123 because ’+’ operator will work as a String Concatenation Operator.
-------------------------------------------------------------------------
How to convert String value into corresponding integer :
--------------------------------------------------------------
Java software people has provided a predefined class called Integer available in java.lang package.

This class contains a predefined static method parseInt(String x) which accepts single String parameter.

This method is used to convert the String value into corresponding integer value.

If the String value is not in a proper format (Virat Rohit) then it will generate an exception i.e
java.lang.NumberFormatException

package com.ravi.command;

public class CommandAddition


{
public static void main(String[] args)
{

//Converting String to integer


int x = Integer.parseInt(args[0]);
int y = Integer.parseInt(args[1]);

System.out.println("Sum is :"+(x+y));

}
------------------------------------------------------------------------
//Program which is similar to Integer.parseIne(String s)
--------------------------------------------------------
package com.ravi.command;

class Calculate
{
public static int doSum(int x, int y)
{
return (x+y);
}
}

public class Addition {

public static void main(String[] args)


{
int result = Calculate.doSum(100, 200);
System.out.println(result);

-------------------------------------------------------------------------
WAP to find out the cube of the number by using command line argument
------------------------------------------------------------------------
package com.ravi.command;

public class FindingCube {

public static void main(String[] args)


{
int num = Integer.parseInt(args[0]);
System.out.println("Cube of :"+num+" is :"+(num*num*num));

}
-------------------------------------------------------------------------
What is a package ?
---------------------
A package is nothing but folder in windows operating System.

The program which contains package statement, we need to compile in a different way

javac -d . FileName.java (Command)

(javac space -d space . space FileName.java)

Program :
---------
package com.nit.basic;
public class Test
{

How to compile the above program :


-----------------------------------
javac -d . Test.java (Command)

When we compile the above code 3 folders will be created.


com -> nit -> basic -> Test.class

Package is divide into two categories

1) Predefined Package OR Built-in package


2) Userdefined Package OR Custom Package

1) Predefined Package OR Built-in package :- The package created


by java software people is known as Predefined Package OR Built-
in package.
java.lang, java.io and so on

2) Userdefined Package OR Custom Package :- The packages created by


user according to use and specification are called Userdefined
Package OR Custom Package.
com.ravi.basic, com.nit.introduction
-------------------------------------------------------------------------
07-11-2023
----------
Naming convention in java language :
--------------------------------------------
1) How to write a class in java
----------------------------------
While writing a class in java we should follow pascal naming convention. A java class represents noun.

ThisIsExampleOfClass (Each word first letter is capital)


Example :
-----------
String
System
Integer
BufferedReader
DataInputStream
ClassNotFoundException
ArithmeticException

2) How to write a method in java :


---------------------------------------
In order to write methods in java we need to follow camel case naming convention. A java method
represents verb.

thisIsExampleOfMethod()

Example:
----------
read()
readLine()
toUpperCase()
charAt()

3) How to write variable(Fields) in java


--------------------------------------------
In order to write variables in java we need to follow camel case naming convention.

rollNumber;
employeeName;
customerNumber;
customerBill;

4) How to write final variable(Field)


-------------------------------
final double PI = 3.14;
final int A = 90;

5) How to write final and static variable

MAX_VALUE;
MIN_VALUE;
Each character must be capital and in between every word _ symbol should be there.

6) How to write package


Package name must be in small character. It is reverse of company name.
com.ravi.basic;
------------------------------------------------------------------------
Token :
--------
A token is the smallest unit of the program that is identified by the compiler.

Every Java statements and expressions are created using tokens.

A token can be divided into 5 types

1) Keywords
2) Identifiers
3) Literals
4) Punctuators
5) Operators

Keyword :-
----------
A keyword is a predefined word whose meaning is already defined by the compiler.

In java all the keywords must be in lowercase only.

A keyword we can’t use as a name of the variable, name of the class or name of the method.

true, false and null look like keywords but actually they are literals.

Identifiers :
--------------
A name in java program by default considered as identifiers.

Assigned to variable, method, classes to uniquely identify them.

We can’t use keyword as an identifier.

Ex:-

class Fan
{
int coil ;

void start()
{
}
}

Here Fan(Name of the class), coil (Name of the variable) and start(Name of the function) are identifiers.
------------------------------------------------------------------------------------
Rules for defining an identifier :
------------------------------------
1) Can consist of uppercase(A-Z), lowercase(a-z), digits(0-9), $ sign, and underscore (_)
2) Begins with letter, $, and _
3) It is case sensitive
4) Cannot be a keyword
5) No limitation of length
-----------------------------------------------------------------------
Literals :-
-----------
Assigning some constant value to variable is called Literal.

Java supports 5 types of Literals :

1) Integral Literal Ex:- int x = 15;

2) Floating Point Literal Ex:- float x = 3.5f;

3) Character Literal Ex:- char ch = ’A’;

4) Boolean Literal Ex:- boolean b = true;

5) String Literal Ex:- String x = "Naresh i Technology";

Note :- null is also a literal.

------------------------------------------------------------------------
08-11-2023
------------
Integral Literal :
------------------
If any literal contains number without decimal then it is called
intergral literal.

Example :- 89, 90, 56, 67

In integral literal we have 4 data types


a) byte (8 bits)
b) short (16 bits)
c) int (32 bits)
d) long (64 bits)

An integral literal we can specify or represent in different ways

a) Decimal literal (Base 10)


b) Octal literal (Base 8)
c) Hexadecimal literal (Base 16)
d) Binary Literal (Base 2) (Available from JDK 1.7 onwards)

In order to get the result from octal, hexadecimal or binary we must need to convert into decimal format.

Decimal Literal :-
-------------------
The base of decimal literal is 10. we can accept any digit from 0-9

Octal Literal :-
----------------
The base is 8. Here we can accept digits from 0-7 only. In java if any integral literal prefeix with ’0’ (Zero)
then it becomes octal lietral.
Example:-

int x = 015; //Valid


int y = 018;//Invalid [Here digit 8 is out of the range]

Hexadecimal Literal :-
-------------------------
The base is 16. Here we can accept digits from 0-15 (0-9 and A-F). In java if any integral literal prefix with
0X or 0x (zero with capital X OR zero with small x) then it becomes hexadecimal literal.

Example :-

int x = 0X15; //Valid


int y = 0x14;//Valid
int z = 0Xadd; //Valid
int a = 0Xage; //Invalid [’g’ is out of range]

Binary Literal :-
-----------------
It is introduced from jdk 1.7 onwards. The base or radix is 2. Here we can accept digits 0 and 1 only. In
java if any integral Literal prefix with 0B or 0b (zero capital B or 0 small b) then it becomes binary literal.

Example :-

int x = 0B111; //Valid


int y = 0b101010; //Valid
int z = 0B12; //Invalid [digit 2 is out of range]

Note :-
------
Being a user we can represent integral literal in decimal, octal, hexadecimal and binary form but JVM
always produces the result in decimal only.
-------------------------------------------------------------------------
//Octal literal
public class Test1
{
public static void main(String[] args)
{
int one = 01;
int six = 06;
int seven = 07;
int eight = 010;
int nine = 011;
System.out.println("Octal 01 = "+one);
System.out.println("Octal 06 = "+six);
System.out.println("Octal 07 = "+seven);
System.out.println("Octal 010 = "+eight);
System.out.println("Octal 011 = "+nine);
}
}
-------------------------------------------------------------------------
//Hexadecimal
public class Test2
{
public static void main(String[] args)
{
int i = 0x10; //16
int j = 0Xadd; //2781
System.out.println(i);
System.out.println(j);
}
}
------------------------------------------------------------------------
//Binary Literal
public class Test3
{
public static void main(String[] args)
{
int i = 0b101;
int j = 0B111;
System.out.println(i); //5
System.out.println(j); //7

}
}
-------------------------------------------------------------------------
By default every integral literal is of type int only but we can specify explicitly as long type by suffixing with
l (small l) OR L (Capital L).

According to industry standard L is more preferable because l (small l) looks like 1(digit 1).

There is no direct way to specify byte and short literals explicitly. If we assign any integral literal to byte
variable and if the value is within the range (-128 to 127) then it is automatically treated as byte literals.

If we assign integral literals to short and if the value is within the range (-32768 to 32767) then
automatically it is treated as short literals.
-----------------------------------------------------------------------
/* By default every integral literal is of type int only*/
public class Test4
{
public static void main(String[] args)
{
byte b = 128;
System.out.println(b);

short s = 32768;
System.out.println(s);
}
}

The above program will generate CE becuase 128 is out of the range of byte as well as 32768 is also out
of the range short.
------------------------------------------------------------------------
//Assigning smaller data type value to bigger data type
public class Test5
{
public static void main(String[] args)
{
byte b = 125;
short s = b; //Implicit (Automatic) type casting
System.out.println(s);
}
}
-------------------------------------------------------------------------
//Converting bigger type to smaller type
public class Test6
{
public static void main(String[] args)
{
short s = 129;
byte b = (byte) s; //Explicit type casting [chance of data loss]
System.out.println(b);
}
}
-------------------------------------------------------------------------
public class Test7
{
public static void main(String[] args)
{
byte x = (byte) 127L;
System.out.println("x value = "+x);

long l = 29L;
System.out.println("l value = "+l);

int y = (int)18L;
System.out.println("y value = "+y);

}
}
------------------------------------------------------------------------
09-11-2023
-----------
Is java pure Object-Oriented language ?
----------------------------------------------
No, Java is not a pure Object-Oriented language. In fact any language which accepts the primary data
type like int, float, char is not a pure object oriented language hence java is also not a pure object oriented
language.

If we remove all 8 primitive data types from java then Java will become pure object oriented language.

In java we have a concept called Wrapper classes through which we can convert the primary data types
into corrosponding Wrapper Object.(Autoboxing 1.5V)

Primary data types Corrosponding Wrapper Object


byte - Byte
short - Short
int - Integer
long - Long
float - Float
double - Double
char - Character
boolean - Boolean
All these wrapper classes are available in java.lang package.
-------------------------------------------------------------------------
//Wrapper claases
public class Test8
{
public static void main(String[] args)
{
Integer x = 24;
Integer y = 24;
Integer z = x + y;
System.out.println("The sum is :"+z);

Boolean b = true;
System.out.println(b);

Double d = 90.90;
System.out.println(d);
}
}

Note :- From java 1.5 onwards now according to Autoboxing concept, we can
directly convert the primitive type into wrapper object.
------------------------------------------------------------------------
How to know the minimum and maximum value as well as size of integral literal data types:
----------------------------------------------------------------
Thses classes (Wrapper classe) are providing the static and final variables through which we can find out
the minimum, maximum value as well as size of the data types

Ex:- I want to find out the range and size of Byte class

Byte.MIN_VALUE = -128

Byte.MAX_VALUE = 127

Byte.SIZE = 8 (in bits format)

Here MIN_VALUE, MAX_VALUE and SIZE these are static and final variables available in these
classes(Byte, Short, Integer and Long).
-------------------------------------------------------------------------
//Program to find out the range and size of Integeral Data type
public class Test9
{
public static void main(String[] args)
{
System.out.println("\n Byte range:");
System.out.println(" min: " + Byte.MIN_VALUE);
System.out.println(" max: " + Byte.MAX_VALUE);
System.out.println(" size :"+Byte.SIZE);

System.out.println("\n Short range:");


System.out.println(" min: " + Short.MIN_VALUE);
System.out.println(" max: " + Short.MAX_VALUE);
System.out.println(" size :"+Short.SIZE);

System.out.println("\n Integer range:");


System.out.println(" min: " + Integer.MIN_VALUE);
System.out.println(" max: " + Integer.MAX_VALUE);
System.out.println(" size :"+Integer.SIZE);

System.out.println("\n Long range:");


System.out.println(" min: " + Long.MIN_VALUE);
System.out.println(" max: " + Long.MAX_VALUE);
System.out.println(" size :"+Long.SIZE);

}
}
-------------------------------------------------------------------------
//We can provide _ in integral literal
public class Test10
{
public static void main(String[] args)
{
long mobile = 9812_3456_78L;
System.out.println("Mobile Number is :"+mobile);
}
}

Note :- From java 1.7V now we can provide _ symbol in numeric


literal just to increase the readability of the code.
-------------------------------------------------------------------------
public class Test11
{
public static void main(String[] args)
{
final int x = 12;
byte b = x;
System.out.println(b);
}
}

Program will compile because x value we cannot re-assign


------------------------------------------------------------------
// Converting from decimal to another number system
public class Test12
{
public static void main(String[] argv)
{
//decimal to Binary
System.out.println(Integer.toBinaryString(7)); //111

//decimal to Octal
System.out.println(Integer.toOctalString(15)); //17

//decimal to Hexadecimal
System.out.println(Integer.toHexString(2781)); //add
}
}
------------------------------------------------------------------------
//var keyword (Available from java 10)
public class Test13
{
public static void main(String[] args)
{
var x = 12; //Here x will become if type int and it
will hold only integer type of value
System.out.println(x);
}
}
-----------------------------------------------------------------------
2) Floating point Literal :
---------------------------
If any numeric literal contains fraction or decimal then it is called
floating point literal.

Example :- 12.1, 78.56, 34.89

In floating point literal we have 2 data types


a) float (32 bits)
b) double (64 bits)

In floating point literal by default every floating point literal is of


type double only so, the following statement will generate compilation error.
float f1 = 23.89; //error

Here we can have 3 solutions.

float f1 = (float) 0.1; //Valid


float f2 = 89.90f; //Valid
float f3 = 23.67F; //Valid

Even though every floating point literal is of type double but still to represent double value explicitly,
compiler has provided two flavors to enhance the readability of the code.

double d1 = 34.89d;
double d1 = 34.89D;

* While working with integeral literal we had four types of representation decimal, octal, hexadecimal and
binary but floating point literal cannot have any different form rather than decimal.

* Integral literal(byte, short, int and long) we can assign to floating point literal(float and double) but
floating point literal we cannot assign to integral literal.

A floating point litearl we can represent in exponent form.

double d1 = 15e2; //Exponent form


-----------------------------------------------------------------------
10-11-2023
------------
public class Test
{
public static void main(String[] args)
{
float f = 2.0; //error
System.out.println(f);
}
}
-----------------------------------------------------------------------
public class Test1
{
public static void main(String[] args)
{
//float a = 1.0;
float b = 15.29F;
float c = 15.25f;
float d = (float) 15.25;
System.out.println(b +" : "+c+" : " +d);

}
}

----------------------------------------------------------------------
public class Test2
{
public static void main(String[] args)
{
double d = 15.15;
double e = 15.15d;
double f = 15.15D;

System.out.println(d+" , "+e+" , "+f);


}
}
-----------------------------------------------------------------------
public class Test3
{
public static void main(String[] args)
{
double x = 0129.89;

double y = 0167;

double z = 0178; //error

System.out.println(x+","+y+","+z);
}
}
----------------------------------------------------------------------
class Test4
{
public static void main(String[] args)
{
double x = 0X29;

double y = 0X9.15; //error

System.out.println(x+","+y);
}
}
-----------------------------------------------------------------------
public class Test5
{
public static void main(String[] args)
{
double d1 = 15e-3;
System.out.println("d1 value is :"+d1);

double d2 = 15e3;
System.out.println("d2 value is :"+d2);

}
}
----------------------------------------------------------------------
public class Test6
{
public static void main(String[] args)
{
double a = 0791; //error

double b = 0791.0;

double c = 0777;

double d = 0Xdead;

double e = 0Xdead.0; //error


}
}
-----------------------------------------------------------------------
public class Test7
{
public static void main(String[] args)
{
double a = 1.5e3;
float b = 1.5e3; //E
float c = 1.5e3F;
double d = 10;
int e = 10.0; //E
long f = 10D; //E
int g = 10F; //E
long l = 12.78F; //E
}
}
-----------------------------------------------------------------------
//Range and size of floating point literal
public class Test8
{
public static void main(String[] args)
{
System.out.println("\n Float range:");
System.out.println(" min: " + Float.MIN_VALUE);
System.out.println(" max: " + Float.MAX_VALUE);
System.out.println(" size :"+Float.SIZE);

System.out.println("\n Double range:");


System.out.println(" min: " + Double.MIN_VALUE);
System.out.println(" max: " + Double.MAX_VALUE);
System.out.println(" size :"+Double.SIZE);
}
}
-----------------------------------------------------------------------
3) boolean Literal :
--------------------
boolean literal can be represented in two states i.e true or false.

In boolean literal we have only one data type i.e boolean which accepts 1 bit of memory as well as it also
depends upon JVM implementation.

boolean isValid = true;


boolean isEmpty = false;

Unlike C and C++, In java we cannot assign integral literal to boolean data type.

boolean isAlive = 0; (Valid in C and C++ but Invalid in Java )

We cannot assign String literal value to boolean data type.

boolean isEmpty = "true"; //Invalid

-----------------------------------------------------------------------
IQ
--
class Test
{
public static void main(String[] args)
{

while(false) //Unreachable loop


{
System.out.println("In while loop");
}

System.out.println("Outside of while loop");

}
}

The same program if we will write with variable program will compile.

class Test
{
public static void main(String[] args)
{
boolean isTrue = false;
while(isTrue)
{
System.out.println("In while loop");
}

System.out.println("Outside of while loop");

}
}
-----------------------------------------------------------------------
public class Test1
{
public static void main(String[] args)
{
boolean isValid = true;
boolean isEmpty = false;

System.out.println(isValid);
System.out.println(isEmpty);
}
}
-----------------------------------------------------------------------
public class Test2
{
public static void main(String[] args)
{
boolean c = 0; //error
boolean d = 1; //error
System.out.println(c);
System.out.println(d);
}
}
----------------------------------------------------------------------
public class Test3
{
public static void main(String[] args)
{
boolean x = "true";
boolean y = "false";
System.out.println(x);
System.out.println(y);
}
}
-----------------------------------------------------------------------
4) Character Literal :
---------------------
It is also known as char literal.

In char literal we have only one data type i.e char which accepts
2 bytes of memory.

In java, We can represent the char literal in different forms which are
as follows :
a) Single character enclosed with single quotes.
char ch = ’A’;

b) We can assign integral literal to char data type to represnt UNICODE value. In older languages like C
and C++, It supports
ASCII format where the range is 0 - 255. Java supports UNICODE
format where the range is 0 - 65535.

char ch1 = 65535; //Valid


char ch1 = 65536; //Invalid

c) We can assign the character literal to integral literal to get


the UNICODE value of that particular character.

Example :- int x = ’A’; -> 65

d) We can assign character literal in 4 digit hexadecimal number


to represent the UNICODE value where the format is

’\udddd’
Here \u means unicode and d represents it is a digit.

The range of 4 digit hexadecimal number is


’\u0000’ to ’\uffff’

e) We can represent all the escape sequences by using char literal.


-----------------------------------------------------------------------
11-11-2023
-----------
public class Test1
{
public static void main(String[] args)
{
char ch1 = ’a’;
System.out.println("ch1 value is :"+ch1);

char ch2 = 97;


System.out.println("ch2 value is :"+ch2);

}
}
----------------------------------------------------------------------
class Test2
{
public static void main(String[] args)
{
int ch = ’A’;
System.out.println("ch value is :"+ch);
}
}
----------------------------------------------------------------------
//The UNICODE value for ? character is
public class Test3
{
public static void main(String[] args)
{
char ch1 = 63;
System.out.println("ch1 value is :"+ch1);

char ch2 = 64;


System.out.println("ch2 value is :"+ch2);

char ch3 = 97;


System.out.println("ch3 value is :"+ch3);
}
}

The ? symbol UNICODE value is 63


-----------------------------------------------------------------------
public class Test4
{
public static void main(String[] args)
{
char ch1 = 47000;
System.out.println("ch1 value is :"+ch1);

char ch2 = 0Xadd;


System.out.println("ch2 value is :"+ch2);
}
}

In the above program we will get ? symbol as an output because the


corresponding language translator is not available in our system/laptop.
-----------------------------------------------------------------------
//Addition of two character in the form of Integer
public class Test5
{
public static void main(String txt[ ])
{
int x = ’A’;
int y = ’B’;
System.out.println(x+y); //131
System.out.println(’A’ + ’A’); //130
}
}
----------------------------------------------------------------------
//Range of UNICODE Value (65535)
class Test6
{
public static void main(String[] args)
{
char ch1 = 65535;
System.out.println("ch value is :"+ch1);

char ch2 = 65536;


System.out.println("ch value is :"+ch2);
}
}
----------------------------------------------------------------------
//WAP in java to describe unicode representation of char in hexadecimal format
class Test7
{
public static void main(String[] args)
{
char ch1 = ’\u0001’;
System.out.println(ch1);

char ch2 = ’\uffff’;


System.out.println(ch2);

char ch3 = ’\u0041’;


System.out.println(ch3);

char ch4 = ’\u0061’;


System.out.println(ch4);
}
}
----------------------------------------------------------------------
class Test8
{
public static void main(String[] args)
{
char c1 = ’A’;
char c2 = 65;
char c3 = ’\u0041’;

System.out.println("c1 = "+c1+", c2 ="+c2+", c3 ="+c3);


}
}
-----------------------------------------------------------------------
class Test9
{
public static void main(String[] args)
{
int x = ’A’;
int y = ’\u0041’;
System.out.println("x = "+x+" y ="+y);
}
}
----------------------------------------------------------------------
//Every escape sequence is char literal
class Test10
{
public static void main(String [] args)
{
char ch =’\n’;
System.out.println(ch);
}
}
-----------------------------------------------------------------------
public class Test11
{
public static void main(String[] args)
{
System.out.println(Character.MIN_VALUE); //white space
System.out.println(Character.MAX_VALUE); //?
System.out.println(Character.SIZE); //16 bits

}
}
----------------------------------------------------------------------
//Java Unicodes
public class Test12
{
public static void main(String[] args)
{
System.out.println(" Java Unicodes\n");

for (int i = 31; i < 126; i++)


{
char ch = (char)i; // Convert unicode to character
String str = i + " "+ ch;

System.out.print(str + "\t\t");
if ((i % 5) == 0) // Set 5 numbers per row
System.out.println();
}
}
}
----------------------------------------------------------------------
String Literal :
----------------
String is a predefined class available in java.lang package. It is a collection of alpha-numeric characters.
We can represent any special symbol by using String literal.

We can String in java by using 3 ways :

1) By Using String Literal :


String str1 = "Hello"; //Literal

2) By using new keyword :


String str2 = new String("India"); //new keyword

3) By using character array :


char [] ch = {’R’,’A’,’V’,’I’};
-----------------------------------------------------------------------
//Three Ways to create the String Object
public class StringTest1
{
public static void main(String[] args)
{
String s1 = "Hello World"; //Literal
System.out.println(s1);

String s2 = new String("Ravi"); //Using new Keyword


System.out.println(s2);

char s3[] = {’H’,’E’,’L’,’L’,’O’}; //Character Array


System.out.println(s3);

}
}
----------------------------------------------------------------------
//String is collection of alpha-numeric character
public class StringTest2
{
public static void main(String[] args)
{
String x="B-61 Hyderabad";
System.out.println(x);

String y = "123";
System.out.println(y);

String z = "67.90";
System.out.println(z);

String p = "A";
System.out.println(p);
}
}
-----------------------------------------------------------------------
//IQ
public class StringTest3
{
public static void main(String []args)
{
String s = 15+29+"Ravi"+40+40;
System.out.println(s);

}
}
---------------------------------------------------------------------
4) Punctuators :
----------------
It is also known as Separators.

It is used to inform the compiler that how the the things will be grouped together.

public class Test


{
int x = 10;
}

Example of punctuators : {}, [], (), ; , ...(var args java 5).


-----------------------------------------------------------------------
5) Operator :
-------------
An operator describes how the calculation will be performed on openands.

In java we will learn following Operators :


--------------------------------------------
1) Arithmetic Operator (Binary Operator)
2) Unary Operator
3) Assignment Operator
4) Relational Operator
5) Logical Operator
6) Boolean Operator
7) Bitwise Operator
8) Ternary Operator
9) Dot operator OR Member Access Operator
10) new Operator (Keyword)
11) instanceof operator (Keyword)
----------------------------------------------------------------------
Arithmetic Operator :-
----------------------
It is also known as Binary Operator because, to work with binary operator we need minimum two
operands.

Example :- +, -, *, / and %
---------------------------------------------------------------------
//Arithmetic Operator
// Addition operator to join two Strings working as String concatenation optr
public class Test1
{
public static void main(String[] args)
{
String s1 = "Welcome to";
String s2 = " Java ";
String s3 = s1 + s2;
System.out.println("String after concatenation :"+s3);

}
}
-----------------------------------------------------------------------
How to read the data from Client :
----------------------------------
Limitation of Command Line Argument :
-------------------------------------
It is used to read the data from Client in String format and here we two limitations :

a) Developer cannot provide some user-friendly message to the end client before input the data.

b) All the data we have in String format so conversion is reqd.

Reading the Data from java.util.Scanner class :


------------------------------------------------
In java.util package, there is a predefined class called Scanner, this class is used to read the data from
the client.

static variable of System class :


----------------------------------
System class available in java.lang package has provided 3 static variables which are as follows :

System.out :- It is used to print the normal message in the screen.

System.err :- It is used to print the error message in the screen.(Red Color)


System.in :- It is used to take the input from the user

How to create the Object for Scanner class :


--------------------------------------------
Scanner sc = new Scanner(System.in);

Methods of Scanner class :


---------------------------
1) public String next() :- It is used to read a single word.

2) public String nextLine() :- It is used to read multiple words or


complete line.

3) public byte nextByte() :- It is used to read byte value

4) public short nextShort() :- It is used to read short value

5) public int nextInt() :- It is used to read int value

6) public long nextLong() :- It is used to read long value

7) public float nextFloat() :- It is used to read float value

8) public double nextDouble() :- It is used to read double value

9) public boolean nextBoolean() :- It is used to read boolean value

10) public char next().charAt(0) :- It is used to read a single character.


-----------------------------------------------------------------------
//Program to read the gender [M/F] from the keyboard

public class ReadGender


{
public static void main(String [] args)
{
java.util.Scanner sc = new java.util.Scanner(System.in);
System.out.print("Enter your Gender [M/F] :");

char gen = sc.next().charAt(0);


System.out.println("Your Gender is :"+gen);
}
}
-----------------------------------------------------------------------
//Program to read the single word from keyboard
import java.util.*;
public class ReadName
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter your name :");
String name = sc.nextLine();
System.out.println("You name is :"+name);
}
}
-----------------------------------------------------------------------
//Buffer Problem
package com.ravi.reading_data;

import java.util.Scanner;

public class EmployeeData {

public static void main(String[] args)


{
Scanner sc = new Scanner(System.in);

System.out.print("Enter Employee Id :");


int eno = sc.nextInt();

System.out.print("Enter Employee Name :");


String name = sc.nextLine(); //Buffer Problem
name = sc.nextLine();

System.out.println("EMPLOYEE DATA");
System.out.println("Employee Id is :"+eno);
System.out.println("Employee Name is :"+name);
sc.close();
}

}
-----------------------------------------------------------------------//Arithmetic Operator (+, -, *, / , %)
//Reverse of a 3 digit number
import java.util.*;
public class Test3
{
public static void main(String[] args)
{
System.out.print("Enter a three digit number :");
Scanner sc = new Scanner(System.in);

int num = sc.nextInt(); //num = 567

int rem = num % 10; //rem = 7


System.out.print("The Reverse is :"+rem); //The reverse is :765

num = num /10; //num = 56


rem = num % 10; //rem = 6
System.out.print(rem);

num = num/10; //num = 5


System.out.println(num);
}
}
-----------------------------------------------------------------------
Unary Operator :
----------------
The operator which works on single operand.

We have so many unary operators in java.

1) Unary minus operator (-)


2) Increment Operator(++)
3) Decrement Operator(--)

//*Unary Operators (Acts on only one operand)


//Unary minus Operator
class Test4
{
public static void main(String[] args)
{
int x = 15;
System.out.println(-x);
System.out.println(-(-x));
}
}
-----------------------------------------------------------------
14-11-2023
----------
//Unary Operators
//Unary Pre increment Operator
class Test5
{
public static void main(String[] args)
{
int x = 15;
int y = ++x; //First increment then assignment
System.out.println(x+":"+y);
}
}
-----------------------------------------------------------------
//Unary Operators
//Unary Post increment Operator
class Test6
{
public static void main(String[] args)
{
int x = 15;
int y = x++; //First assignment then increment
System.out.println(x+":"+y);
}
}
------------------------------------------------------------------
//Unary Operators
//Unary Pre increment Operator
class Test7
{
public static void main(String[] args)
{
int x = 15;
int y = ++15; //error
System.out.println(y);
}
}
-----------------------------------------------------------------
//Unary Operators
//Unary Pre increment Operator
class Test8
{
public static void main(String[] args)
{
int x = 15;
int y = ++(++x); //error
System.out.println(y);
}
}

Note :- Increment and Decrement Operator can work with any data type except boolean.
-----------------------------------------------------------------
//Unary Operators
//Unary post increment Operator
class Test9
{
public static void main(String[] args)
{
int x = 15;
System.out.println(++x + x++); //32
System.out.println(x); //17
System.out.println("..................");

int y = 15;
System.out.println(++y + ++y); //33
System.out.println(y); //17
}
}

------------------------------------------------------------------
//Unary Operators
//Unary post increment Operator
class Test10
{
public static void main(String[] args)
{
char ch =’A’;
ch++;
System.out.println(ch);
}
}
------------------------------------------------------------------
//Unary Operators
//Unary post increment Operator
class Test11
{
public static void main(String[] args)
{
double d = 15.15;
d++;
System.out.println(d);
}

Note :- Increment and decrement operator we can apply with any data type except boolean.
-----------------------------------------------------------------
//Unary Operators
//Unary Pre decrement Operator
class Test12
{
public static void main(String[] args)
{
int x = 15;
int y = --x; //First decrement then assignment
System.out.println(x+":"+y);
}
}
-----------------------------------------------------------------
//Unary Operators
//Unary Post decrement Operator
class Test13
{
public static void main(String[] args)
{
int x = 15;
int y = x--;
System.out.println(x+":"+y);
}
}
-----------------------------------------------------------------
Interview Question
----------------------
Whenever we work with Arithmetic Operator and Unary minus operator, the minimum data type required
is int, So after calculation of expression it is promoted to int type.

//IQ
class Test14
{
public static void main(String args[])
{
byte i = 1;
byte j = 1;
byte k = i + j; //error
System.out.println(k);
}
}
------------------------------------------------------------------
class Test15
{
public static void main(String args[])
{
/*short b = 6;
b = b + 7; //error
System.out.println(b); */
byte b = 6;
b += 7;//short hand operator b += 7 is equal to (b = b + 7)
System.out.println(b);
}
}

Note :- From the above program it is clear that with Arithmetic Operator we need int as a minimum data
type but the same rule is not applicable
for short hand operator.
------------------------------------------------------------------
class Test16
{
public static void main(String args[])
{
byte b = 1;
byte b1 = -b; //error
System.out.println(b1);
}
}
-----------------------------------------------------------------
What is a local variable :
----------------------------
If a variable is declared inside a method body not as a method parameter then it is called Local / Stack/
Temporary / Automatic variable.

Ex:-

public void input()


{
int y = 12;
}

Here in the above example y is local variable.

Local variable we can’t use outside of the function or method.

A local variable must be initialized before use otherwise we wiil get compilation error.

We can’t use any access modifier on local variable except final.

Program
---------
public class Test17
{
public static void main(String [] args)
{
private int x = 100;//error
System.out.println(x);

int y;
System.out.println(y); //error
}
}
Note :- All the local variables are executed inside the method with the help of STACK MEMORY (LIFO)
----------------------------------------------------------------------
//Program to describe that methods are executed as a part of STACK Memory

public class StackMemory


{
public static void main(String [] args)
{
System.out.println("Main method started..");
m1();
System.out.println("Main method ended..");
}

public static void m1()


{
System.out.println("M1 method started..");
m2();
System.out.println("M1 method ended..");
}

public static void m2()


{
int x = 100;
System.out.println("I am m2 method..");
}
}
NOTE :- THIS PROGRAM CONTAINS DIAGRAM(14-NOV-23)

From the above program it is also clear that we cannot use our local variables outside of the method
because once method execution is over it will be deleted from Stack Frame as shown in the diagram
(14-Nov)
-------------------------------------------------------------------------
24-11-2023
------------
3) Assignment Operator :
------------------------
-> It is used to assign the value to an identifier. We use = operator for assignment.

//*Program on Assignment Operator


class Test18
{
public static void main(String args[])
{
int x = 5, y = 3;
System.out.println("x = " + x);
System.out.println("y = " + y);

x %= y; //short hand operator x = x % y


System.out.println("x = " + x);
}
}
----------------------------------------------------------------------
Relational Operator :-
------------------------
These operators are used to compare the values. The return type is boolean. We have total 6 Ralational
Operators.

1) > (Greater than)

2) < (Less than)

3) >= (Greater than or equal to)

4) <= (Less than or equal to)

5) == (double equal to)

6) != (Not equal to )

---------------------------------------------------------------------
//*Program on relational operator(6 Operators)
class Test19
{
public static void main(String args[])
{
int a = 10;
int b = 20;
System.out.println("a == b : " + (a == b) ); //false
System.out.println("a != b : " + (a != b) ); //true
System.out.println("a > b : " + (a > b) ); //false
System.out.println("a < b : " + (a < b) ); //true
System.out.println("b >= a : " + (b >= a) ); //true
System.out.println("b <= a : " + (b <= a) ); //false
}
}
---------------------------------------------------------------------
If condition :
---------------
It is decision making statement. It is used to test a boolean expression. The expression must return
boolean type.

//Program to check a number is 0 or +ve or -ve


import java.util.Scanner;
class Test20
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
System.out.print("Please enter a Number :");

int num = sc.nextInt();


if(num == 0)
System.out.println("It is zero");

else if(num>0)
System.out.println(num+" is positive");
else
System.out.println(num+" is negative");

sc.close(); //To close Scanner resource


}
}
----------------------------------------------------------------------
/*program to calculate telephone bill
For 100 free call rental = 360
For 101 - 250, 1 Rs per call
For 251 - unlimited , 1.2 Rs per call
*/
import java.util.*;
class Test21
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter current Reading :");
int curr_read = sc.nextInt();

System.out.print("Enter Previous Reading :");


int prev_read = sc.nextInt();

int nc = curr_read - prev_read;


System.out.println("Your Number of call for this month is :"+nc);

double bill = 0.0;


if (nc <=100)
{
bill = 360;
}
else if(nc<=250)
{
bill = 360 + (nc-100)*1.0;
}
else if(nc >250)
{
bill = 360 + 150 + (nc-250)*1.2;
}
System.out.println("The bill is :"+bill);
}
}
----------------------------------------------------------------------
Nested if:
---------
If an ’if condition’ is placed inside another if condition then it is called Nested if.
In nested if condition, we have one outer if and one inner if condition, the inner if condition will only
execute when outer if condition returns true.

if(condition) //Outer if condition


{
if(condition) //inner if condition
{
}
else //inner else
{
}
}
else //outer else
{
}
---------------------------------------------------------------------
//Nested if
//Program to find out big among three number
class Test22
{
public static void main(String args[])
{
int a =25;
int b =22;
int c =18;

int big=0;

if(a>b) //(Outer if condition)


{
if(a>c) //Nested If Block (inner if)
big=a;
else
big=c;
}
else //already confirmed b is greater than a
{
if(b>c)
big=b;
else
big=c;
}
System.out.println("The big number is :"+big);
}
}

Note :- In the above program to find out the biggest number among three numbers we need to take the
help of nested if condition but the code becomes complex, to reduce the length of the code Logical
Operator came into the picture.
---------------------------------------------------------------------
Logical Operator :-
--------------------
It is used to combine or join the multiple conditions into a single statement.
It is also known as short-Circuit logical operator.
In Java we have 3 logical Operators

1) && (AND Logical Operator)

2) || (OR Logical Operator)

3) ! (NOT Logical Operator)

&& :- All the conditions must be true. if the first expression is false it will not check right side
expressions.

|| :- Among multiple conditions, at least one condition must be true. if the first expression is true it will
not check right side expressions.
! :- It is an inverter, it makes true as a false and false as a true.

Note :- The && and || operator only works with boolean operand so the following code will not compile.

if(5 && 6)
{

}
---------------------------------------------------------------------
//*Program on Logical Operator (AND, OR, Not Operator)
//Biggest number among 3 numbers

class Test23
{
public static void main(String args[])
{
java.util.Scanner sc = new java.util.Scanner(java.lang.System.in);
System.out.print("Enter the value of a :");
int a = sc.nextInt();
System.out.print("Enter the value of b :");
int b = sc.nextInt();
System.out.print("Enter the value of c :");
int c = sc.nextInt();

int big =0;

if(a>b && a>c)


big = a;
else if(b>a && b>c)
big = b;
else
big = c;
System.out.println("The big number is :"+big);
}
}
----------------------------------------------------------------------
//OR Operator (At least one condition must be true)
class Test24
{
public static void main(String args[])
{
int a=10;
int b=5;
int c=20;
System.out.println(a>b || a<c); //true
System.out.println(b>c || a>c); //false
}
}
---------------------------------------------------------------------
// !Operator (not Operator works like an Inverter)
class Test25
{
public static void main(String args[])
{
System.out.println(!true);
}
}
---------------------------------------------------------------------
06-Jul-23
---------
Boolean Operators :
-----------------------
Boolean Operators work with boolean values that is true and false. It is used to perform boolean logic
upon two boolean expressions.
It is also known as non short circuit. There are two non short circuit logical operators.

& boolean AND operator (All condions must be true but if first expression is false still it will check all
right side expression)

| boolean OR operator (At least one condition must be true but if the first condition is true still it will
check all right side expression )
---------------------------------------------------------------------
//* Boolean Operators
/*
& boolean AND operator
| boolean OR operator
*/
//Works with boolean values

class Test26
{
public static void main(String[] args)
{
int z = 5;
if(++z > 5 || ++z > 6) //Logical OR
{
z++;
}
System.out.println(z); //7

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

z = 5;
if(++z > 5 | ++z > 6) //Boolean OR
{
z++;
}
System.out.println(z); //8
}
}
----------------------------------------------------------------------
class Test27
{
public static void main(String[] args)
{
int z = 5;
if(++z > 6 & ++z> 6)
{
z++;
}
System.out.println(z);
}
}
----------------------------------------------------------------------
Bitwise Operator :-
---------------------
In order to work with binary bits java software people has provided Bitwise operator. It also contains 3
operators

& (Bitwise AND) :- Returns true if both the inputs are true.

| (Bitwise OR) :- Returns false if both the inputs are false

^ (Bitwise X-OR) :- Returns true if both the arguments are opposite to each other.
---------------------------------------------------------------------
//Bitwise Operator
class Test28
{
public static void main(String[] args)
{
System.out.println(true & true); //true
System.out.println(false | true); //true
System.out.println(false ^ true); //true

System.out.println(6 & 7); //6


System.out.println(6 | 7); //7
System.out.println(6 ^ 7); //1
}
}
----------------------------------------------------------------------
//Bitwise Complement Operator
public class Test29
{
public static void main(String args[])
{
//System.out.println(~ true); //Invalid
System.out.println(~ -7);
System.out.println(~ 6);
}
}
----------------------------------------------------------------------
Ternary Operator OR Conditional Operator :
--------------------------------------------------
The ternary operator (? :) consists of three operands. It is used to evaluate boolean expressions. The
operator decides which value will be assigned to the variable.It is used to reduced the size of if-else
condition.

//Ternary Operator OR Conditional Operator


public class Test30
{
public static void main(String args[])
{
int a = 60;
int b = 69;
int max = 0;

max=(a>b)?a:b; //Type casting


System.out.println("Max number is :"+max);
}
}
---------------------------------------------------------------------
class Test
{
public static void main(String[] args)
{
char a = ’A’;
float i = 65 ;
System.out.println(false ? i : a); //Type casting
System.out.println(true ? a : 65);
}
}
-----------------------------------------------------------------------
25-11-2023
-----------
Member access Operator Or Dot Operator :
--------------------------------------------------
It is used to access the member of the class so whenever we want to invoke(call) the member of the class
(fields + methods) then we should use dot(.) operator.

Some important points :


-----------------------
a) From our main method (static method) we can’t call non-static member i.e non-static variable and
non-static method, Here Object is required otherwise we will get error as shown in the program below

public class Test


{
int x = 100; //Non-static variable

public void m1() //Non-static method


{
System.out.println("Non static member m1");
}

public static void main(String[] args)


{
System.out.println("x value is :"+x); //error
m1(); //error
}
}

b) From our main method (static method) we can directly call (Without class name) static variable and
static method but they must be defined within the same class only as shown in the program below.

public class Test


{
static int x = 100; //static variable

public static void m1() //static method


{
System.out.println("Non static member m1");
}

public static void main(String[] args)


{
System.out.println("x value is :"+x);
m1();
}
}

c) We can directly call (With the help of class name) any static method and static variable avaibale in
another class from the main method, here object is not required as shown in the program below.

class Welcome
{
static int x = 100;

public static void m1()


{
System.out.println("Non static member m1");
}
}

public class Test


{
public static void main(String[] args)
{
System.out.println("x value is :"+Welcome.x);
Welcome.m1();
}
}
-----------------------------------------------------------------------
new Operator
-------------
This Operator is used to create Object. If the member of the class (field + method) is static, object is not
required. we can directly call with the help of class name.

On the other hand if the member of the class (variables + method) is not declared as static then it is called
non-static member Or instance member , to call the non-static member object is required.

class Welcome
{
int x = 100; //instance variable (non-static variable)

public void m1() //instance method (non-static method)


{
System.out.println("Non static member m1");
}
}
public class Test
{
public static void main(String[] args)
{
Welcome w = new Welcome();
System.out.println("x value is :"+w.x);
w.m1();
}
}

--------------------------------------------------------------------
The conclusion is if our member of the class is static then object is not required, on the other hand if the
member of the class is
non-static then object is required.
--------------------------------------------------------------------

instanceof operator :
---------------------

1)This Operator will return true/false

2) It is used to check whether a reference variable is holding the particular/corresponding type of Object
or not.

3) It is also a keyword.

4) In between the object reference and class name , we must have some kind of relation (assignment
relation) otherwise we will get compilation error.

//Program on instanceof operator


---------------------------------
public class Test
{
public static void main(String[] args)
{
Test t1 = new Test();

if(t1 instanceof Test)


{
System.out.println("t1 is pointing to Test Object");
}

Integer i = 24;

if(i instanceof Number) //Number is the super class of Integer


{
System.out.println("i is pointing to Integer Object");
}
else
{
System.out.println("i is not pointing to Integer Object");
}
}
}
-------------------------------------------------------------------
Drawback of if condition :
--------------------------
The major drawback with if condition is, the CPU has to check the condition again and again so the
performance of CPU will be decreased, to avoid this we introduced switch case statement.

switch case :
--------------
It is a selection statement, based on the availabe cases the appropriate case will be executed otherwise
default will be executed.

break keyword is optional.

In switch statement we cannot pass long, float and double.

Strings are allowed from java 7v onwards as well as enums are allowed from java 5v.

import java.util.*;
public class SwitchDemo
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Please Enter a Character :");

char colour = sc.next().toLowerCase().charAt(0);

switch(colour)
{
case ’r’ : System.out.println("Red") ; break;
case ’g’ : System.out.println("Green");break;
case ’b’ : System.out.println("Blue"); break;
case ’w’ : System.out.println("White"); break;
default : System.out.println("No colour");
}
System.out.println("Completed") ;
}
}
-------------------------------------------------------------------------
import java.util.*;
public class SwitchDemo1
{
public static void main(String args[])
{
System.out.println("\t\t**Main Menu**\n");
System.out.println("\t\t**100 Police**\n");
System.out.println("\t\t**101 Fire**\n");
System.out.println("\t\t**102 Ambulance**\n");
System.out.println("\t\t**139 Railway**\n");
System.out.println("\t\t**181 Women’s Helpline**\n");

System.out.print("Enter your choice :");


Scanner sc = new Scanner(System.in);
int choice = sc.nextInt();

switch(choice)
{
case 100:
System.out.println("Police Services");
break;
case 101:
System.out.println("Fire Services");
break;
case 102:
System.out.println("Ambulance Services");
break;
case 139:
System.out.println("Railway Enquiry");
break;
case 181:
System.out.println("Women’s Helpline ");
break;
default:
System.out.println("Your choice is wrong");
}
}
}
-------------------------------------------------------------------------
import java.util.*;
public class SwitchDemo2
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter the name of the season :");
String season = sc.next().toLowerCase();

switch(season)
{
case "summer" :
System.out.println("It is summer Season!!");
break;

case "rainy" :
System.out.println("It is Rainy Season!!");
break;
}
}
}
-------------------------------------------------------------------------

public class Test2


{
public static void main(String[] args)
{
double val = 1;
switch(val) //Error, can’t pass long, float and double
{
case 1:
System.out.println("Hello");
break;
}
}
}
--------------------------------------------------------------------------
Loop in java :
---------------
A loop is nothing but repetation of statement based on the condition.

In java we have 4 types of loop

1) Do-while loop (Exit control loop)


2) While loop(Entry control loop)
3) For loop
4) For-each loop(Enhanced for loop)

Program on do-while loop :


--------------------------
public class Test
{
public static void main(String[] args)
{
do
{
int x = 1; //block level variable
System.out.println(x);
x++;
}
while (x<=10); //error
}
}

Note : The program will generate compilation error because x is block level variable and we cannot use x
outside of the block.
--------------------------------------------------------------------------
public class Test
{
public static void main(String[] args)
{
int x = 1; //local variable
do
{
System.out.println(x);
x++;
}
while (x<=10);
}
}
-------------------------------------------------------------------------
Program on while loop :
-----------------------
class WhileLoop
{
public static void main(String[] args)
{
int x = 0;

while(x>=-10)
{
System.out.println(x);
x--;
}
}
}
--------------------------------------------------------------------------
Program on for loop :
----------------------
public class Test
{
public static void main(String[] args)
{
for(int i =1; i<=10; i++)
{
System.out.println(i);
}
}
}
--------------------------------------------------------------------------
For Each loop :
---------------
-> It is an enhanced for loop which came from java 1.5 onwards.
-> The main purpose of this loop to fetch the values from Collection.

public class Test


{
public static void main(String[] args)
{
int []x = {67, 45, 23, 15};
java.util.Arrays.sort(x);

for(int y : x)
{
System.out.println(y);
}

String []fruits = {"Orange", "Mango", "Apple"};

java.util.Arrays.sort(fruits);

for(String fruit : fruits)


{
System.out.println(fruit);
}
}
}

In java.util package there is a predefined class called Arrays which contains static method sort() through
which we can sort an array variable in ascending order.
-------------------------------------------------------------------------
27-11-2023
----------
Method and Parameter :
----------------------
This package contains two files :(Method return type as String)
---------------------------------------------------------------
package com.ravi.method;

//BLC
public class Student
{
public static String getStudentDetails(int sno, String sname, double fees)
{
return " Roll is :"+sno+" sname is :"+sname+" fees is :"+fees;
}
}

StudentDataConcatenation.java
------------------------------
package com.ravi.method;

//ELC
public class StudentDataConcatenation
{
public static void main(String[] args)
{
String details = Student.getStudentDetails(101, "ABC", 12000);
System.out.println(details);
}

}
-------------------------------------------------------------------------
Types of variables in Java :
---------------------------
In java based on the data type we have only 2 types of variables :

1) Primitive Type

Example :- byte, short, int and so on

2) Non-primitive type (Reference type)

Employee e1 = new Employee();


e1 is a reference variable.

Based on the declaration position, it is further classified into 4 categories

a) Class variable OR Static Field


b) Instance variable OR Non-static Field
c) Parameter Variable
d) Local Variable (Block level Variable)
Program on Primitive Variable :
-------------------------------
package com.ravi.method;

public class PrimitiveVariable


{
int a = 100; //Instance Variable OR Non-static Field
static int b = 200; //Class Variable OR static Field

public static void main(String[] args)


{
PrimitiveVariable pv = new PrimitiveVariable();
System.out.println("Instance variable :"+pv.a);
System.out.println("Class Variable :"+PrimitiveVariable.b);
int d = 400;
System.out.println("Local variable :"+d);
acceptData(300);
}

public static void acceptData(int c) //c is parameter variable


{
System.out.println("Parameter variable :"+c);
}

Program on Reference Variable :


-------------------------------
package com.ravi.method;

import java.util.Scanner;

class Test
{
public void m1()
{
System.out.println("Test class m1 method");
}
}

public class ReferenceVariable


{
Test t1 = new Test(); //Instance Variable (Reference variable)

static Scanner sc = new Scanner(System.in); //Class Variable

public static void main(String[] args)


{
Test t2 = new Test(); // Local Reference variable

acceptData(t2);
}

public static void acceptData(Test t3) //t3 is parameter variable


{
t3.m1();
}

}
-------------------------------------------------------------------------
Object Oriented Programming (OOPs):
----------------------------------
It is a methodology to develop or design the programs by using class and Object.

What is an Object ?
-------------------
An Object is a physical Entity which is existing in the real world.
Example :- Pen, Car, Laptop, Fan

Writing Program on these real life object is known Object Oriented Programming.

In OOP, We concentrate on objects where as in POP we concentrate on Function.

An Object is having 3 characteristics :


---------------------------------------
1) Identity (Name of the Object)
2) State (Data OR Variable of the Object) [OOP = Properties]
3) Behavior (Function/Method of the Object)

Advantages Of OOP :
-------------------
There are 3 advantages of OOP

a) Modularity (Dividing the bigger task into number of smaller tasks)


b) Reusability (We can reuse a particular module so many times)
c) Flexibility (Easy maintainence)

Features of OOP :
------------------
There are 6 features of OOP :

1) Class
2) Object
3) Abstraction
4) Encapsulation
5) Inheritance
6) Polymorphism

What is a class?
----------------
A class is a model/blueprint/template/prototype for creating an object.

A class is a user-defined data type which contains data member and member function.

Example :

public class Student


{
student data (Properties)
+
Student behavior (Function)
}

A class is logical entity which does not take any space.

A CLASS IS A COMPONENT WHICH IS USED TO DEFINE OBJECT PROPERTIES AND


OBJECT BEHAVIOR.

Student.java
------------
package com.ravi.oop;

public class Student


{
String regNo;
String name;

public void talk()


{
System.out.println("My Registration no is :"+regNo);
System.out.println("My Name is :"+name);
}

public String writeExam()


{
return "My name is :"+name+" and every Saturday I am writing Java exam";
}

public static void main(String[] args)


{
Student raj = new Student();
//Initializing the raj student proprties
raj.regNo = "NIT23001";
raj.name = "Raj Gourav";

//Calling the behavior


raj.talk();
String data = raj.writeExam();
System.out.println(data);

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

Student priya = new Student();


//Initializing the priya student proprties
priya.regNo = "NIT23002";
priya.name = "Priya Kumari";
//Calling the behavior
priya.talk();
data = priya.writeExam();
System.out.println(data);

}
}
--------------------------------------------------------------------------
WAP to implement OOP using Customer object

package com.ravi.oop;

public class Customer


{
//Properties
int customerId;
String customerName;
double customerBill;

//Behavior
public void getCustomerInformation()
{
System.out.println("Id is :"+customerId);
System.out.println("Name is :"+customerName);
System.out.println("Bill is :"+customerBill);
}

public static void main(String[] args)


{
Customer ram = new Customer();

//Initializing the properties


ram.customerId = 001;
ram.customerName = "Ram kumar";
ram.customerBill = 23456.90;

//calling the behavior


ram.getCustomerInformation();

}
-------------------------------------------------------------------------
Difference among class, object and instance
-------------------------------------------
Class :- Logical Entity

Object :- Physical Entity

Instance :- The way of creating object is called Instance.

--------------------------------------------------------------------------
Default constructor added by compiler :
---------------------------------------
What is Constructor (Introduction)
----------------------------------
If the name of the class and name of the method both are exactly same as well as it does not contain any
return type then it is called Constructor.
Example :-
----------
class Student
{
public Student() //constructor
{
}
}

In Java, whenever we write a class and if don’t write any type of constructor in that class then
automatically one default constructor will be added by compiler.

Evary java class must contain at-least one constructor either explicitly written by user or implicitly added
by compiler.

The access modifier of defualt constructor depends upon class access


modifier.

Example :
-----------
class Student
{
}

javac Student.java (Compilation) javap Student.class(To see the default


constructor)

class Student
{
Student() //default constructor added by the compiler
{
}
}
-------------------------------------------------------------------------
Why compiler is adding default constructor to our class :
---------------------------------------------------------
We have 2 reasons that why compiler is adding default constructor :

1) Without default constructor, Object creation is not possible in java.


2) default constructor will initialize all the instance variables with
default values.

Data type - Default value


byte - 0
short - 0
int - 0
long - 0
float - 0.0
double - 0.0
char - (space)
boolean - false
String - null
Object - null (For ant class i.e reference variable the default value
is null)
-----------------------------------------------------------------------
WAP that describes default values will be provided by default constructor for instance variables

Student.java
-------------
package com.ravi.oop;

public class Student


{
int studentNumber;
String studentName;

public void showStudentData()


{
System.out.println(studentNumber);
System.out.println(studentName);
}

public static void main(String[] args)


{
Student raj = new Student();
raj.showStudentData();
}

}
-----------------------------------------------------------------------
How to provide userdefined values for the instance variable :
-------------------------------------------------------------
The default constructor added by the compiler will provide the default values for the instance variable, but
these default values are not useful for the user so, user will take a separate method setEmployeeData() to
re-initialize the instance variable according to his/her choice as shown in the program.

Employee.java
--------------

package com.ravi.oop;

public class Employee


{
int employeeId;
String employeeName;

public void setEmployeeData()


{
employeeId = 111;
employeeName = "Ravi";
}

public void getEmployeeData()


{
System.out.println("Employee Id is :"+employeeId);
System.out.println("Employee Name is :"+employeeName);
}

public static void main(String[] args)


{
Employee raj = new Employee();
raj.getEmployeeData(); //0 and null

raj.setEmployeeData();
raj.getEmployeeData(); // 111 and Ravi
}
}
-----------------------------------------------------------------------
How to take the input from the user to initailize my instance variable :
------------------------------------------------------------------------
Manager.java
-------------
package com.ravi.oop;

import java.util.Scanner;

public class Manager


{
int managerId;
double managerSalary;

public void setManagerData()


{
Scanner sc = new Scanner(System.in);
System.out.print("Enter Manager id :");
managerId = sc.nextInt();
System.out.print("Enter Manager Salary :");
managerSalary = sc.nextDouble();
sc.close();

}
public void getManagerData()
{
System.out.println("Manager id is :"+managerId);
System.out.println("Manager Salary is :"+managerSalary);
}

public static void main(String[] args)


{
Manager sneha = new Manager();
sneha.setManagerData();
sneha.getManagerData();
}

Instance variable :
-------------------
If a non static variable is declared inside the class but outside of the method then it is called Instance
variable.

As far as its accessibility is concerned, it is accessible within the same class as well as outside of the
class also depending upon access modifier.
Instance variables are created at the time of object creation.[Instance variables are always the part of the
object only]

Parameter Variable :
---------------------
If a variable is declared inside a method parameter (not inside a method body) then it will become
parameter variable.

As far as its accessibility is concerned, it is accessible within the same method only.
------------------------------------------------------------------------
How to write OOP using BLC and ELC :
------------------------------------
If we write everything in a single class then it is not an Object Oriented Programming approach even we
are creating Object.

In this approach, the re-usability of BLC class is not possible.

In a single Java file we can declare only one public class, remaining all the classes declared inside that
file must be non-public so, re-usability of these classes will not possible.
[5 classes = 5 java files]

In this package we have 2 files :


----------------------------------
Player.java
------------
package com.ravi.blc_elc;

//BLC
public class Player
{
int playerId;
String playerName;

public void setPlayerData(int id, String name)


{
playerId = id;
playerName = name;
}

public void getPlayerData()


{
System.out.println("Player id is :"+playerId);
System.out.println("Player name is :"+playerName);
}

Rohit.java [It is available in the same package]


-----------
package com.ravi.blc_elc;

public class Rohit


{
public static void main(String[] args)
{
Player rohit = new Player();
rohit.setPlayerData(45, "Rohit Sharma");
rohit.getPlayerData();

Virat.java [It is available in another Package]


--------------

package com.ravi.oop;

import com.ravi.blc_elc.Player;

public class Virat


{
public static void main(String[] args)
{
Player virat = new Player();
virat.setPlayerData(18, "Virat Kohli");
virat.getPlayerData();
}

From the above program it is clear that we can re-use Our Player class from the same package or even
from the another package.
------------------------------------------------------------------------
01-12-2023
----------
this keyword :
--------------
Whenever instance variable name and parameter variable name both are same then at the time of
variable initialization our runtime environment gets confused that which one is instance variable and
which one is parameter variable.

To avoid the above said problen, Java software people introduced "this"
keyword.

this keyword always refers to the current object and instance variables are the part of the object so by
using this keyword we can refer to instance variable.

We cannot use this keyword from static area (Static context).

We have 2 files :
------------------
Customer.java
--------------
package com.ravi.this_keyword;
//BLC
public class Customer
{
int customerId;
String customerName;

public void setCustomerData(int customerId, String customerName)


{
this.customerId = customerId;
this.customerName = customerName;

public void getCustomerData()


{
System.out.println("Customer id is :"+customerId);
System.out.println("Customer Name is :"+customerName);
}

CustomerDemo.java
-----------------
package com.ravi.this_keyword;
//ELC
public class CustomerDemo
{
public static void main(String[] args)
{
Customer raj = new Customer();
raj.setCustomerData(111, "Raj Gourav");
raj.getCustomerData();
}

}
------------------------------------------------------------------------
Role of instance variable while creating the Object :
-----------------------------------------------------
Whenever we create an Object in java, a separate copy of all the instance variables will be created for
each and every object.

package com.ravi.this_keyword;

public class Test


{
int x = 10;

public static void main(String [] args)


{
Test t1 = new Test();
Test t2 = new Test();
++t1.x;
--t2.x;

System.out.println(t1.x);
System.out.println(t2.x);
}
}
-----------------------------------------------------------------------
Role of static variable while creating the Object :
-----------------------------------------------------
Whenever we create an object, a single copy of static variable will be created and this single copy will be
sharable by all the objects.

package com.ravi.this_keyword;

public class Demo


{
static int x = 10;

public static void main(String[] args)


{
Demo d1 = new Demo();
Demo d2 = new Demo();

--d1.x; --d2.x;

System.out.println(d1.x); //8
System.out.println(d2.x);//8
}

Note :
-------
Instance variable = Multiple copies with multiple objects
Class Variable = Single Copy for all the Objects.
-----------------------------------------------------------------------
When we should declare instance variable and when we should declare static variable?

If the value of the variable is different with respect to object then we should declare instance variable on
the other hand if the value of the
variable will be common for all the objects then we should declare class variable (Static field).

public class Student


{
int sno;
String sname;
String address;
static String collegeName = "NIT";
static String courseName = "java";
}
------------------------------------------------------------------------
02-12-2023
-----------
Program that describes when to declare instance variable and when to declare class variable
2 Files :
----------
Student.java
-------------
package com.ravi.instance_static;

public class Student


{
int rollNumber;
String studentName;
String studentAddress;
static String collegeName = "NIT";
static String courseName = "Java";

public void setStudentData(int rollNumber, String studentName, String studentAddress)


{
this.rollNumber = rollNumber;
this.studentName = studentName;
this.studentAddress = studentAddress;
}

public void getStudentData()


{
System.out.println("Roll Number is :"+rollNumber);
System.out.println("Name is :"+studentName);
System.out.println("Address is :"+studentAddress);
System.out.println("College Name is :"+Student.collegeName);
System.out.println("Course Name is :"+Student.courseName);
}
}

StudentDemo.java
-----------------
package com.ravi.instance_static;

public class StudentDemo {

public static void main(String[] args)


{
Student s1 = new Student();
s1.setStudentData(111, "ABC", "Ameerpet");
s1.getStudentData();
System.out.println("...........");
Student s2 = new Student();
s2.setStudentData(222, "DEF", "S.R Nagar");
s2.getStudentData();
}

}
------------------------------------------------------------------------
How to print object properties ?
---------------------------------
If we want to print our object properties then we should generate(override) toString() method in our class
from Object class.
In order to generate the toString() method we need to follow the steps
Right click on the program -> source -> generate toString()

In order to call this toString() method, we need to print the corresponding object reference by using
System.out.println() statement.

Manager m = new Manager();


System.out.println(m); //Calling toString() method of Manager class

Employee e = new Employee();


System.out.println(e); //Calling toString() method of Employee class

2 files in this program :


-------------------------
Manager.java
------------
package com.ravi.to_string;

public class Manager


{
int managerId;
String managerName;
String managerAddress;
double managerSalary;

public void setManagerData(int id, String name, String addr,double salary)


{
this.managerId = id;
this.managerName = name;
this.managerAddress = addr;
this.managerSalary = salary;
}

@Override
public String toString()
{
return "Manager [managerId=" + managerId + ", managerName=" + managerName + ",
managerAddress=" + managerAddress
+ ", managerSalary=" + managerSalary + "]";
}

ManagerDemo.java
------------------
package com.ravi.to_string;

public class ManagerDemo {

public static void main(String[] args)


{
Manager m1 = new Manager();
m1.setManagerData(1, "Raj", "AMPT", 120000);
System.out.println(m1); //toString()

}
------------------------------------------------------------------------
Data Hiding :
-------------
Data hiding is nothing but declaring our data members with private access modifier so our data will not be
accessible from outer world that means no one can access our data directly.

We should provide the accessibility of our data through methods so we can perform VALIDATION ON
DATA which are coming from outer world.

This program contains 2 files :


--------------------------------
Customer.java
--------------
package com.ravi.data_hiding;

//BLC
public class Customer
{
private double balance = 1000; //Data Hiding

public void deposit(int amount)


{
//Validation
if(amount <=0)
{
System.out.println("Amount can’t be deposited");
}
else
{
balance = balance + amount;
System.out.println("Available balance is :"+balance);
}
}

public void withdraw(int amount)


{
balance = balance - amount;
System.out.println("Available balance is :"+balance);
}
}

BankingApplication.java
-------------------------
package com.ravi.data_hiding;

public class BankingApplication


{
public static void main(String[] args)
{
Customer hacker = new Customer();
hacker.deposit(5000);
hacker.withdraw(2000);

}
------------------------------------------------------------------------
Lab Program :
-------------
2 files :

Employee.java
--------------
package com.ravi.lab;

public class Employee


{
private int empId;
private String empName;
private double empSalary;
private char empGrade;

public void setEmployeeData(int id, String name, double salary)


{
this.empId = id;
this.empName = name;
this.empSalary = salary;
}

public void calculateEmployeeGrade()


{
if(this.empSalary >= 100000)
{
empGrade = ’A’;
}
else if(this.empSalary >=75000)
{
empGrade = ’B’;
}
else if(this.empSalary >=50000)
{
empGrade = ’C’;
}
else
{
empGrade = ’D’;
}
}

@Override
public String toString()
{
return "Employee [empId=" + empId + ", empName=" + empName + ", empSalary=" + empSalary + ",
empGrade=" + empGrade
+ "]";
}

EmployeeDemo.java
------------------

package com.ravi.lab;

public class EmployeeDemo {

public static void main(String[] args)


{
Employee e1 = new Employee();
e1.setEmployeeData(1, "Virat", 40000);
e1.calculateEmployeeGrade();
System.out.println(e1);

}
-----------------------------------------------------------------------
04-12-2023
----------
Abstraction :
-------------
Showing the essential details without showing the background details is called abstraction.

In our real world a user always interacts with functionality of the product but not the data so as a
developer we should hide the data from end user by declaring them private.

On the other hand the function must be declared as public so our end user witll interact with the
function/method.

In Java we can achieve abstraction by using two ways :

1) Abstract class and abstract methods :- By using abstract class and


abstract method we can achieve abstraction 0 to 100%

2) By using interface :- By using interface we can achieve 100%


abstraction.

Example of Abstract class :-


----------------------------
package com.ravi.m2;

public abstract class Lift


{
public abstract void keyOne();
public abstract void keyTwo();
public abstract void keyThree();
public abstract void keyFour();

public void liftInformation()


{
System.out.println("Lift information");
}
}

Example of interface :-
---------------------
package com.ravi.m2;

public interface SteelLift


{
public void keyOne();
public void keyTwo();
public void keyThree();
public void keyFour();

}
------------------------------------------------------------------------
Constructor :
------------

What is the advantage of Writing constructor in our program :


-------------------------------------------------------------

If we don’t write a constructor in our program then variable initialization and variable re-initialization both
are done in two different lines.

If we write constructor in our program then variable initialization and variable re-initialization both are done
in the same line i.e at the time of Object creation.

[Diagram 04-DEC-23]
------------------------------------------------------------------------
Constructor :
--------------
It is used to construct the object so it is called Constructor.

If the name of the class and name of the method both are exactly same and it should not contain any
return type then it is called Constructor.

*The main purpose of constructor to initialize the instance variable of the class.

Every class in Java must contain at least one constructor, either implicitly added by compiler or explicitly
written by user.

By default, Constructor never contain any return type but internally it is returning the current class object
(this keyword)

public class Student


{
private int roll;

public int getData()


{
return this.roll;
}

public static void main(String[] args)


{
int data = new Student().getData();
System.out.println(data);
}
}

A constructor is automatically called and executed at the time of creating the object.

In Java we have 3 types of Constructors :


------------------------------------------
1) Default constructor.
2) No Argument Constructor OR Zero-Argument Constructor OR Parameter
less Constructor.
3) Parameterized Constructor.

Default Constructor :-
----------------------
If the constructor is added by compiler then it is called default constructor.

2) No argument constructor :-
----------------------------------
The constructor written by the user in the class without any parameter then it is called No argument
constructor or parameter less constructor or zero argument constructor.

By using no argument constructor all the objects will be initialized with same values so it is not
recommended approach because we will not be able to customized each individual object with different
value, to avoid this parameterized constructor came into picture.

Ex:-
public class Test
{
int x, y;

public Test() //No argument constructor, written by the user


{
x = 100;
y = 200;
}
}
-----------------------------------------------------------------------
This program contains 2 files :
---------------------------------
Person.java
-----------
package com.ravi.no_arg;

public class Person


{
private int personId;
private String personName;

public Person()
{
super();
personId = 111;
personName = "Ravi";
}

@Override
public String toString() {
return "Person [personId=" + personId + ", personName=" + personName + "]";
}

NoArgument.java
----------------
package com.ravi.no_arg;

public class NoArgument


{
public static void main(String[] args)
{
Person ravi = new Person();
System.out.println(ravi);

Person raj = new Person();


System.out.println(raj);

Person priya = new Person();


System.out.println(priya);

}
-----------------------------------------------------------------------
Parameterized Constructor :
---------------------------
If one or more argument is passed to the constructor then it is called parameterized constructor.

If we want initialize our objects with different values(unlike no argument constructor) then we should
choose parameterized constructor.

public class Test


{
private int x,y;

public Test(int x, int y)


{
this.x = x;
this.y = y;
}
}
-----------------------------------------------------------------------
This Program contains two files :
----------------------------------
Dog.java
--------
package com.ravi.parameterized;

public class Dog


{
private int dogAge;
private String dogName;
private double dogHeight;
private String dogColor;

public Dog(int dogAge, String dogName, double dogHeight, String dogColor) {


super();
this.dogAge = dogAge;
this.dogName = dogName;
this.dogHeight = dogHeight;
this.dogColor = dogColor;
}

@Override
public String toString() {
return "Dog [dogAge=" + dogAge + ", dogName=" + dogName + ", dogHeight=" + dogHeight + ",
dogColor=" + dogColor
+ "]";
}

ParameterizedConstructor.java
------------------------------
package com.ravi.parameterized;

public class ParameterizedConstructor {

public static void main(String[] args)


{
Dog d1 = new Dog(4, "Tiger", 3.5, "Black");
System.out.println(d1);

Dog d2 = new Dog(5, "Tommy", 4.5, "Grey");


System.out.println(d2);

}
-----------------------------------------------------------------------
05-12-2023
----------
HAS-A Relation :
----------------
It is a technique through which we can take the reference variable of a class, as a proprty to another class
is called HAS-A Relation.

This package contains 3 files :


--------------------------------
College.java
-------------
package com.ravi.has_a_relation;

//BLC
public class College
{
private String collegeName;
private String collegeLocation;

public College(String collegeName, String collegeLocation)


{
super();
this.collegeName = collegeName;
this.collegeLocation = collegeLocation;
}

@Override
public String toString()
{
return "College [collegeName=" + collegeName + ", collegeLocation=" + collegeLocation + "]";
}

Student.java
-------------
package com.ravi.has_a_relation;

//BLC
public class Student
{
private int studentId;
private String studentName;
private double studentFees;
private College clg; //HAS-A Relation

public Student(int studentId, String studentName, double studentFees, College clg) //clg = c1
{
super();
this.studentId = studentId;
this.studentName = studentName;
this.studentFees = studentFees;
this.clg = clg;

@Override
public String toString() {
return "Student [studentId=" + studentId + ", studentName=" + studentName + ", studentFees=" +
studentFees
+ ", clg=" + clg + "]";
}
}

Tester.java
------------
package com.ravi.has_a_relation;

//ELC
public class Tester
{
public static void main(String[] args)
{
College c1 = new College("NIT", "Hyd");

Student s1 = new Student(1, "A", 27000, c1);


System.out.println(s1);

Student s2 = new Student(2, "B", 28000, c1);


System.out.println(s2);
}

}
-----------------------------------------------------------------------
HAS-A Relation Program Example :
---------------------------------
1) Person and Address
2) Customer and Order
3) Company and Employee
4) Citizen and AadharCard/PAN Card
5) Customer and Account

Another Program on HAS-A relation :


-----------------------------------

AadharCard.java
----------------
package com.ravi.has_a_relation;

import java.util.Date;

public class AadharCard


{
private long aadharNumber;
private Date issueDate; //HAS-A Relation
private String issuingAuthority;

public AadharCard(long aadharNumber, Date issueDate, String issuingAuthority) {


super();
this.aadharNumber = aadharNumber;
this.issueDate = issueDate;
this.issuingAuthority = issuingAuthority;
}

@Override
public String toString() {
return "AadharCard [aadharNumber=" + aadharNumber + ", issueDate=" + issueDate + ",
issuingAuthority="
+ issuingAuthority + "]";
}

Citizen.java
-------------
package com.ravi.has_a_relation;

public class Citizen


{
private String citizenName;
private String nationality;
private AadharCard aadharCard; //HAS-A Relation

public Citizen(String citizenName, String nationality, AadharCard aadharCard) //aadharCard = ac


{
super();
this.citizenName = citizenName;
this.nationality = nationality;
this.aadharCard = aadharCard;
}

@Override
public String toString() {
return "Citizen [citizenName=" + citizenName + ", nationality=" + nationality + ", aadharCard=" +
aadharCard
+ "]";
}

Main.java
---------

package com.ravi.has_a_relation;

import java.util.Date;

public class Main {

public static void main(String[] args)


{
AadharCard ac = new AadharCard(1234_5678_1234L, new Date(), "uidai");

Citizen c = new Citizen("Raj", "Indian", ac);


System.out.println(c);
}
}
-----------------------------------------------------------------------
How to write setter and getter :
--------------------------------
setter :- To modify the existing object data.

This program contains 2 files [Setter Program]:


--------------------------------
package com.ravi.setter_getter;

public class Milk


{
private double milkPrice;
private String milkType;

public Milk(double milkPrice, String milkType)


{
super();
this.milkPrice = milkPrice;
this.milkType = milkType;
}

//setter
public void setMilkPrice(double milkPrice)
{
this.milkPrice = milkPrice;
}

//setter
public void setMilkType(String milkType)
{
this.milkType = milkType;
}

@Override
public String toString() {
return "Milk [milkPrice=" + milkPrice + ", milkType=" + milkType + "]";
}

Main.java
---------
package com.ravi.setter_getter;

public class Main {

public static void main(String[] args)


{
Milk m1 = new Milk(30, "Tonned Milk");
System.out.println(m1);
System.out.println(".............");
//calling setter to modify the existing object data
m1.setMilkPrice(61);
m1.setMilkType("Full Cream");
System.out.println(m1);
}

}
-----------------------------------------------------------------------
06-12-2023
------------
Program by using getter :
------------------------
getter :- It is used to read the private data value from outside of the class.

2 files :
----------
Manager.java
-------------
package com.ravi.getter;

//BLC
public class Manager
{
private double salary;

public Manager(double salary)


{
super();
this.salary = salary;
}

//getter
public double getSalary()
{
return this.salary;
}

//setter
public void setSalary(double salary)
{
this.salary = salary;
}

@Override
public String toString()
{
return "Manager [salary=" + salary + "]";
}

ELC.java
---------
package com.ravi.getter;

import java.util.Scanner;

public class ELC


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter Manager Salary :");
double sal = sc.nextDouble();

Manager m1 = new Manager(sal);


double managerSalary = m1.getSalary();

if(managerSalary >= 150000)


{
System.out.println("Role is HR Manager");
}
else
{
System.out.println("Role is Sales Manager");
}

}
----------------------------------------------------------------------
Encapsulation :-
----------------
Binding the data member with its associated function/method in a single unit is called encapsulation.

In other words we can say "Grouping the related things together is called Encapsulation". [Laptop]

In encapsulation data must be tightly coupled with associated function.

It provides us security because we can’t access the data directly, data must be accessible via methods
only.

We can achieve encapsulation in our program by using following

a) Declare all the data members as private (Tightly encapsulated class)


b) Define getters and setters for each instance variable to perform read and write operation.

Note :
-----
If we declare all the instance variables with private access modifier then it is called tightly encapsulated
class

On the other hand if some variables are declared with private access modifier and other variables are not
declared with private access modifier then it is called loosly encapsulated class
----------------------------------------------------------------------
Passing an Object reference to the Constructor (Copy Constructor)
------------------------------------------------------------------
We can pass an object reference to the constructor, the main purpose is to copy the content of one object
to another object.

3 files :
----------
Employee.java
--------------
package com.ravi.passing_object_ref;

public class Employee


{
private int employeeNumber; //111
private String employeeName; //Raj

public Employee(int employeeNumber, String employeeName)


{
super();
this.employeeNumber = employeeNumber;
this.employeeName = employeeName;
}

public int getEmployeeNumber() {


return employeeNumber;
}

public String getEmployeeName() {


return employeeName;
}

@Override
public String toString()
{
return "Employee [employeeNumber=" + employeeNumber + ", employeeName=" + employeeName +
"]";
}
}

Manager.java
-------------
package com.ravi.passing_object_ref;

public class Manager


{
private int managerId;
private String managerName;

public Manager(Employee emp) //emp = e1


{
managerId = emp.getEmployeeNumber();
managerName = emp.getEmployeeName();
}

@Override
public String toString() {
return "Manager [managerId=" + managerId + ", managerName=" + managerName + "]";
}
}

PassingObjectReference.java
-----------------------------
package com.ravi.passing_object_ref;

public class PassingObjectReference {

public static void main(String[] args)


{
Employee e1 = new Employee(111, "Raj");

Manager m1 = new Manager(e1);


System.out.println(m1);

In the above program we are taking the content of Employee object to initialise the instance variable
Manager class Here both are two different classes.

The following program explains how to copy the same object data to another object of same class.

2 files :
----------
Player.java
------------
package com.ravi.passing_object_ref;

public class Player


{
private String name1, name2;

public Player(String name1, String name2)


{
super();
this.name1 = name1;
this.name2 = name2;
}
public Player(Player p) //p = p1
{
this.name1 = p.name2;
this.name2 = p.name1;
}
@Override
public String toString() {
return "Player [name1=" + name1 + ", name2=" + name2 + "]";
}
}

ELC.java
--------
package com.ravi.passing_object_ref;

public class ELC {

public static void main(String[] args)


{
Player p1 = new Player("Rohit", "Virat");
System.out.println(p1);

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

Player p2 = new Player(p1);


System.out.println(p2);

}
----------------------------------------------------------------------
07-12-2023
-----------
Lab Program :
-------------
The payroll system of an organization involves calculating the gross salary of each type of employee and
the tax applicable to each.

Note : Attributes/Fields must be non-Private for the classes.

Create the following BLC classes as described below.

Class Employee
Fields: employeeId: int, employeeName : String, basicSalary : double, HRAPer : double, DAPer : double

Public Method: calculateGrossSalary() - returns a double


Calculate the gross salary as : basicSalary +HRAPer +DAPer

Class Manager
Fields: id: int, name : String, basicSalary : double, HRAPer : double,DAPer : double, projectAllowance:
double
Public Method: calculateGrossSalary() - returns a double
Calculate the gross salary as : basicSalary +HRAPer +DAPer + projectAllowance

Class Trainer
Fields: id: int, name : String, basicSalary : double, HRAPer : double,DAPer : double, batchCount: int,
perkPerBatch: double

Public Method: calculateGrossSalary() - returns a double


Calculate the gross salary as : basicSalary +HRAPer +DAPer +(batchCount * perkPerBatch)
Class Sourcing
Fields: id: int, name : String, basicSalary : double, HRAPer : double,DAPer : double, enrollmentTarget: int,
enrollmentReached: int, perkPerEnrollment: double
Public Method: calculateGrossSalary() - returns a double

Calculate the gross salary as : basicSalary +HRAPer +DAPer


+((enrollmentReached/enrollmentTarget)*100)*perkPerEnrollment)

Class TaxUtil
Fields: None
Public Methods:
calculateTax(Employee) - returns a double
calculateTax(Manager) - returns a double
calculateTax(Trainer) - returns a double
calculateTax(Sourcing) - returns a double

Tax Calculation Logic: If gross salary is greater than 50000 tax is 20% else, tax is 5%

Note : Attributes/Fields must be non-Private for the above classes.

A ClassObject class is given to you with the main Method. Use this class to test your solution.

6 files :
-----------

Employee.java
--------------
package com.ravi.lab_tax_util;

public class Employee


{
int employeeId;
String employeeName;
double basicSalary;
double HRAPer;
double DAPer;

public Employee(int employeeId, String employeeName, double basicSalary, double hRAPer, double
dAPer) {
super();
this.employeeId = employeeId;
this.employeeName = employeeName;
this.basicSalary = basicSalary;
HRAPer = hRAPer;
DAPer = dAPer;
}

public double calculateGrossSalary()


{
return basicSalary +HRAPer +DAPer;
}

}
Manager.java
-------------
package com.ravi.lab_tax_util;

public class Manager


{
int managerId;
String managerName;
double basicSalary;
double HRAPer;
double DAPer;
double projectAllowance;

public Manager(int managerId, String managerName, double basicSalary, double hRAPer, double
dAPer,
double projectAllowance) {
super();
this.managerId = managerId;
this.managerName = managerName;
this.basicSalary = basicSalary;
HRAPer = hRAPer;
DAPer = dAPer;
this.projectAllowance = projectAllowance;
}

public double calculateGrossSalary()


{
return basicSalary +HRAPer +DAPer + projectAllowance;
}

Trainer.java
-------------
package com.ravi.lab_tax_util;

public class Trainer


{
int trainerId;
String trainerName;
double basicSalary;
double HRAPer;
double DAPer;
int batchCount;
double perkPerBatch;

public Trainer(int trainerId, String trainerName, double basicSalary, double hRAPer, double dAPer, int
batchCount,
double perkPerBatch) {
super();
this.trainerId = trainerId;
this.trainerName = trainerName;
this.basicSalary = basicSalary;
HRAPer = hRAPer;
DAPer = dAPer;
this.batchCount = batchCount;
this.perkPerBatch = perkPerBatch;
}

public double calculateGrossSalary()


{
return basicSalary +HRAPer +DAPer +(batchCount * perkPerBatch);
}

Sourcing.java
-------------
package com.ravi.lab_tax_util;

public class Sourcing


{
int sourcingId;
String sourcingName;
double basicSalary;
double HRAPer;
double DAPer;
int enrollmentTarget;
int enrollmentReached;
double perkPerEnrollment;

public Sourcing(int sourcingId, String sourcingName, double basicSalary, double hRAPer, double dAPer,
int enrollmentTarget, int enrollmentReached, double perkPerEnrollment) {
super();
this.sourcingId = sourcingId;
this.sourcingName = sourcingName;
this.basicSalary = basicSalary;
HRAPer = hRAPer;
DAPer = dAPer;
this.enrollmentTarget = enrollmentTarget;
this.enrollmentReached = enrollmentReached;
this.perkPerEnrollment = perkPerEnrollment;
}

public double calculateGrossSalary()


{
return basicSalary + HRAPer +DAPer
+((enrollmentReached/enrollmentTarget)*100)*perkPerEnrollment;
}

}
TaxUtil.java
-------------
package com.ravi.lab_tax_util;

public class TaxUtil


{
public double calculateTax(Employee e1) // e1 = employee
{
if(e1.calculateGrossSalary() >=50000)
{
return e1.calculateGrossSalary()*0.20;
}
else
{
return e1.calculateGrossSalary()*0.05;
}
}

public double calculateTax(Manager m1)


{
if(m1.calculateGrossSalary() >=50000)
{
return m1.calculateGrossSalary()*0.20;
}
else
{
return m1.calculateGrossSalary()*0.05;
}
}

public double calculateTax(Trainer t1)


{
if(t1.calculateGrossSalary() >=50000)
{
return t1.calculateGrossSalary()*0.20;
}
else
{
return t1.calculateGrossSalary()*0.05;
}
}

public double calculateTax(Sourcing s1)


{
if(s1.calculateGrossSalary() >=50000)
{
return s1.calculateGrossSalary()*0.20;
}
else
{
return s1.calculateGrossSalary()*0.05;
}
}
}
ClassObject.java
-----------------
package com.ravi.lab_tax_util;

public class ClassObject {

public static void main(String[] args)


{
Employee employee = new Employee(1, "Raj", 40000, 3500, 2000);

Manager manager = new Manager(2, "Virat", 80000, 10000, 4000, 3500);


Trainer trainer = new Trainer(3, "Rohit", 120000, 2000, 1500, 1200, 2000);

Sourcing sourcing = new Sourcing(4,"Bumrah", 30000, 3000, 2200, 100, 80, 350);

TaxUtil tax = new TaxUtil();


double totalTax = tax.calculateTax(employee);
System.out.println("Tax amount for Employee :"+totalTax);

totalTax = tax.calculateTax(manager);
System.out.println("Tax amount for Manager :"+totalTax);

totalTax = tax.calculateTax(trainer);
System.out.println("Tax amount for Trainer :"+totalTax);

totalTax = tax.calculateTax(sourcing);
System.out.println("Tax amount for Sourcing :"+totalTax);

}
}
------------------------------------------------------------------------
How to take method return type as a class :
--------------------------------------------
We can take following return types for a method in Java :

1) void

2) we can take all the primitive data types like byte, short and so on

3) we can take class name as return type of the method

public class Test


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

public Test accept()


{
return new Test(12);
}
}
4) We can also take interface as a method return type.
-------------------------------------------------------------------------

Customer.java
-------------
package com.ravi.method_return_type;

import java.util.Date;
import java.util.Scanner;

public class Customer


{
private Integer customerId;
private String customerName;
private Double customerBill;
private Date dateOfJoining; //HAS-A Relation

public Customer(Integer customerId, String customerName, Double customerBill, Date dateOfJoining)


{
super();
this.customerId = customerId;
this.customerName = customerName;
this.customerBill = customerBill;
this.dateOfJoining = dateOfJoining;
}

public static Customer getCustomerObject()


{
Scanner sc = new Scanner(System.in);
System.out.print("Enter Customer Id :");
int cid = sc.nextInt();
System.out.print("Enter Customer Name :");
String cName = sc.nextLine();
cName = sc.nextLine();
System.out.print("Enter Customer Bill :");
double cBill = sc.nextDouble();

Date d1 = new Date();

return new Customer(cid, cName, cBill, d1);


}

@Override
public String toString() {
return "Customer [customerId=" + customerId + ", customerName=" + customerName + ", customerBill="
+ customerBill
+ ", dateOfJoining=" + dateOfJoining + "]";
}

Main.java
---------
package com.ravi.method_return_type;

import java.util.Scanner;

public class Main {

public static void main(String[] args)


{
Scanner sc = new Scanner(System.in);
System.out.print("How many Customer Object u want :");
int numberOfObjects = sc.nextInt();

for(int i=1; i<=numberOfObjects; i++)


{
Customer object = Customer.getCustomerObject();
System.out.println(object);
}
sc.close();

}
------------------------------------------------------------------------
08-12-2023
----------
Another Program, how to take method return types as a class :
-------------------------------------------------------------
2 files :
---------
Book.java
----------
package com.ravi.method_return_type_class;

import java.util.Scanner;

public class Book


{
private String bookTitle;
private String authorName;

public Book(String bookTitle, String authorName)


{
super();
this.bookTitle = bookTitle;
this.authorName = authorName;
}

public String getBookTitle()


{
return bookTitle;
}

public String getAuthorName()


{
return authorName;
}

ELC.java
---------
package com.ravi.method_return_type_class;

import java.util.Scanner;

public class ELC


{
public static void main(String[] args)
{
Book object = getBookObject();
System.out.println("Book Title is :"+object.getBookTitle());
System.out.println("Author Name is :"+object.getAuthorName());
}

public static Book getBookObject()


{
Scanner sc = new Scanner(System.in);
System.out.print("Enter title of the book :");
String title = sc.nextLine();
System.out.print("Enter Autor’s Name of the book :");
String author = sc.nextLine();

Book b1 = new Book(title, author);


return b1;

}
-------------------------------------------------------------------------
Lab Program :(Method return type as a class + Passing Object ref)
------------------------------------------------------------------
A class called Customer is given to you.

The task is to find the Applicable Credit card Type and create CardType object based on the Credit Points
of a customer.

Define the following for the class.

Attributes :
customerName : String,private
creditPoints: int, private

Constructor :
parameterizedConstructor: for both cusotmerName & creditPoints in that order.

Methods :
Name of the method : getCreditPoints
Return Type : int
Modifier : public
Task : This method must return creditPoints

Name of the method : toString, Override it,


Return type : String
Task : return only customerName from this.

Create another class called CardType. Define the following for the class

Attributes :
customer : Customer, private
cardType : String, private
Constructor :
parameterizedConstructor: for customer and cardType attributes in that order

Methods :
Name of the method : toString Override this.
Return type : String
Modifier : public
Task : Return the string in the following format.
The Customer ’Rajeev’ Is Eligible For ’Gold’ Card.

Create One more class by name CardsOnOffer and define the following for the class.

Method :
Name Of the method : getOfferedCard
Return type : CardType
Modifiers: public,static
Arguments: Customer object

Task : Create and return a CardType object after logically finding cardType from creditPoints as per the
below rules.
creditPoints cardType
100 - 500 - Silver
501 - 1000 - Gold
1000 > - Platinum
< 100 - EMI

Create an ELC class which contains Main method to test the working of the above.

4 files :
----------
Customer.java
-------------
package com.ravi.credit_card;

public class Customer


{
private int creditPoints;
private String customerName;

public Customer(int creditPoints, String customerName)


{
super();
this.creditPoints = creditPoints;
this.customerName = customerName;
}

public int getCreditPoints()


{
return this.creditPoints;
}

@Override
public String toString()
{
return this.customerName;
}

CardType.java
--------------
package com.ravi.credit_card;

public class CardType


{
private Customer customer; //HAS-A Relation
private String cardType;

public CardType(Customer customer, String cardType)


{
super();
this.customer = customer;
this.cardType = cardType;
}

@Override
public String toString()
{
return "The Customer ’"+this.customer+"’ Is Eligible for ’"+this.cardType+"’ Card.";

CardsOnOffer.java
------------------
package com.ravi.credit_card;

public class CardsOnOffer


{
public static CardType getOfferedCard(Customer obj)
{
int creditPoint = obj.getCreditPoints();

if(creditPoint >= 100 && creditPoint <= 500 )


{
return new CardType(obj, "Silver");
}
else if(creditPoint >500 && creditPoint<= 1000 )
{
return new CardType(obj, "Gold");
}
else if(creditPoint >= 1000 )
{
return new CardType(obj, "Platinum");
}
else
{
return new CardType(obj, "EMI");
}
}
}

Main.java
----------
package com.ravi.credit_card;

import java.util.Scanner;

public class Main {

public static void main(String[] args)


{
Scanner sc = new Scanner(System.in);
System.out.print("Enter Customer Name :");
String name = sc.nextLine();
System.out.print("Enter Customer credit points :");
int creditPoint = sc.nextInt();

Customer c1 = new Customer(creditPoint, name);

CardType offeredCard = CardsOnOffer.getOfferedCard(c1);


System.out.println(offeredCard);
sc.close();
}

}
------------------------------------------------------------------------
Can we declare a Constructor with private access modifier ?
------------------------------------------------------------
Yes, we can declare a constructor with private access modifier. We should declare a constructor with
private access modifier for the following 2 reasons :

1) If that class contains only static method. (Example java.lang.Math)


2) If we create singleton class. It is class for which only one object
is allowed.
Program :
----------
public class Test
{
private Test()
{
System.out.println("Private Constructor");
}

public static void main(String[] args)


{
new Test();
}
}
-------------------------------------------------------------------------
Some important points to remember :

1) We cannot apply final and static modifier on Constructor.

2) We can write only return keyword without value inside a constructor

public class Test


{
public Test()
{
System.out.println("Private Constructor");
return ;
}
public static void main(String[] args)
{
new Test();
}
}

3) We if write any return type before the constructor then it will become
method and now we need to invoke explicitly.

public class Test


{
public void Test() //Method
{
System.out.println("Method");
}
public static void main(String[] args)
{
Test t1 = new Test();
t1.Test();
}
}
-------------------------------------------------------------------------
09-12-2023
----------
HEAP and STACK Diagram :
------------------------
What is Garbage Collector in Java ?
------------------------------------
In Java the programmer is only responsible to allocate the memory by using constructor, memory
de-allocation is not the responsibility of the programmer. It is automatically done by garbage collector.

As we know all the objects are created inside the HEAP Memory where as all our methods are executed
inside stack memory.

The main purpose of GC(Garbage Collector) to scan the heap memory, identify which objects are eligible
for GC and which objects are not eligible. (An object is eligible for GC if that object does not contain any
references)

How many ways we can make an object eligible for GC :


-----------------------------------------------------
There are 3 ways we can make an object eligible for GC.

1) Assigning null literal to reference variable :


Employee e1 = new Employee(111,"Ravi");
e1 = null;

2) Creating an Object inside a method :

public void createObject()


{
Employee e2 = new Employee();
}
Here we are creating Employee object inside the method so, once the method execution is over then e2
will be deleted from the Stack Frame and the employee object will become eligible for GC.

3) Assigning new Object to the old existing reference variable:

Employee e3 = new Employee();


e3 = new Employee();

Earlier e3 variable was poting to Employee object after that a new Employee Object is created which is
pointing to another memory location so the first object is eleigible for GC.

--------------------------------------------------------------------------
HEAP and Stack Diagram for CustomerDemo.java
--------------------------------------------
class Customer
{
private String name;
private int id;

public Customer(String name , int id) //constructor


{
this.name=name;
this.id=id;
}

public void setId(int id) //setter


{
this.id=id;
}
public int getId() //getter
{
return id;
}
}

public class CustomerDemo


{
public static void main(String[] args)
{
int val=100;
Customer c = new Customer("Ravi",2);

m1(c);

//GC [Only one object i.e 3000x is eligible for GC]

System.out.println(c.getId());
}

public static void m1(Customer cust)


{
cust.setId(5);

cust = new Customer("Rahul",7);

cust.setId(9);
System.out.println(cust.getId());
}
}

// 9 5
--------------------------------------------------------------------------
HEAP and STACK Diagram for Sample.java
---------------------------------------
public class Sample
{
private Integer i1 = 900;

public static void main(String[] args)


{
Sample s1 = new Sample();

Sample s2 = new Sample();

Sample s3 = modify(s2);

s1 = null;

//GC [4 objects are eligible i.e. 1000x, 2000x, 5000x and 6000x]

System.out.println(s2.i1);
}
public static Sample modify(Sample s)
{
s.i1=9;
s = new Sample();
s.i1= 20;
System.out.println(s.i1);
s=null;
return s;
}
}

// 20 9
-------------------------------------------------------------------------
HEAP and STACK Diagram for Test.java
--------------------------------------
public class Test
{
Test t;
int val;

public Test(int val)


{
this.val = val;
}

public Test(int val, Test t)


{
this.val = val;
this.t = t;
}

public static void main(String[] args)


{
Test t1 = new Test(100);

Test t2 = new Test(200,t1);

Test t3 = new Test(300,t1);

Test t4 = new Test(400,t2);

t2.t = t3; //3000x


t3.t = t4; //4000x
t1.t = t2.t; //3000x
t2.t = t4.t; //2000x

System.out.println(t1.t.val);
System.out.println(t2.t.val);
System.out.println(t3.t.val);
System.out.println(t4.t.val);
}

}
//300 200 400 200
------------------------------------------------------------------------
HEAP and STACK Diagram for Employee.java
----------------------------------------
public class Employee
{
int id = 100;

public static void main(String[] args)


{
int val = 200;

Employee e1 = new Employee();

e1.id = val;

update(e1);

System.out.println(e1.id);

Employee e2 = new Employee();

e2.id = 500;

switchEmployees(e2,e1); //3000x , 1000x

//GC [2 objects 2000x and 4000x are eligible for GC]

System.out.println(e1.id);
System.out.println(e2.id);
}

public static void update(Employee e) //e = e1


{
e.id = 500;
e = new Employee();
e.id = 400;
}

public static void switchEmployees(Employee e1, Employee e2)


{
int temp = e1.id;
e1.id = e2.id; //500
e2 = new Employee();
e2.id = temp;
}
}

//500 500 500


-----------------------------------------------------------------------
instance block or non-static block in java
-------------------------------------------
It is a new feature introduced in java. The main purpose of instance block to initialize the instance variable
of the class before the constructor, that is the reason it is also known as instance initializer.

An instance block we can write inside the class even inside the method or constructor.

An instance block will be automatically placed in the second line of constructor at the time of compilation.
An instance block will be executed automatically at the time of creating the object BEFORE THE
CONSTRUCTOR BODY EXECUTION.

Instance block will executed once per object that means whenever we create an object, instance block
will be executed.

If we have multiple instance blocks in a class then they would be executed in the same order as they
were written in the class(order wise)
------------------------------------------------------------------------
Program that describes instance block will be executed before the constructor

2 files :
-----------
Test.java
----------
package com.ravi.instance_block;

public class Test


{

public Test()
{
System.out.println("No Argument Constructor!!!");
}

{
System.out.println("Instance Block!!!");
}

InstanceDemo.java
------------------
package com.ravi.instance_block;

public class InstanceDemo {

public static void main(String[] args)


{
Test t1 = new Test();
System.out.println("......");
Test t2 = new Test();
}

}
-----------------------------------------------------------------------
Program to show instance blocks are executed according to the order

2 files :
-----------
Test.java
----------
package com.ravi.instance_block;
public class Test
{
private int x;

public Test()
{
System.out.println(x);
}

{
x = 100;
System.out.println(x);
}

{
x = 200;
System.out.println(x);
}

{
x = 300;
System.out.println(x);
}
}

InstanceDemo.java
-----------------
package com.ravi.instance_block;

public class InstanceDemo {

public static void main(String[] args)


{
Test t1 = new Test();

}
----------------------------------------------------------------------
Program to show if user has written any non-static block after the constructor body then compiler will not
perform any action.

2 files :
---------
Test.java
---------
package com.ravi.instance_block;

public class Test


{

public Test()
{
System.out.println("No Argument constructor");
{
System.out.println("Instance Block");
}
}

InstanceDemo.java
-------------------
package com.ravi.instance_block;

public class InstanceDemo {

public static void main(String[] args)


{
Test t1 = new Test();

}
}
------------------------------------------------------------------------
13-12-2023
-----------
Relationship between the classes :
----------------------------------
In Java, we have 2 types of relationship between the classes :

a) IS-A Relation (We can achieve using Inheritance concept)


b) HAS-A Relation (We can achieve using Association concept)

Inheritance (IS-A Relation) :


--------------------------------
Deriving a new class (child class) from existing class (parent class) in such a way that the new class will
acquire all the properties and features (except private) from the existing class is called inheritance.

It is one of the most imporatnt feature of OOPs which provides "CODE REUSABILITY".

Using inheritance mechanism the relationship between the classes is parent and child. According to C++
the parent class is called Base class and the child class is called Derived class, According to Java the
parent class is called super class and the child class is called sub class.

In java we provide inheritance using ’extends’ keyword.

*By using inheritance all the feature of super class is by default available to the sub class so the sub class
need not to start the process from begning onwards.

Inheritance provides IS-A relation between the classes. IS-A relation is tightly coupled relation (Blood
Relation) so if we modify the super class content then automatically sub class content will also modify.

Inheritance provides us hierarchical classification of classes, In this hierarchy if we move towards upward
direction more generalized properties will occur, on the other hand if we move towards downwand more
specialized properties will occur.

In Java we have 5 types of Inheritance :


----------------------------------------
1) Single Level Inheritance
2) Multilevel Inheritance
3) Hierarchical Inheritance
4) Multiple Inheritance (Java does not support MI)
5) Hybrid Inheritance (Combination of two Inheritance)
--------------------------------------------------------------------------
//Program on Single level Inheritance :
---------------------------------------
IN JAVA OBJECT IS THE SUPER CLASS OF ALL THE CLASSES .

3 files :
---------
Parent.java
------------
package com.ravi.single_level;

public class Parent


{
public void bike()
{
System.out.println("Honda Bike");
}
}

Child.java
-----------
package com.ravi.single_level;

public class Child extends Parent


{
public void car()
{
System.out.println("Audi Car");
}
}

SingleLevel.java
-----------------
package com.ravi.single_level;

public class SingleLevel {

public static void main(String[] args)


{
Child c1 = new Child();
c1.bike();
c1.car();
}

}
-----------------------------------------------------------------------
14-12-2023
----------
Program to call the super class constructor using super keyword :
-----------------------------------------------------------------
Main.java [Single File Approach]

package com.ravi.inheritance;

class A
{
public A()
{
super();
System.out.println("No Arg of Super class");
}
}

class B extends A
{
public B()
{
super();
System.out.println("No Arg of Sub class");
}
}
public class Main
{
public static void main(String[] args)
{
B b1 = new B();

}
------------------------------------------------------------------------
//Program on Multilevel Inheritance
package com.ravi.inheritance;

class AA
{
public AA()
{
System.out.println("AA");
}
}
class BB extends AA {}

class CC extends BB
{
public CC()
{
System.out.println("CC");
}
}

public class ELC


{
public static void main(String[] args)
{
CC c1 = new CC();

}
----------------------------------------------------------------------
Program on Single Level Inheritance :
-------------------------------------
Comapny :
TemporaryEmployee
|-eno
|-ename
|-eaddr
PermanentEmployee
|-department
|-designation

SingleLevel.java
-----------------
package com.ravi.single_level_demo;

class TemporaryEmployee
{
int employeeNumber;
String employeeName;
String employeeAddress;

public TemporaryEmployee(int employeeNumber, String employeeName, String employeeAddress) {


super();
this.employeeNumber = employeeNumber;
this.employeeName = employeeName;
this.employeeAddress = employeeAddress;
}

@Override
public String toString()
{
return "TemporaryEmployee [employeeNumber=" + employeeNumber + ", employeeName=" +
employeeName
+ ", employeeAddress=" + employeeAddress + "]";
}

}
class PermanentEmployee extends TemporaryEmployee
{
String department;
String designation;

public PermanentEmployee(int employeeNumber, String employeeName, String employeeAddress,


String department,
String designation) {
super(employeeNumber, employeeName, employeeAddress);
this.department = department;
this.designation = designation;
}
@Override
public String toString()
{
return super.toString()+ "PermanentEmployee [department=" + department + ", designation=" +
designation + "]";
}

public class SingleLevel


{
public static void main(String[] args)
{
PermanentEmployee pe = new PermanentEmployee(101, "Virat", "Delhi", "Cricket", "batter");
System.out.println(pe);

}
------------------------------------------------------------------------
super keyword :
---------------
It is used to call the member of member of super class. We can use super keyword in 3 ways :

1) To call the super class Constructor

2) To call the super class method

3) To call the super class variable

To call the super class constructor : (Constructor Chaining)


-----------------------------------------------------------------
Whenever we write a class in java and we don’t write any kind of constructor to the class then the java
compiler will automatically add one default constructor to the class.

THE FIRST LINE OF ANY CONSTRUCTOR IS RESERVERD EITHER FOR super() or this() keyword.

In the first line of any constructor if we don’t specify either super() or this() then the compiler will
automatically add super() to the first line of constructor.

Now the purpose of this super() [added by java compiler], to call the default constructor or No-Argument
constructor of the super class.

In order to call the constructor of super class as well as same class, we have total 4 cases.

We have 4 cases :
-----------------
case 1 :
---------
super() :- Will call no argument OR default constructor of super class.
It is automatically added by compiler.

CallingNoArgumentOfSuperClass.java
-----------------------------------
package com.ravi.cases;

class Super
{
public Super()
{
System.out.println("No Argument of super class");
}
}
class Sub extends Super
{
public Sub()
{
System.out.println("No Argument of Sub class");
}
}

public class CallingNoArgumentOfSuperClass


{

public static void main(String[] args)


{
Sub s1 = new Sub();

------------------------------------------------------------------------
Case 2 :
--------
super(9) :- Will call parameterized constructor of super class.

CallingParameterizedConstructorOfSuper.java
-------------------------------------------
package com.ravi.cases;

class Base
{
public Base(String str) //str = Ravi
{
super();
System.out.println("Hello :"+str);
}
}
class Derived extends Base
{

public Derived(String str)


{
super(str);
System.out.println("Parameterized Constructor of Derived class");
}

public class CallingParameterizedConstructorOfSuper


{

public static void main(String[] args)


{
Derived d1 = new Derived("Ravi");

}
------------------------------------------------------------------------
15-12-2023
----------
Case 3 :
--------
this() :- It is used to call the no argument constructor of the current class.

package com.ravi.this_demo;

class Super
{
public Super()
{
super();
System.out.println("No Argument of super class");
}

public Super(String str) //str = NIT


{
this();
System.out.println("Parameterized Constructor super class :"+str);
}
}
class Sub extends Super
{
public Sub()
{
super("NIT");
System.out.println("No Argument Constructor of Sub class ");
}
}

public class CallingNoArgumentofCurrentclass


{
public static void main(String[] args)
{
Sub s1 = new Sub();
}
}
------------------------------------------------------------------------
Case 4 :
--------
this(9) :- Will call the parameterized constructor of current class.

package com.ravi.this_demo;

class A
{
public A()
{
this(15);
System.out.println("No Argument Constructor...");
}

public A(int a) //a = 15


{
super();
System.out.println("Parameterized Constructor..."+a);
}
}
class B extends A
{
public B()
{
System.out.println("No Argument Constructor of Sub class..");
}
}

public class CallingParameterizedConstructorOfCurrentClass {

public static void main(String[] args)


{
new B(); //Nameless OR Anonymous Object

Note :- super keyword always refers to its immediate super class.


-----------------------------------------------------------------------
Program on super keyword using single level Inheritance :
---------------------------------------------------------
3 files :
--------
Shape.java
----------
package com.ravi.super_example;

public class Shape


{
private int data; //loosely encapsulated class
public Shape(int data)
{
this.data = data;
System.out.println("Data value is :"+data);
}

public int getData()


{
return this.data;
}

Square.java
------------
package com.ravi.super_example;

public class Square extends Shape


{
public Square(int side)
{
super(side);
}

public void getAreaOfSquare()


{
double area = getData() * getData();
System.out.println("Area of Square is :"+area);
}
}

ShapeDemo.java
--------------
package com.ravi.super_example;

public class ShapeDemo


{
public static void main(String[] args)
{
Square ss = new Square(5);
ss.getAreaOfSquare();

}
------------------------------------------------------------------------
Program on super keyword using Hierarchical Inheritance :
---------------------------------------------------------
4 Files :
---------
Shape.java
-----------
package com.ravi.super_ex;
public class Shape
{
protected int data; //loosely encapsulated class

public Shape(int data)


{
this.data = data;
System.out.println("Data value is :"+data);
}

public int getData()


{
return this.data;
}

Rectangle.java
---------------
package com.ravi.super_ex;

public class Rectangle extends Shape


{
protected int breadth;

public Rectangle(int length, int breadth)


{
super(length);
this.breadth = breadth;
}

public void getAreaOfRectangle()


{
double area = data * breadth;
System.out.println("Area of Rectangle is :"+area);
}

Circle.java
-----------
package com.ravi.super_ex;

import java.text.DecimalFormat;

public class Circle extends Shape


{
final double PI = 3.14;

public Circle(int radius)


{
super(radius);
}
public void getAreaOfCircle()
{
double area = PI * data*data;
DecimalFormat df = new DecimalFormat("000.00");
String format = df.format(area);
System.out.println("Area of Circle is :"+format);
}
}

Tester.java
-----------
package com.ravi.super_ex;

import java.util.Scanner;

public class Tester {

public static void main(String[] args)


{
Scanner sc = new Scanner(System.in);
System.out.print("Enter the length of Rectangle :");
int length = sc.nextInt();

System.out.print("Enter the breadth of Rectangle :");


int breadth = sc.nextInt();

Rectangle rr = new Rectangle(length, breadth);


rr.getAreaOfRectangle();

System.out.print("Enter the radius of the Circle :");


int radius = sc.nextInt();

Circle cc = new Circle(radius);


cc.getAreaOfCircle();
sc.close();

Note :DecimalFormat is a predefined class available in java.text package to provide the format for decimal
value.
----------------------------------------------------------------------
16-12-2023
-----------
2) To call the method of the super class
---------------------------------------------
Whenever super class method name and sub class method name both are same and if we create an
object for the sub class then by default it will invoke or call the sub class method, if we want to call the
super class method then we should use super keyword.

Just like this keyword, we cannot use super keyword from static
area.

3 files
-------
Super.java
----------
package com.ravi.test;

public class Super


{
public void show()
{
System.out.println("Super class Show method");
}
}

Sub.java
---------
package com.ravi.test;

public class Sub extends Super


{
public void show()
{
System.out.println("Sub class Show method");
super.show();
}
}

SuperMethod.java
----------------
package com.ravi.test;

public class SuperMethod {

public static void main(String[] args)


{
Sub s1 = new Sub();
s1.show();

}
-----------------------------------------------------------------------
To call super class variable :
------------------------------
Whenever super class variable name and sub class variable name both are same and if we create an
object for the sub class then the sub class will provide more priority to its own class variable, If we want to
invoke the super class variable then we should use super keyword.

super keyword always refers to its immediate super class.

Note :- We should use super keyword when the super class member name and sub class member
name both are same as welll as We can’t use super keyword from static context.

3 files :
---------
Father.java
------------
package com.ravi.test;

public class Father


{
protected double balance = 50000;
}

Son.java
---------
package com.ravi.test;

public class Son extends Father


{
protected double balance = 18000;

public void getBalance()


{
System.out.println("Father balance is :"+super.balance);
System.out.println("Son balance is :"+balance);
}
}

SuperVar.java
--------------
package com.ravi.test;

public class SuperVar {

public static void main(String[] args)


{
Son s1 = new Son();
s1.getBalance();

}
-----------------------------------------------------------------------
Program on multilevel inheritance :
-----------------------------------

MultiLevel.java [Single File Approach]


---------------------------------------

package com.ravi.multilevel;

class Student
{
protected int studentId;
protected String studentName;
protected String studentAddress;
}
class Science extends Student
{
protected int phy, che;
}

class PCM extends Science


{
protected int math;

public PCM(int sno, String name, String addr, int phy, int che, int math)
{
studentId = sno;
studentName = name;
studentAddress = addr;
this.phy = phy;
this.che = che;
this.math = math;
}

@Override
public String toString() {
return "PCM [math=" + math + ", phy=" + phy + ", che=" + che + ", studentId=" + studentId + ",
studentName="
+ studentName + ", studentAddress=" + studentAddress + "]";
}

public void calculateResult()


{
double result = this.phy + this.che + this.math;
System.out.println("Total Marks :"+result);
}

public class MultiLevel


{
public static void main(String[] args)
{
PCM p1 = new PCM(1, "ABC", "Ampt", 67, 72, 80);
System.out.println(p1);
p1.calculateResult();
}

}
----------------------------------------------------------------------
Program on Hierarchical Inheritance
------------------------------------
package com.ravi.inheritance;

class Employee
{
protected double salary;
}

class Developer extends Employee


{
public Developer(double salary)
{
super();
this.salary = salary;
}

@Override
public String toString() {
return "Developer [salary=" + salary + "]";
}
}

class Designer extends Employee


{
public Designer(double salary)
{
super();
this.salary = salary;
}

@Override
public String toString() {
return "Designer [salary=" + salary + "]";
}

public class HierarchicalInheritance {

public static void main(String[] args)


{
System.out.println(new Developer(50000));
System.out.println(new Designer(20000));

}
-----------------------------------------------------------------------
IQ
--
Why Java does not support multiple Inheritance ?
------------------------------------------------
Java does not support multiple inheritance using classes, because if a sub class inherits two or more than
two super classes then the default constructor added by the compiler will generate ambiguity issue to call
the super class constructor.(16-DEC)

It is a also known as Diamond Problem in java.

We can achieve multiple Inheritance by using interface concept.


----------------------------------------------------------------------
18-12-2023
-----------
Access modifiers in Java :
--------------------------
In terms of accessibility i.e. to define the accessibility level of the class or the member of the class, Java
software people has provided
four access modifiers.

1) private (Accessible within the same class)


2) default (Accessible within the same package)
3) protected
4) public

private :-
---------
It is an access modifier and it is the most restrictive access modifier because the member declared as
private can’t be accessible from outside of the class.
In Java we can’t declare an outer class as a private or protected. Generally we should declare the data
member(variables) as private.

In java outer class can be declared as public, abstract and final only.

default :-
----------
It is an access modifier which is less restrictive than private. It is such kind of access modifier whose
physical existance is not avaialble that means when we don’t specify any kind of access modifier before
the class name, variable name or method name then by default it would be default.

As far as its accessibility is concerned, default members are accessible within the same folder(package)
only.

protected :
------------
It is an access modifier which is less restrictive than default because the member declared as protected
can be accessible from the outside of the package (folder) too but by using inheritance concept.

Test.java[Available in com.ravi.m1 package]


----------------------------------------------
package com.ravi.m1;

//BLC
public class Test
{
protected int x = 200;
}

ELC.java [Available in another package com.ravi.m2]


----------------------------------------------------
package com.ravi.m2;

import com.ravi.m1.Test;

public class ELC extends Test


{
public static void main(String[] args)
{
ELC e1 = new ELC();
System.out.println(e1.x);
}

}
-----------------------------------------------------------------------
public :
-------
It is an access modifier which does not contain any kind of restriction that is the reason the member
declared as public can be accessible from everywhere without any restriction.

According to Object Oriented rule we should declare the classes and methods as public where as
variables must be declared as private or protected according to the requirement.
-----------------------------------------------------------------------
HAS-A relation between the classes :
------------------------------------------
In order to acheive HAS-A relation concept we should use Association.

Association (Relationship between the classes through Object reference)


----------------------------------------------------------------

Association :
---------------
Association is a connection between two separate classes that can be built up through their Objects.

The association builds a relationship between the classes and describes how much a class knows about
another class.

This relationship can be unidirectional or bi-directional. In Java, the association can have one-to-one,
one-to-many, many-to-one and many-to-many relationships.

Example:-
One to One: A person can have only one PAN card
One to many: A Bank can have many Employees
Many to one: Many employees can work in single department
Many to Many: A Bank can have multiple customers and a customer can have multiple bank accounts.
-----------------------------------------------------------------------
Program on Association Concept :
--------------------------------
3 files :
----------
Student.java
------------
package com.ravi.assiciation;

public class Student


{
private int studentId;
private String studentName;
private long contactNumber;
private String studentAddress;

public Student(int studentId, String studentName, long contactNumber, String studentAddress) {


super();
this.studentId = studentId;
this.studentName = studentName;
this.contactNumber = contactNumber;
this.studentAddress = studentAddress;
}

@Override
public String toString() {
return "Student [studentId=" + studentId + ", studentName=" + studentName + ", contactNumber=" +
contactNumber
+ ", studentAddress=" + studentAddress + "]";
}

public int getStudentId() {


return studentId;
}

public void setStudentId(int studentId) {


this.studentId = studentId;
}

Faculty.java
-------------
package com.ravi.assiciation;

import java.util.Scanner;

public class Faculty


{
public static void viewStudentProfile(Student obj)
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter Student Id :");
int id = sc.nextInt();

if(id == obj.getStudentId())
{
System.out.println(obj);
}
else
{
System.err.println("Sorry! Student data is not available");
}
}

AssociationDemo.java
--------------------
package com.ravi.assiciation;

public class AssociationDemo {

public static void main(String[] args)


{
Student s1 = new Student(101, "Raj", 9812_3456_78L, "S R Nagar");

Faculty.viewStudentProfile(s1);

}
-------------------------------------------------------------------------
19-12-2023
----------
Composition [Strong reference]:
-------------------------------
Composition in Java is a way to design classes such that one class contains an object of another class. It
is a way of establishing a "HAS-A" relationship between classes. Composition represents a strong
relationship between the containing class and the contained class.If the containing object is destroyed, all
the contained objects are also destroyed.

A car has an engine. Composition makes strong relationship between the objects. It means that if we
destroy the owner object, its members will be also destroyed with it. For example, if the Car is destroyed
the engine will also be destroyed as well.

3 files :
----------
Engine.java
-----------
package com.ravi.composition;

public class Engine


{
private String engineType;
private int horsePower;

public Engine(String engineType, int horsePower)


{
super();
this.engineType = engineType;
this.horsePower = horsePower;
}

@Override
public String toString()
{
return "Engine [engineType=" + engineType + ", horsePower=" + horsePower + "]";
}

Car.java
---------
package com.ravi.composition;

public class Car


{
private String carName;
private int carModel;
private Engine engine;

public Car(String carName, int carModel)


{
this.carName = carName;
this.carModel = carModel;
this.engine = new Engine("Battery", 1200); //Composition
}

@Override
public String toString()
{
return "Car [carName=" + carName + ", carModel=" + carModel + ", engine=" + engine + "]";
}

Composition.java
----------------
package com.ravi.composition;

public class Composition


{
public static void main(String[] args)
{
Car c1 = new Car("Audi", 2023);
System.out.println(c1);
}
}

H.W (GCR)
----------
Laptop and MotherBoard
Fan and Coil
-------------------------------------------------------------------------
Aggregation (Weak Reference) :
-----------------------------------
Aggregation in Java is another form of association between classes that represents a "HAS-A"
relationship, but with a weaker bond compared to composition. In aggregation, one class contains an
object of another class, but the contained object can exist independently of the container. If the container
object is destroyed, the contained object can still exist.

3 files :
----------
Employee.java
-------------
package com.ravi.aggregation;

public class Employee


{
private int employeeNumber;
private String employeeName;
private double employeeSalary;

public Employee(int employeeNumber, String employeeName, double employeeSalary) {


super();
this.employeeNumber = employeeNumber;
this.employeeName = employeeName;
this.employeeSalary = employeeSalary;
}

@Override
public String toString() {
return "Employee [employeeNumber=" + employeeNumber + ", employeeName=" + employeeName + ",
employeeSalary="
+ employeeSalary + "]";
}

Company.java
-------------
package com.ravi.aggregation;

public class Company


{
private String companyName;
private String companyLocation;
private Employee employee;

public Company(String companyName, String companyLocation, Employee employee) {


super();
this.companyName = companyName;
this.companyLocation = companyLocation;
this.employee = employee;
}

@Override
public String toString() {
return "Company [companyName=" + companyName + ", companyLocation=" + companyLocation + ",
employee=" + employee
+ "]";
}
}

Aggregation.java
-----------------
package com.ravi.aggregation;

public class Aggregation


{
public static void main(String[] args)
{
Employee e1 = new Employee(101, "Ravi", 12000);
e1 = null;

Employee e2 = new Employee(102, "Raj", 14000);


Company c1 = new Company("TCS", "Hyderabad", e2);
System.out.println(c1);
}

}
--------------------------------------------------------------------------
Polymorphism :
------------------
Poly means "many" and morphism means "forms".

It is a Greek word whose meaning is "same object having different behavior".

In our real life a person or a human being can perform so many task, in the same way in our programming
languages a method or a constructor can perform so many task.

Eg:-

void add(int a, int b)

void add(int a, int b, int c)

void add(float a, float b)

void add(int a, float b)

Polymorphism can be divided into two types :

1) Static polymorphism OR Compile time polymorphism OR Early binding

2) Dynamic Polymorphism OR Runtime polymorphism OR Late binding

Static Polymorphism :
------------------------
The polymorphism which exist at the time of compilation is called static polymorphism.

In static polymorphism, compiler has very good idea that which method is going to invoke(call) depending
upon the type of parameter we have passed in the method.

This type of preplan polymorphism is called static polymorphism.

Example:- Method Overloading

Dynamic Polymorphism :
----------------------------
The polymorphism which exist at runtime is called dynamic polymorphism.

In dynamic polymorphism, compiler does not have any idea about method calling, at runtime JVM will
decide that which method is invoked depending upon the class type.

This type of polymorphism is called dynamic polymorphism.(Dynamic Method dispatched)

Example:- Method Overriding


-------------------------------------------------------------------
Note :- In static polymorphism method calling is done at the time of compilation so it is also known as
Early Binding.
On the other hand In dynamic Polymorphism method calling is done at the of execution so it is also
known as Late Binding.
-------------------------------------------------------------
20-12-2023
------------

Method Overloading :
--------------------
Writing two or more methods in the same class or even in the super and sub class in such a way that the
method name must be same but the argument must be different.

While Overloading a method we can change the return type of the method.

Method overloading is possible in the same class as well as super and sub class.

While overloading the method the argument must be different otherwise there will be ambiguity problem.

IQ
---
Can we overload the main method?
---------------------------------
We can overload the main method but JVM will always search the main method which takes String array
as a parameter.

Example :
------------
public static void main(String [] args) //JVM will serach this method
{
}

public static void main(String x)


{
}

public static void main(int y)


{
}
----------------------------------------------------------------------
//Program on Constructor Overloading :
--------------------------------------
package com.ravi.method_overloading;

class Addition
{
public Addition(int x, int y)
{
super();
System.out.println("Sum of two integer :"+(x+y));
}

public Addition(int x, int y, int z)


{
this(100,200);
System.out.println("Sum of three integer :"+(x+y+z));
}

public Addition(float x, float y)


{
this(10,20,30);
System.out.println("Sum of two float :"+(x+y));
}
}

public class OverloadDemo1


{
public static void main(String[] args)
{
Addition a = new Addition(2.3f, 4.5f);

}
-----------------------------------------------------------------------
Program on Method Overloading by changing the return type.

package com.ravi.method_overloading;

class Add
{
public int add(int x, int y)
{
return (x+y);
}

public float add(float x, float y)


{
return (x+y);
}

public String add(String x, String y)


{
return (x+y);
}
}

public class OverloadDemo2


{
public static void main(String[] args)
{
Add a1 = new Add();
String add = a1.add("Data", "base");
System.out.println("Result is :"+add);

float res = a1.add(2.3f, 2.3f);


System.out.println("Result is :"+res);

int result = a1.add(10, 20);


System.out.println("Result is :"+result);
}

}
-----------------------------------------------------------------------
Var-Args :
------------
It was introduced from JDK 1.5 onwards.

It stands for variable argument. It is an array variable which can hold 0 to n number of parameters of
same type or different type by using Object class.

It is represented by exactly 3 dots (...) so it can accept any number of argument (0 to nth) that means now
we need not to define method body again and again, if there is change in method parameter value.

var-args must be only one and last argument.

We can use var-args as a method parameter only.


------------------------------------------------------------------------
Program that describes var args can hold 0 to n number of parameters :
----------------------------------------------------------------------
2 Files :
---------
Test.java
----------
package com.ravi.var_args;

public class Test


{
public void input(int ...x) //Array
{
System.out.println("Var args executed");
}
}

Main.java
----------
package com.ravi.var_args;

public class Main {

public static void main(String ...x)


{
Test t1 = new Test();
t1.input();
t1.input(12);
t1.input(15,19);
t1.input(10,20,30);
t1.input(10,20,30,40);
t1.input(10,20,30,40,50);

}
-----------------------------------------------------------------------
Program that describes how to add patameter values using var args :
-------------------------------------------------------------------
2 Files :
---------
Test.java
---------
package com.ravi.var_args1;

public class Test


{
public void acceptData(int ...x) //10 20 30
{
int sum = 0;

for(int y : x)
{
sum = sum + y;
}
System.out.println("Sum of parameter :"+sum);
}
}

Main.java
----------
package com.ravi.var_args1;

public class Main


{
public static void main(String[] args)
{
Test t1 = new Test();
t1.acceptData();
t1.acceptData(10,20);
t1.acceptData(10,20,30);
t1.acceptData(100,100,100,100);

}
----------------------------------------------------------------------
Program that describes var args must be only one and last argument.

Test.java
---------
package com.ravi.var_args2;

public class Test


{
/*
* public void accept(float ...x, int ...y) //invalid { }
*
* public void accept(int ...x, int y) //Invalid {
*
*}
*/

public void accept(int x, int... y) // valid


{
System.out.println("x value is :"+x);
for (int z : y)
{
System.out.println(z);
}
}
}

Main.java
---------
package com.ravi.var_args2;

public class Main {

public static void main(String[] args)


{
Test t1 = new Test();
t1.accept(10, 20,30,40,50);
}
}
-----------------------------------------------------------------------
21-12-2023
----------
Program that describes we can accept hetrogeneous types of data using var args.

2 Files :
---------
Test.java
---------
package com.ravi.var_args3;

public class Test


{
public void acceptHetro(Object ...obj)
{
for(Object o : obj)
{
System.out.println(o);
}
}
}

Main.java
----------
package com.ravi.var_args3;

public class Main {

public static void main(String[] args)


{
Test t1 = new Test();

t1.acceptHetro(true,45.90,12,’A’, new String("Ravi"));

}
}
----------------------------------------------------------------------
Ambiguity issue while overloading a method :
--------------------------------------------
While overloading a method, if we have ambiguity issue then we should
use the following two rules :

1) Most specific type (The nearest type which one is smaller)

double > float


float > long
long > int
int > char
int > short
short > byte

2) While overloading if we have an ambiguity issue then compiler provides the priority on the following
basis :
WAV [Widening -> Autoboxing -> var args]

----------------------------------------------------------------------
class Demo
{
public void m1(float i,int j){
System.out.println("float method ");
}

public void m1(int i, float j){


System.out.println("int method ");
}
}

public class Ambiguity {

public static void main(String[] args)


{
new Demo().m1(10, 10); //error
new Demo().m1(10f, 10);//valid

---------------------------------------------------------------------
class Demo
{
public void m1(int ...x){
System.out.println("int method ");
}
public void m1(boolean ...x){
System.out.println("boolean method ");
}
}

public class Ambiguity {

public static void main(String[] args)


{
new Demo().m1(); //error

}
---------------------------------------------------------------------
package com.ravi.ambiguity_overloading;

class Test
{

public void accept(char ...x)


{
System.out.println("Char");
}

public void accept(int ...x)


{
System.out.println("int");
}

public class AmbiguityDemo1


{
public static void main(String[] args)
{
Test t1 = new Test();
t1.accept();

}
Note :- Here char will be executed becoz char is more specific than int
-------------------------------------------------------------------------
package com.ravi.ambiguity_overloading;

class Test
{
public void accept(byte b)
{
System.out.println("byte :"+b);
}
public void accept(short s)
{
System.out.println("short :"+s);
}

public class AmbiguityDemo1


{
public static void main(String[] args)
{
Test t1 = new Test();
//t1.accept(9); //CE becoz 9 is of type int
t1.accept((byte)15);
t1.accept((short)29);

Note :- 9 is by default of type int so we cannot assign to byte and short


-------------------------------------------------------------------------
package com.ravi.ambiguity_overloading;

class Test
{
public void accept(int b)
{
System.out.println("int :"+b);
}

public void accept(long s)


{
System.out.println("long :"+s);
}

public class AmbiguityDemo1


{
public static void main(String[] args)
{
Test t1 = new Test();
t1.accept(9);

Here int will be executed becoz int is more specific than long.
------------------------------------------------------------------------
package com.ravi.ambiguity_overloading;

class Test
{
public void accept(String b)
{
System.out.println("String :"+b);
}

public void accept(Object s)


{
System.out.println("Object :"+s);
}

public class AmbiguityDemo1


{
public static void main(String[] args)
{
Test t1 = new Test();
t1.accept("Ravi");
t1.accept(null);

Note :- String will be executed becoz String is more Specific type.


-----------------------------------------------------------------------
package com.ravi.ambiguity_overloading;

class Test
{
public void accept(Integer b)
{
System.out.println("Integer :"+b);
}

public void accept(String s)


{
System.out.println("String :"+s);
}

public void accept(Object s)


{
System.out.println("Object :"+s);
}

public class AmbiguityDemo1


{
public static void main(String[] args)
{
Test t1 = new Test();
t1.accept(null); //error

}
}

Note :- In between Integer and String there is an ambiguity that which one is specific type.
-------------------------------------------------------------------------
WAV
---
package com.ravi.ambiguity_overloading;

class Test
{
public void accept(long b)
{
System.out.println("Long :"+b);
}

public void accept(Integer s)


{
System.out.println("Integer :"+s);
}

public class AmbiguityDemo1


{
public static void main(String[] args)
{
Test t1 = new Test();
t1.accept(15);

Note :- In between long and Integer, the priority will be given to long
------------------------------------------------------------------------
package com.ravi.ambiguity_overloading;

class Test
{
public void accept(int ...b) //WAV
{
System.out.println("Var Args :"+b);
}

public void accept(Integer s)


{
System.out.println("Integer :"+s);
}

public class AmbiguityDemo1


{
public static void main(String[] args)
{
Test t1 = new Test();
t1.accept(15);

In between Autoboxing and var args, priority goes to Autoboxing.


------------------------------------------------------------------------
* Method Overriding :
--------------------
Writing two or more methods in the super and sub class in such a way that method signature(method
name along with method parameter) of both the methods must be same in the super and sub classes.

While working with method overriding generally we can’t change the return type of the method but from
JDK 1.5 onwards we can change the return type of the method in only one case that is known as
Co-Variant.

Without inheritance method overriding is not possible that means if there is no inheritance there is no
method overriding.
------------------------------------------------------------------------
What is the advantage of Method Overriding ?
-------------------------------------------
The advantage of Method Overriding is, each class is specifying its own specific behavior.
------------------------------------------------------------------------
Upcasting :-
------------
It is possble to assign sub class object to super class reference variable using dynamic polymorphism. It
is known as Upcasting.

Example:- Animal a = new Dog(); //valid [upcasting]

Downcasting :
---------------
By default downcasting is not possible, Here we are trying to assign super class object to sub class
reference variable but the same we can achieve by using explicit type casting. It is known as
downcasting

Eg:- Dog d = new Animal(); //Invalid

Dog d =(Dog) new Animal(); //Valid because Explicit type casting

But by using above statement (Downcasting) whenever we call a method we will get a runtime
exception called java.lang.ClassCastException. [Animal cann’t be cast to Dog]
------------------------------------------------------------------------
class Animal
{
public void eat()
{
System.out.println("I can’t say");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("Dog is non-Veg type Animal");
}

}
public class AnimalDemo
{
public static void main(String[] args)
{
Animal a = new Dog(); //upcasting
a.eat();

}
}
-----------------------------------------------------------------------
package com.arvi.interface_demo;

class Shape
{
public void draw()
{
System.out.println("No idea, What type of draw");
}
}
class Rectangle extends Shape
{
public void draw()
{
System.out.println("Drawing Rectangle");
}
}
class Square extends Shape
{
public void draw()
{
System.out.println("Drawing Square");
}
}

public class MethodOverridingDemo


{
public static void main(String[] args)
{
Shape s;

s = new Rectangle(); s.draw();


s = new Square(); s.draw(); //Dynamic Method dispatch

------------------------------------------------------------------------
@Override Annotation :
--------------------------
In Java we have a concept called Annotation, introduced from JDK 1.5 onwards. All the annotations must
be start with @ symbol.

@Override annotation is optional but it is always a good practice to write @Override annotation before the
Overridden method so compiler as well as user will get the confirmation that the method is overridden
method and it is available in the super class.

If we use @Override annotation before the name of the method in the sub class and if the method is not
available in the super class then it will generate a compilation error so it is different from comment
because comment will not generate any kind of compilation error if method is not an overridden method,
so this is how it is different from comment.
-----------------------------------------------------------------------
package com.arvi.interface_demo;

class Bird
{
public void fly()
{
System.out.println("Bird can fly");
}
}
class Parrot extends Bird
{
@Override
public void fly()
{
System.out.println("Parrot can fly");
}
}

public class MethodOverridingDemo


{
public static void main(String[] args)
{
Bird b = new Parrot();
b.fly();

}
------------------------------------------------------------------------
Role of Access modifier while overriding a method :
----------------------------------------------------
While overriding the method from super class, the access modifier of sub class method must be greater
or equal in comparison to access modifier of super class method otherwise we will get compilation error.

public is greater than protected, protected is greater than default (public > protected > default)
[default < protected < public]

So the conclusion is we can’t reduce the visibility while overriding a method.

Note :- private access modifier is not availble (visible) in sub class so it is not the part of method
overriding.
class RBI
{
public void loan()
{
System.out.println("Bank should provide loan..");
}
}
class SBI extends RBI
{
@Override
protected void loan() //error
{
System.out.println("SBI provides loan @ 9.2%..");
}
}
class RBIDemo
{
public static void main(String[] args) throws Exception
{
RBI r1;
r1 = new SBI(); r1.loan(); //Dynamic method dispatch
}
}
------------------------------------------------------------------------
23-12-2023
----------
In method overriding, if super class and sub class variable name both are same then it is called variable
shadow.
Here in upcasting we will verify the reference type at the time of calling the variable, based on the
reference type variable will be invoked.

Example :-
Animal a = new Lion();
a.name; // a is animal reference so Animal class variable will
be invoked.

package com.ravi.variable_shadow;

class Animal
{
String name = "Ranbeer";

public String makeNoise()


{
return "Generic";
}
}
class Lion extends Animal
{
String name = "Rashmika";

public String makeNoise()


{
return "Roar..";
}
}

public class MethodOverriding


{
public static void main(String[] args)
{
Animal a1 = new Animal();
System.out.println(a1.name +" : "+a1.makeNoise());
System.out.println(".....................");

Lion l = new Lion();


System.out.println(l.name +" : "+l.makeNoise());
System.out.println(".....................");

Animal a = new Lion();


System.out.println(a.name +" : "+a.makeNoise());
}
}
-----------------------------------------------------------------------
IQ :
---
Co-variant concept in method overriding :
------------------------------------------------
In general we cann’t change the return type of method while overriding a method. if we try to change it will
generate compilation error as shown in the program below.

class Super
{
public void show()
{
System.out.println("Super class show method ...");
}
}
class Sub extends Super
{
@Override
public int show()
{
System.out.println("Sub class show method ");
return 0;
}
}
public class IncompatibleOverride
{
public static void main(String [] args)
{
Super s = new Sub();
s.show();
}
}

Note :- return type int is not compatible void.


-----------------------------------------------------------------------
But from JDK 1.5 onwards we can change the return type of the method in only one case that the return
type of both the METHODS(SUPER AND SUB CLASS METHODS) MUST BE IN INHERITANCE
RELATIONSHIP (IS-A relation ship so it is compatible) called Co-Variant as shown in the program below.

Note :- Co-variant will not work with primitive data type, it will work only with classes
-----------------------------------------------------------------------
package com.ravi.variable_shadow;

class Alpha{}
class Beta extends Alpha{}

class Vehicle
{
public Alpha run()
{
System.out.println("Vehicle is running");
return new Beta();
}
}
class Car extends Vehicle
{
@Override
public Beta run()
{
System.out.println("Car is running");
return new Beta();
}
}

public class CoVariant


{
public static void main(String[] args)
{
Vehicle v = new Car();
v.run();

}
------------------------------------------------------------------------
package com.ravi.variable_shadow;

class Student
{
public Object writeExam()
{
System.out.println("Student is Writing Exam..");
return null;
}
}

class JavaStudent extends Student


{
@Override
public Double writeExam()
{
System.out.println("Java Student is Writing Exam..");
return null;
}
}

public class CoVariantDemo


{
public static void main(String[] args)
{
Student s1 = new JavaStudent();
s1.writeExam();
}

}
------------------------------------------------------------------------
public class Test
{
@Override
public String toString()
{
return "NIT";
}

public static void main(String[] args)


{
Object t1 = new Test();
System.out.println(t1);
}
}
-----------------------------------------------------------------------
26-12-2023
-----------
While working with co-variant return type, the method return value will be super class object (Animal class
object) because if it will return
sub class object(Rabbit object) then we will get java.lang.ClassCastException as shown in the program
below.

package com.ravi.co_variant;

class Animal
{
public Animal sleep()
{
System.out.println("Animal is sleeping");
return new Animal();
}
}

class Rabbit extends Animal


{
@Override
public Rabbit sleep()
{
System.out.println("Rabbit is sleeping");
return new Rabbit();
}
}

public class CoVariantDemo


{
public static void main(String[] args)
{
Animal a1 = new Rabbit();
Animal obj = a1.sleep();
}
}
-----------------------------------------------------------------------
*
What is Method Hiding?
OR
Can we override static method?
OR
Can we override main method?

Points to remember :
--------------------
Point 1)
--------
We cannot override static method but static methods can be inherited as shown in the program below.

package com.ravi.co_variant;

class Alpha
{
public static void m1()
{
System.out.println("m1 static method");
}
}
class Beta extends Alpha
{
}

public class StaticMethodInheritance


{
public static void main(String[] args)
{
//Valid but not recommended
//Beta b1 = new Beta();
//b1.m1();

Beta.m1();

}
-----------------------------------------------------------------------
Point 2)
We cannot override any static method with non-static method.

class Alpha
{
public static void m1()
{
System.out.println("m1 static method");
}
}
class Beta extends Alpha
{
public void m1()
{
System.out.println("m1 non-static method");
}
}

public class StaticMethodOvderridingWithNonStaticMethod


{
public static void main(String[] args)
{

}
-----------------------------------------------------------------------
Point 3)
We cannot override any non-static method with static method.

class Alpha
{
public void m1()
{
System.out.println("m1 non static method");
}
}
class Beta extends Alpha
{
public static void m1()
{
System.out.println("m1 static method");
}
}
public class OverridingNonStaticWithStatic
{
public static void main(String[] args)
{

}
}

So, the conclusion is we cannot overide static with non static method as well as non-static with static
method because static method belongs to class and non-static method belongs to object.
-----------------------------------------------------------------------
Point 4)
--------
If we write static method in the super class and sub class with same signature and same return type then
it looks like static method is overridden but actually it is METHOD HIDING. The sub class static method is
hidden from super class static method as shown in the program.

package com.ravi.co_variant;

class Alpha
{
public static void m1()
{
System.out.println("m1 static method of Alpha class");
}
}
class Beta extends Alpha
{
//Method Hiding
public static void m1()
{
System.out.println("m1 static method of Beta class");
}
}

public class StaticMethodInheritance


{
public static void main(String[] args)
{
Alpha a1 = new Beta();
a1.m1();

Note :- We cannot apply @Override annotation on static methods.

-----------------------------------------------------------------------
Program on Method Hiding :
--------------------------
class Super
{
public static void m1()
{
}
}
class Sub extends Super
{
public static int m1()
{
return 0;
}
}
public class MethodHiding
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

Note :- In the above program we will get compilation error because return type int is not compatible with
void so method cannot be HIDDEN.

*We cannot override main method because main method is a static method but we can overload where
JVM will always search the main method which takes String array as a parameter.
-----------------------------------------------------------------------
final keyword in java :
-----------------------
It is used to provide some kind of restriction in our program.
We can use final keyword in ways 3 ways in java.

1) To declare a class as a final. (Inheritance is not possible)


2) To declare a method as a final (Overriding is not possible)
3) To declare a variable (Field) as a final

To declare a class as a final :


-------------------------------
Whenever we declare a class as a final class then we cann’t extend or inherit that class otherwise we will
get a compilation error.

We should declare a class as a final if the composition of the class (logic of the class) is very important
and we don’t want to share the feature of the class to some other developer to modify the original
behavior of the existing class, In that situation we should declare a class as a final.

Declaring a class as a final does not mean that the variables and methods declared inside the class will
also become as a final only the class behavior is final that means we can modify the variables value as
well as we can create the object for the final classes.

Note :- In java String is declared as final class.

final class A
{
private int x = 100;
public void setData()
{
x = 120;
System.out.println(x);
}
}
class B extends A
{
}
public class FinalClassEx
{
public static void main(String[] args)
{
B b1 = new B();
b1.setData();
}
}
-----------------------------------------------------------------------
final class Test
{
private int data = 100;

public void setData(int data)


{
this.data = data;
System.out.println("Data value is :"+data);
}
}
public class FinalClassEx1
{
public static void main(String[] args)
{
Test t1 = new Test();
t1.setData(200);
}
}
----------------------------------------------------------------------
2) To declare a method as a final (Overriding is not possible)
--------------------------------------------------------------------
Whenever we declare a method as a final then we can’t override that method in the sub class otherwise
there will be a compilation error.

We should declare a method as a final if the body of the method i.e the implementation of the method is
very important and we don’t want to override or change the super class method body by sub class
method body then we should declare the super class method as final method.

class A
{
protected int a = 10;
protected int b = 20;

public final void calculate()


{
int sum = a+b;
System.out.println("Sum is :"+sum);
}
}
class B extends A
{
@Override
public void calculate()
{
int mul = a*b;
System.out.println("Mul is :"+mul);
}
}
public class FinalMethodEx
{
public static void main(String [] args)
{
A a1 = new B();
a1.calculate();
}
}
-----------------------------------------------------------------------
class A
{
protected int a = 10;
protected int b = 20;

private final void calculate()


{
int sum = a+b;
System.out.println("Sum is :"+sum);
}
}
class B extends A
{
public void calculate()
{
int mul = a*b;
System.out.println("Mul is :"+mul);
}
}
public class FinalMethodEx1
{
public static void main(String [] args)
{
B b1 = new B();
b1.calculate();
}
}

Note :- super class method is private so not visible in the sub class (No Compilation error even super
class method is final)
-----------------------------------------------------------------------
3) To declare a variable(field) as a final :(Re-assignment is not possible)
------------------------------------------------------------------
In older langugaes like C and C++ we use "const" keyword to declare a constant variable but in java const
is a reserved word for future use so instead of const we should use "final" keyword.

If we declare a variable as a final then we can’t perform re-assignment (i.e nothing but re-initialization) of
that variable.

In java It is always a better practise to declare a final variable by uppercase letter according to the naming
convention.

Some example of predefined final variables

Byte.MIN_VALUE -> MIN_VALUE is a static and final variable

Byte.MAX_VALUE -> MAX_VALUE is a static and final variable

Example:- final int DATA = 10; (Now we can not perform re-assignment )
-----------------------------------------------------------------------
// All different types of final variables

package com.ravi.set_interface;

public class SetDemo


{
final int A = 10;
final static int B = 20;

public static void main(String[] args)


{
final SetDemo sd = new SetDemo();
sd.acceptData(30);
System.out.println("Static variable :"+SetDemo.B);
System.out.println("Instance variable :"+sd.A);
//sd = new SetDemo(); Invalid
}

public void acceptData(final int C)


{
System.out.println("Parameter Variable :"+C);
}
}
-----------------------------------------------------------------------

class A
{
final int A = 10;
public void setData()
{
A = 10; //error [Re-assignment is not possible]
System.out.println("A value is :"+A);
}
}
class FinalVarEx
{
public static void main(String[] args)
{
A a1 = new A();
a1.setData();
}
}
-----------------------------------------------------------------------
class FinalVarEx1
{
public static void main(String[] args)
{
final int A = 127;
byte b = A;
System.out.println(b);
}
}

The above program will execute.


-----------------------------------------------------------------------
Blank final variable :
----------------------
If we declare a final variable without initialization then it is called Blank final variable.

1) final variables must be initialized at the time of declaration or later (only through constructor, instance
block), after that we can’t perform re-initialization.

2) A blank final variable can’t be initialized by default constructor.

3) A blank final variable must be initialized by the user as a part of constructor. If we have multiple
constructor then final variable must be initialized with all the constructor to provide values for the blank
final variable to all the objects.

public class BlankFinalVar


{
final int A; //Blank final variable

public static void main(String[] args)


{
BlankFinalVar fv = new BlankFinalVar();
System.out.println(fv.A);
}
}
-----------------------------------------------------------------------
class Demo
{
final int A; // blank final variable

public Demo() //No Argument constructor


{
A = 15;
System.out.println(A);
}

public Demo(int x) //parameterized constructor


{
A = x;
System.out.println(x);
}

}
public class BlankFinalVariable
{
public static void main(String[] args)
{
Demo d1 = new Demo(); //d1 -> A -> 15

Demo d2 = new Demo(8); //d2 -> A -> 8


}
}
-----------------------------------------------------------------------
28-12-2023
----------
Method Chaining :
-----------------
Method Chaining :
-----------------
-> It is a technique through which we can call a method based on my
previous method return type.

-> The final return type of the method will be decided by last
method invocation as shown in the following program.

MathodChaining.java
--------------------
public class MathodChaining
{
public static void main(String[] args)
{
String str1 = "india";
char ch = str1.concat(" is great").toUpperCase().charAt(0);
System.out.println(ch);

String str2 = "hyderabad";


int len = str2.concat(" is nice city ").length();
System.out.println(len);

Working with Object class and its methods :


--------------------------------------------------
There is a predefined class called Object available in java.lang package, this Object class is by default the
super class of all the classes we have in java.

class Test
{

Note :- Object is the super class for this Test class. by default this Object class is super class so explicitly
we need not to mention.

Since, Object is the super class of all the classes in java that means we can override the method of
Object class (Except final methods) as well as we can use the methods of Object class anywhere in java
because every class is sub class of Object class.

The Object class provides some common behavior to each sub class Object like we can compare two
objects , we can create clone (duplicate) objects, we can print object properties(instance variable),
providing a unique number to each and every object(hashCode()) and so on.
-----------------------------------------------------------------------
1) public native final java.lang.Class getClass()
---------------------------------------------------
It is a predefined method of Object class.

This method returns the runtime class of the object, the return type of this method is java.lang.Class.
This method will provide class keyword + Fully Qualified Name (package name + class name)

This getClass() method return type is java.lang.Class so further we can apply any other method of
java.lang.Class class method.
------------------------------------------------------------------------
package com.ravi.object;

public class GetClassDemo


{
public static void main(String[] args)
{
GetClassDemo gcd = new GetClassDemo();
System.out.println(gcd.getClass());

}
-----------------------------------------------------------------------
package com.ravi.object;

public class GetClassDemo1 {

public static void main(String[] args)


{
GetClassDemo1 gcd = new GetClassDemo1();
String name = gcd.getClass().getName();//Method Chaining
System.out.println(name);

Note :- getClass() method return type is java.lang.Class so we can further call any method available in
java.lang.Class, Here we are calling getName() method available in java.lang.Class and return type of this
method is String.
-----------------------------------------------------------------------
public native int hashCode() :-
-----------------------------
It is a predefined method of Object class.

Every Object contains a unique number generated by JVM at the time of Object creation is called
hashCode.

we can find out the hashCode value of an Object by using hashCode() method of Object class, return
type of this method is int.

package com.ravi.object;

class Demo
{
}

public class HashCodeDemo


{
public static void main(String[] args)
{
Demo d1 = new Demo();
Demo d2 = new Demo();
Demo d3 = d2;

System.out.println("Hashcode");
System.out.println(d1.hashCode()+" : "+d2.hashCode()+" : "+d3.hashCode());

}
-----------------------------------------------------------------------
3) public String toString() :
----------------------------
It is a predefined method of Object class.

it returns a string representation of the object. In general, the toString method returns a string that
"textually represents" this object. The result should be a concise but informative representation that is
easy for a person to read

toString() method of Object class conatins following logic.

public String toString()


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

Please note internally the toString() method is calling the hashCode() and getClass() method of Object
class.

In java whenever we print any Object reference by using System.out.println() then internally it will invoke
the toString() method of Object class as shown in the following program.
---------------------------------------------------------------------
package com.ravi.object;

class Test
{
}

public class ToStringDemo


{
public static void main(String[] args)
{
Test t1 = new Test();
System.out.println(t1.toString());

}
-----------------------------------------------------------------------
package com.ravi.object;

class Foo
{
@Override
public String toString()
{
return "NIT";
}
}

public class ToStringDemo1


{
public static void main(String[] args)
{
System.out.println(new Foo());

}
-----------------------------------------------------------------------
29-12-2023
----------
public boolean equals(Object obj)
---------------------------------
It is a predefined method of Object class.

It is mainly used to compare two objects based on the memory address or memory reference because
internally it uses == operator only.

As a user we can override equals(Object obj) method of Object class for content comparison so the
behavior of Object class equals() method can change at the time of overriding.

Note :- String class has overridden equals(Object obj) method for content comparison.
----------------------------------------------------------------------
Program that describes Object class equals(Object obj) method uses
== operator internally.

2 Files :
---------
Product.java
-------------
package com.ravi.equals_method;

public class Product


{
private int productId;
private String productName;

public Product(int productId, String productName)


{
super();
this.productId = productId;
this.productName = productName;
}

}
ProductEquality.java
---------------------
package com.ravi.equals_method;

public class ProductEquality


{
public static void main(String[] args)
{
Product p1 = new Product(111, "Laptop");
Product p2 = new Product(222, "Mobile");
Product p3 = new Product(111, "Laptop");
Product p4 = p3;

System.out.println("Comparison using == Operator");


System.out.println(p1==p2); //false
System.out.println(p1==p3); //false

System.out.println("Comparison using equals(Object) method");


System.out.println(p1.equals(p2)); //false
System.out.println(p1.equals(p3)); //false
System.out.println(p4.equals(p3)); //true

}
-----------------------------------------------------------------------
From the above program it is clear that equals(Object obj) method of Object class uses == operator so, it
is meant for memory address OR memory reference comparison.

We can override equals(Object obj) method in our class to change the default behavior of equals(Object
obj) method of Obejct class from MEMORY ADDRESS COMPARISON TO CONTENT COMPARISON.

PARENT CLASS
-------------
public boolean equals(Object obj)
{
//Memory address comparison;
}

CHILD CLASS
-----------
@Override
public boolean equals(Object obj)
{
//Content comparison;
}
----------------------------------------------------------------------
2 Files :
---------
Employee.java
-------------
package com.ravi.equals_method;

public class Employee


{
private int employeeId;
private String employeeName;

public Employee(int employeeId, String employeeName)


{
super();
this.employeeId = employeeId;
this.employeeName = employeeName;
}

//Overriding equals(Object obj) method from Object class for


// comparing the content

@Override
public boolean equals(Object obj) //obj = e2 [111, "Virat"]
{
//First Object Data
int eid1 = this.employeeId;
String name1 = this.employeeName;

//Second Object data


Employee e2 = (Employee) obj; //Down casting
int eid2 = e2.employeeId;
String name2 = e2.employeeName;

if(eid1 == eid2 && name1.equals(name2))


{
return true;
}
else
{
return false;
}

}
}

EmployeeEquality.java
---------------------
package com.ravi.equals_method;

public class EmployeeEquality


{
public static void main(String[] args)
{
Employee e1 = new Employee(111, "Virat");
Employee e2 = new Employee(111, "Virat");

System.out.println(e1.equals(e2));
}
}
----------------------------------------------------------------------
At the time of two objects comparison if both the objects are same type then we can compare but if the
objects are different type or null then by using instanceof operator we will verify whether both the objects
are same type or differenr type as shown in the program below.
3 Files :
----------
Student.java
-------------
package com.ravi.equals_method;

public class Student


{
private int studentId;
private String studentName;

public Student(int studentId, String studentName)


{
super();
this.studentId = studentId;
this.studentName = studentName;
}

@Override
public boolean equals(Object obj) // obj = s2
{
if(obj instanceof Student)
{
Student s2 = (Student) obj;

if(this.studentId == s2.studentId && this.studentName.equals(s2.studentName))


{
return true;
}
else
{
return false;
}

}
else
{
System.err.println("Comparison is not possible");
return false;
}
}
}

Customer.java
-------------
package com.ravi.equals_method;

public class Customer


{
private int customerId;
private String customerName;
public Customer(int customerId, String customerName)
{
super();
this.customerId = customerId;
this.customerName = customerName;
}

StudentEquality.java
----------------------
package com.ravi.equals_method;

public class StudentEquality {

public static void main(String[] args)


{
Student s1 = new Student(222,"ABC");
Student s2 = new Student(222,"ABC");
Customer c1 = new Customer(222,"ABC");

System.out.println(s1.equals(s2));
System.out.println(s1.equals(c1));
System.out.println(s1.equals(null));

}
---------------------------------------------------------------------
30-12-2023
-----------
Abstract class and abstract methods :
-------------------------------------------
A class that does not provide complete implementation (partial implementation) is defined as an abstract
class.

An abstract method is a common method which is used to provide easiness to the programmer because
the programmer faces complexcity to remember the method name.

An abstract method observation is very simple because every abstract method contains abstract keyword,
abstract method does not contain any method body and at the end there must be a terminator i.e ;
(semicolon)

In java whenever action is common but implementations are different then we should use abstract
method, Generally we declare abstract method in the super class and its implementation must be
provided in the sub classes.

if a class contains at least one method as an abstract method then we should compulsory declare that
class as an abstract class.

Once a class is declared as an abstract class we can’t create an object for that class.

*All the abstract methods declared in the super class must be overridden in the sub classes otherwise the
sub class will become as an abstract class hence object can’t be created for the sub class as well.

In an abstract class we can write all abstract method or all concrete method or combination of both the
method.

It is used to acheive partial abstraction that means by using abstract classes we can acheive partial
abstraction(0-100%).

*An abstract class may or may not have abstract method but an abstract method must have abstract
class.

Note :- We can’t declare an abstract method as final, private and static (illegal combination of modifiers)

-----------------------------------------------------------------------
Program on abstract method :
-----------------------------
abstract class Shape
{
public abstract void draw();
}

class Rectangle extends Shape


{
@Override
public void draw()
{
System.out.println("Drawing Rectangle");
}
}
class Square extends Shape
{
@Override
public void draw()
{
System.out.println("Drawing Square");
}
}

public class ShapeDemo


{
public static void main(String[] args)
{
Shape s1 ;

s1 = new Rectangle(); s1.draw();


s1 = new Square(); s1.draw();
}
}
------------------------------------------------------------------------
package com.ravi.co_variant;

abstract class Car


{
protected int speed = 100;

public Car()
{
System.out.println("Car class Constructor");
}

public void getCarDetails()


{
System.out.println("My car has 4 wheels");
}

public abstract void run();

class Honda extends Car


{

@Override
public void run()
{
System.out.println("Honda Car is running");
}
}

public class InterviewQuestion


{
public static void main(String[] args)
{
Car c1 = new Honda();
System.out.println("Speed is :"+c1.speed);
c1.getCarDetails();
c1.run();

****Note :- In an abstract class if we have any constructor then it will be executed by sub class object
using super keyword.
------------------------------------------------------------------------
01-01-2024
----------
What is the advantage of writing constructor in abstract class?
----------------------------------------------------------------
We cannot create an object for abstract class but we can take object properties (Object state OR Instance
variable) inside the abstract class
which will be initialized through sub class object using super keyword.
-----------------------------------------------------------------------
How many ways we can Initialize the object properties
------------------------------------------------------
The following are the ways to initialize the object properties :
----------------------------------------------------------------
public class Test
{
int x,y;
}
1) At the time of declaration :

Example :

public class Test


{
int x = 10;
int y = 20;
}

Test t1 = new Test(); [x = 10 y = 20]


Test t2 = new Test(); [x = 10 y = 20]

Here the drawback is all objects will be initialized with same value.
-----------------------------------------------------------------------

2) By using Object Reference :

public class Test


{
int x,y;
}

Test t1 = new Test(); t1.x=10; t1.y=20;


Test t2 = new Test(); t2.x=30; t2.y=40;

Here we are getting different values with respect to object but here
the program becomes more complex.
-----------------------------------------------------------------------
3) By using methods :

A) First Approach (Method without Parameter)


----------------------------------------------
public class Test
{
int x,y;

public void setData() //All the objects will be initialized with


{ same value
x = 100; y = 200;
}
}

Test t1 = new Test(); t1.setData(); [x = 100 y = 200]


Test t2 = new Test(); t2.setData(); [x = 100 y = 200]

B) Second Approach (Method with Parameter)


-------------------------------------------
public class Test
{
int x,y;

public void setData(int x, int y)


{
this.x = x;
this.y = y;
}
}

Test t1 = new Test(); t1.setData(12,78); [x = 12 y = 78]


Test t2 = new Test(); t2.setData(15,29); [x = 15 y = 29]

Here the Drawback is initialization and re-initialization both are done in two different lines so
Constructor introduced.
----------------------------------------------------------------------
4) By using Constructor

A) First Approach (No Argument Constructor)


--------------------------------------------
public class Test
{
int x,y;

public Test() //All the objects will be initialized with


{ same value
x = 100; y = 200;
}
}

Test t1 = new Test(); [x = 100 y = 200]


Test t2 = new Test(); [x = 100 y = 200]

B) Second Approach (Parameterized Constructor)


-----------------------------------------------
public class Test
{
int x,y;

public Test(int x, int y)


{
this.x = x;
this.y = y;
}
}

Test t1 = new Test(12,78); [x = 12 y = 78]


Test t2 = new Test(15,29); [x = 15 y = 29]

This is the best way to initialize our instance variable because variable initialization and variable
re-initialization both will be done in the same line as well as all the objects will be initialized with different
values.

C) Third Approach (Copy Constructor)


--------------------------------------

public class Manager


{
private int managerId;
private String managerName;

public Manager(Employee emp)


{
this.managerId = emp.getEmployeeId();
this.managerName = emp.getEmployeeName();
}
}

Here with the help of Object reference (Employee class) we are


initializing the properties of Manager class. (Copy Constructor)

d) By using instance block (Instance Initializer)


-------------------------------------------------

public class Test


{
int x,y;

public Test()
{
System.out.println(x); //100
System.out.println(y); //200
}

//Instance block
{
x = 100;
y = 200;
}

-----------------------------------------------------------------------
5) By using super keyword :

class Super
{
int x,y;

public Super(int x , int y)


{
this.x = x;
this.y = y;
}
}
class Sub extends Super
{
Sub()
{
super(100,200); //Initializing the properties of super class
}
}

new Sub();
-----------------------------------------------------------------------
//Program that describes that all the abstract method must be overridden in the sub classes otherwise sub
class will also become as an abstract
class

package com.ravi.abstract_ex;

abstract class Alpha


{
public abstract void show();
public abstract void demo();
}
abstract class Beta extends Alpha
{
@Override
public void show() //demo();
{
System.out.println("Show method implemented in Beta class");
}
}
class Gamma extends Beta
{
@Override
public void demo()
{
System.out.println("demo method implemented in Gamma class");
}
}

public class AbstractDemo


{
public static void main(String[] args)
{
Gamma g = new Gamma();
g.show(); g.demo();

}
-----------------------------------------------------------------------
Program on abstract class :
----------------------------
4 Files :
---------
Shape.java
-----------
package com.ravi.abstract_example;

public abstract class Shape


{
protected int data; //length of rectangle + Radius

public Shape(int data)


{
this.data = data;
}
public abstract double area();
}

Rectangle.java
--------------
package com.ravi.abstract_example;

public class Rectangle extends Shape


{
protected int breadth;
public Rectangle(int length, int breadth) // 5 10
{
super(length);
this.breadth = breadth;
}

@Override
public double area()
{
double areaOfRect = data * breadth;
return areaOfRect;
}

Circle.java
------------
package com.ravi.abstract_example;

public class Circle extends Shape


{
final double PI = 3.14;
public Circle(int radius)
{
super(radius);
}

@Override
public double area()
{
double areaOfCircle = PI * data * data;
return areaOfCircle;
}

ShapeDemo.java
---------------
package com.ravi.abstract_example;

import java.text.DecimalFormat;

public class ShapeDemo {


public static void main(String[] args)
{
Rectangle rectangle = new Rectangle(10,15);
double areaOfRect = rectangle.area();
System.out.println("Area of Rectangle is :"+areaOfRect);

Circle circle = new Circle(3);


double areaOfCircle = circle.area();
DecimalFormat df = new DecimalFormat("00.00");
System.out.println("Area of Circle is :"+df.format(areaOfCircle));

}
-----------------------------------------------------------------------
//Abstract class using Array concept

package com.ravi.abstract_example;

abstract class Animal


{
public abstract void checkup();
}

class Lion extends Animal


{
@Override
public void checkup()
{
System.out.println("LION check up");

class Dog extends Animal


{
@Override
public void checkup()
{
System.out.println("DOG check up");

class Bird extends Animal


{
@Override
public void checkup()
{
System.out.println("Bird check up");

}
}

public class AnimalDoctor


{
public static void main(String[] args)
{

Lion []lions = {new Lion(), new Lion(), new Lion()};

Dog []dogs = {new Dog(),new Dog()};

Bird []birds = {new Bird()};

checkAnimals(lions);
checkAnimals(dogs);
checkAnimals(birds);
}

public static void checkAnimals(Animal []animals)


{
for(Animal animal : animals)
{
animal.checkup();
}
}

}
----------------------------------------------------------------------
02-01-2024
-----------
Working with Anonymous inner class with concrete class :
---------------------------------------------------------
package com.ravi.abstract_ex;

class Super
{
public void show()
{
System.out.println("super class show method");
}
}

public class AnonymousInnerWithConcrete


{
public static void main(String[] args)
{
//Anonymous inner class
Super sub = new Super()
{
@Override
public void show()
{
System.out.println("sub class show method");
}
};
sub.show();

}
----------------------------------------------------------------------
Anonymous inner class with abstract class and abstract method :
--------------------------------------------------------------
package com.ravi.anonymous_demo;

abstract class Animal


{
public abstract void sleep();
}

public class AnonymousWithAbstract


{
public static void main(String[] args)
{
//Anonymous inner class
Animal lion = new Animal()
{
@Override
public void sleep()
{
System.out.println("Lion is sleeping");
}
};

//Anonymous inner class


Animal dog = new Animal()
{
@Override
public void sleep()
{
System.out.println("Dog is sleeping");
}
};
lion.sleep(); dog.sleep();
}

}
-----------------------------------------------------------------------
interface upto java 1.7
------------------------
An interface is a keyword in java which is similar to a class.

Upto JDK 1.7 an interfcae contains only abstract method that means there is a guarantee that inside an
interfcae we don’t have concrete or general or instance methods.

From java 8 onwards we have a facility to write default and static methods.

By using interface we can achieve 100% abstraction concept because it contains only abstract methods.
In order to implement the member of an interface, java software people has provided implements
keyword.

All the methods declared inside an interface is by default public and abstract so at the time of overriding
we should apply public access modifier to sub class method.

All the variables declared inside an interface is by default public, static and final.

We should override all the abstract methods of interface to the sub classes otherwise the sub class will
become as an abstract class hence object can’t be created.

We can’t create an object for interface, but reference can be created.

By using interfcae we can acheive multiple inheritance in java.

We can achieve loose coupling using inetrface.

Note :- inside an interface we can’t declare any blocks (instance, static), instance variables (No
properties) as well as we can’t write constructor inside an interface.
----------------------------------------------------------------------
Program on interface :
----------------------
3 Files :
---------
Moveable.java(I)
----------------
package com.ravi.interface_demo;

public interface Moveable


{
int SPEED = 90; //public + static + final
void move(); //public + abstract

Car.java(c)
------------
package com.ravi.interface_demo;

public class Car implements Moveable


{
@Override
public void move()
{
//SPEED = 120; Invalid
System.out.println("Moving with "+SPEED+" Speed");
}
}

Main.java
-----------
package com.ravi.interface_demo;
public class Main
{
public static void main(String[] args)
{
Moveable m = new Car();
m.move();
System.out.println("Car Speed is :"+Moveable.SPEED);
}

}
----------------------------------------------------------------------
package com.ravi.interface_demo;

interface Bank
{
void deposit(int amount);
void withdraw(int amount);
}
class Customer implements Bank
{
protected double balance = 1000;

@Override
public void deposit(int amount)
{
if(amount <=0)
{
System.out.println("Amount cannot be deposited");
}
else
{
balance = balance + amount;
System.out.println("After Deposit :"+balance);
}
}

@Override
public void withdraw(int amount)
{
balance = balance - amount;
System.out.println("After Withdraw :"+balance);
}
}

public class BankingApplication


{
public static void main(String[] args)
{
Bank b = new Customer();
b.deposit(5000);
b.withdraw(2000);
}
}
-----------------------------------------------------------------------
Program on loose coupling :
----------------------------
Loose Coupling :- If the degree of dependency from one class object to another class is very low then it is
called loose coupling.

Tightly coupled :- If the degree of dependency of one class to another class is very high then it is called
Tightly coupled.

According to IT industry standard we should always prefer loose coupling so the maintenance of the
project will become easy.
-----------------------------------------------------------------------
6 Files :
----------
HotDrink.java(I)
-----------------
package com.ravi.loose_coupling;

public interface HotDrink


{
void prepare();
}

Tea.java
---------
package com.ravi.loose_coupling;

public class Tea implements HotDrink


{
@Override
public void prepare()
{
System.out.println("Preparing Tea");
}

Coffee.java
------------
package com.ravi.loose_coupling;

public class Coffee implements HotDrink


{
@Override
public void prepare()
{
System.out.println("Preparing Coffee");
}
}

Restaurant.java
---------------
package com.ravi.loose_coupling;

public class Restaurant


{
public static void createObject(HotDrink hd) //hd = new Tea()
{
hd.prepare();
}
}

Horlicks.java
--------------
package com.ravi.loose_coupling;

public class Horlicks implements HotDrink


{
@Override
public void prepare()
{
System.out.println("Preparing Horlicks");
}

Main.java
---------
package com.ravi.loose_coupling;

public class Main {

public static void main(String[] args)


{
Restaurant.createObject(new Tea());
Restaurant.createObject(new Coffee());
Restaurant.createObject(new Horlicks());
}

}
----------------------------------------------------------------------
It is always better to take method return type as interface so we can return any implementer class object
as shown in the example below

public HotDrink accept()


{

return new Tea() OR new Coffee() OR new Horlicks() OR any future


implementer class object...........................
}
-----------------------------------------------------------------------
03-01-2024
----------
Multiple Inheritance using interface :
--------------------------------------
Upto java 7, interface does not contain any method body that means all the methods are abstract method
so we can achieve multiple
inheritance by providing the logic in the implementer class as shown in the below program (Diagram
16-FEB-24)

In a class we have a constructor so, it is providing ambiguity issue but inside an interface we don’t have
constructor so multiple inheritance is possible using interface.

package com.ravi.mi;

interface A
{
void doSum(int x, int y);
}
interface B
{
void doSum(int x, int y);
}
class Implementer implements A,B
{
@Override
public void doSum(int x, int y)
{
System.out.println("Sum is :"+(x+y));
}
}
public class MultipleInheritance
{
public static void main(String[] args)
{
Implementer i = new Implementer();
i.doSum(12, 20);

}
----------------------------------------------------------------------
Extending interface :
---------------------
One interface can extends another interface, it cannot implement because interface cannot provide
implementation for the abstract method.

package com.ravi.mi;

interface Alpha
{
void m1();
}
interface Beta
{
void m2();
}

interface Gamma extends Alpha, Beta


{
void m3();
}

class Implement implements Gamma


{
@Override
public void m1()
{
System.out.println("m1 method");
}

@Override
public void m2()
{
System.out.println("m1 method");
}

@Override
public void m3()
{
System.out.println("m1 method");
}
}
public class ExtendingInterface
{
public static void main(String[] args)
{
Implement i = new Implement();
i.m1(); i.m2(); i.m3();
}

}
----------------------------------------------------------------------
java 8 features : (March 2014)
-----------------------------
Limitation of abstract method :
OR
Maintenance problem with interface in an Industry upto JDK 1.7
--------------------------------------------------------------
The major maintenance problem with interface is, if we add any new abstract method at the later stage of
development inside an existing interface then all the implementer classes have to override that abstract
method otherwise the implementer class will become as an abstract class so it is one kind of
boundation.

We need to provide implementation for all the abstract method available inside an interface whether it is
required or not?

To avoid this maintenance problem java software people introduced default method inside an interface.
-----------------------------------------------------------------------
What is default Method inside an interface?
------------------------------------------------
default method is just like concrete method which contains method body and we can write inside an
interface from java 8 onwards.

default method is used to provide specific implementation for the implementer classes which are
implmenting from interface because we can override default method inside the sub classes to provide our
own specific implementation.

*By using default method there is no boundation to override the default method in the sub class, if we
really required it then we can override to provide my own implementation.
by default, default method access modifier is public so at the time of overriding we should use public
access modifier.

4 files :
---------
Vehicle.java(I)
---------------
package com.nit.java8;

public interface Vehicle


{
void run();
void horn();

default void digitalMeter() //java 1.8


{
System.out.println("Digital Meter");
}
}

Car.java(C)
-----------
package com.nit.java8;

public class Car implements Vehicle


{
@Override
public void run()
{
System.out.println("Car is running");
}

@Override
public void horn()
{
System.out.println("Car horn");
}
@Override
public void digitalMeter() //java 1.8
{
System.out.println("Car is having digital meter");
}

Bike.java(C)
------------
package com.nit.java8;

public class Bike implements Vehicle


{
@Override
public void run()
{
System.out.println("Bike is running");
}

@Override
public void horn()
{
System.out.println("Bike horn");
}
}

Main.java(C)
------------
package com.nit.java8;

public class Main


{
public static void main(String[] args)
{
Vehicle v;
v = new Car(); v.run(); v.digitalMeter();
v = new Bike(); v.run();
}

}
---------------------------------------------------------------
The following program explains that default methods are having low priority than normal methods
(Concrete Method). class is having more power than interface.

package com.nit.interface_demo;

interface A
{
default void m1()
{
System.out.println("M1 method of interface A");
}
}
class B
{
public void m1()
{
System.out.println("M1 method of class B");
}
}
class C extends B implements A
{
}

public class InterfaceAndClass {

public static void main(String[] args)


{
new C().m1();
}

}
-----------------------------------------------------------------------
Can we override Object class method using default method?
---------------------------------------------------------
No, we cannot override object class method as a default method inside an interface.

interface Callable
{
public default String toString() //error
{
return "NIT";
}
}

public class OverridingObjectClass


{
public static void main(String[] args)
{

Note :- The above program will generate compilation error because we cannot override Object class
method as a default method inside an interface.
-----------------------------------------------------------------------
Can we achieve multiple inheritance in java using default method
-----------------------------------------------------------------
Multiple inheritance is possible in java by using default method inside an interface, here we need to use
super keyword to differenciate the super interface methods.

package com.nit.interface_demo;

interface I
{
default void m1()
{
System.out.println("m1 method of interface I");
}
}
interface J
{
default void m1()
{
System.out.println("m1 method of interface J");
}
}

class Implementer implements I,J


{

@Override
public void m1()
{
System.out.println("Overridden m1 method");
I.super.m1();
J.super.m1();
}
}

public class MultipleInheritanceUsingDefault


{
public static void main(String[] args)
{
Implementer i = new Implementer();
i.m1();
}

}
------------------------------------------------------------------------
What is static method inside an interface?
------------------------------------------
We can define static method inside an interface from java 1.8 onwards.

static method is only available inside the interface where it is defined that means we cannot invoke static
method from the implementer classes.

It is used to provide common functionality which we can apply/invoke from any ELC class.

By default static method of an inetrafce contains public access


modifier.
----------------------------------------------------------------------
Can we define main method inside an interface?
----------------------------------------------
Yes, we can define main method inside an interface and this main method will be executed without class.

package com.ravi.static_method;

public interface Loveable


{
public static void main(String [] args)
{
System.out.println("It will run without class");
}
}
-----------------------------------------------------------------------
Define static method inside an interface to achieve common functionality

package com.ravi.static_method;

interface Calculator
{
public static double doSum(int x, int y)
{
return (x+y);
}
public static double findSquare(int side)
{
return (side * side);
}
}

public class StaticCalculation implements Calculator


{
public static void main(String[] args)
{
double sum = Calculator.doSum(12, 14);
System.out.println("Sum is :"+sum);

double square = Calculator.findSquare(15);


System.out.println("Square is :"+square);

Note :- STATIC METHOD OF AN INTERFACE CAN BE CALL FROM INTERFACE NAME ONLY ONLY
-----------------------------------------------------------------------
Program that describes static method of an interface is NOT AVAILABLE to the implementer classes

interface Vehicle
{
static void move()
{
System.out.println("Static method of Vehicle");
}
}
class StaticMethod1 implements Vehicle
{
public static void main(String[] args)
{
Vehicle.move();
move(); //error

StaticMethod1.move(); //error

StaticMethod1 sm = new StaticMethod1();


sm.move(); //error

}
}

Note :- In the above program we will get compilation error because static method is available to Vehicle
interface only so, implementer class cannot invoke static method move.
-----------------------------------------------------------------------

Interface Static Method:


------------------------
a) Accessible using the interface name.
b) Cannot be overridden by implementing classes.
c) Can be called using the interface name only.

Class Static Method:


--------------------
a) Accessible using the class name.
b) Can be hidden (not overridden) in subclasses by redeclaring a static method with the same
signature.
c) Can be called using the super class, sub class name as well as sub class object also as shown in the
program below.

class A
{
public static void m1()
{
System.out.println("Static method A");
}
}
class B extends A
{

}
public class Demo
{
public static void main(String [] args)
{
B.m1(); //valid
new B().m1(); //valid
}
}
-----------------------------------------------------------------------
Anonymous inner class using interface concept :
-----------------------------------------------
package com.ravi.anonymous;

interface Worker
{
void work();
}

public class AnonymousDemo


{
public static void main(String[] args)
{
//Anonymous inner class
Worker manager = new Worker()
{
@Override
public void work()
{
System.out.println("Manager is working");
}
};

//Anonymous inner class


Worker hr = new Worker()
{
@Override
public void work()
{
System.out.println("HR is working");
}
};

//Anonymous inner class


Worker clerk = new Worker()
{
@Override
public void work()
{
System.out.println("Clerk is working");
}
};

manager.work(); hr.work(); clerk.work();

}
----------------------------------------------------------------------
05-01-2024
-----------
What is a functional interface?
-------------------------------
If an interface contains exactly one abstract method then that interface is known as Functional interface.

A functional interface will be represented by @FunctionalInterface


annotation.

A functional interface may contain ’n’ number of default and static methods but it must contain only one
abstract method.

Example :
----------
@FunctionalInterface
public interface Printable
{
void print(); //SAM [Single Abstract Method]

Program :
---------
AnonymousWithInterface.java
---------------------------
package com.ravi.functional_interface_demo;

@FunctionalInterface
interface Student
{
void writeExam();
}
public interface AnonymousWithInterface
{
public static void main(String[] args)
{
Student science = new Student()
{
@Override
public void writeExam()
{
System.out.println("Science students are Writing the Exam");
}
};

Student commerce = new Student()


{
@Override
public void writeExam()
{
System.out.println("Commerce students are Writing the Exam");
}
};
science.writeExam();
commerce.writeExam();
}
}
----------------------------------------------------------------------
-------------------
Lambda Expression :
----------------------
It is a new feature introduced in java from JDK 1.8 onwards.
It is an anonymous function i.e function without any name.
In java it is used to enable functional programming.
It is used to concise our code as well as we can remove boilerplate code.
It can be used with functional interface only.
If the body of the Lambda Expression contains only one statement then curly braces are optional.
We can also remove the variables type while defining the Lambda Expression parameter.
If the lambda expression method contains only one parameter then we can remove () symbol also.

In lambda expression return keyword is optional but if we use return keyword then {} are compulsory.

Independently Lamda Expression is not a statement.

It requires a target variable i.e functional interface reference only.

Lamda target can’t be class or abstract class, it will work with functional interface only.
--------------------------------------------------------------------
The following program explains Lambda target must be functional interface only.

@FunctionalInterface
interface Drawable
{
void draw();
}
public class Lambda
{
public static void main(String[] args)
{
()-> System.out.println("Drawing"); //error [target is reqd]
}
}

Note : Lambda target must be functional interface only.


------------------------------------------------------------------------
package com.ravi.functional_interface_demo;

@FunctionalInterface
interface Vehicle
{
void run();
}
public class Lambda1
{
public static void main(String[] args)
{
Vehicle car = ()-> System.out.println("Car is running");
car.run();

Vehicle bike = ()-> System.out.println("Bike is running");


bike.run();
}

------------------------------------------------------------------------
package com.ravi.functional_interface_demo;

@FunctionalInterface
interface Calculate
{
void doSum(int x, int y);
}

public class Lambda2


{
public static void main(String[] args)
{
Calculate c1 = (c ,d)-> System.out.println("Sum is :"+(c+d));
c1.doSum(12, 20);
}

}
------------------------------------------------------------------------
package com.ravi.functional_interface_demo;

@FunctionalInterface
interface Length
{
int getNameLength(String name);
}
public class Lambda3
{
public static void main(String[] args)
{
Length l = name-> name.length();

Scanner sc = new Scanner(System.in);


System.out.print("Enter your Name :");
String name = sc.next();

System.out.println("Length of "+name+" is :"+l.getNameLength(name));


sc.close();

}
}
------------------------------------------------------------------------
Working with Predefined interface :
------------------------------------
There is a predefined interface called Runnable available in java.lang package.
It contains only one abstract method i.e. run() so, it is a functional
interface.

@FunctionalInterface
public interface Runnable
{
public abstract void run();
}
------------------------------------------------------------------------
package com.ravi.functional_interface_demo;

public class Lambda4


{
public static void main(String[] args)
{
Runnable r1 = new Runnable()
{
@Override
public void run()
{
System.out.println("Anonymous class");
}

};
r1.run();

Runnable r2 = ()-> System.out.println("Anonymous Function");


r2.run();

}
------------------------------------------------------------------------
06-01-2024
-----------
Working with predefined Functional interface :
----------------------------------------------
What is type parameter?
---------------------------
It is a technique through which we can make our application indepenedent of data type. It is represented
by <T>

In java we can pass Wrapper classes as well as User-defined class to this type parameter.

We cannot pass any primitive type to this type parameter.

Program on Type Parameter :


---------------------------
TypeParameter.java
--------------------

package com.nit.type_parameter;

class Accept<T>
{
private T x;

public Accept(T x) //Student x


{
this.x = x;
}

public T getData()
{
return this.x;
}
}

public class TypeParameter


{
public static void main(String[] args)
{
Accept<Integer> intType = new Accept<Integer>(12);
System.out.println("Integer type is :"+intType.getData());

Accept<Double> doubleType = new Accept<Double>(90.67);


System.out.println("Double type is :"+doubleType.getData());

Accept<Boolean> boolType = new Accept<Boolean>(true);


System.out.println("Boolean type is :"+boolType.getData());

Accept<Student> studentType = new Accept<Student>(new Student());


System.out.println(studentType.getData());
}

class Student
{
@Override
public String toString()
{
return "Student toString method";
}
}
-----------------------------------------------------------------------
Working with predefined functional interfaces :
------------------------------------------------------
In order to help the java programmer to write concise java code in day to day programming java software
people has provided the following predefined functional interfaces

1) Predicate<T>
2) Consumer<T>
3) Function<T,R>
4) Supplier<T>
5) BiPredicate<T,U>
6) BiConsumer<T, U>
7) BiFunction<T,U,R>

Note :-
-------
All these predefined functional interfaces are provided as a part of java.util.function sub package.

Predicate<T> functional interface :


-------------------------------------------
It is a predefined functional interface available in java.util.function sub package.

It contains an abstract method test() which takes type parameter <T> and returns boolean value. The
main purpose of this interface to test one argument boolean expression.

@FunctionalInterface
public interface Predicate<T>
{
boolean test(T x);
}

Note :- Here T is a "type parameter" and it can accept any type of User defined class as well as Wrapper
class like Integer, Float, Double and so on.

We can’t pass primitive type.


------------------------------------------------------------------------
package com.ravi.predicate_demo;

import java.util.Scanner;
import java.util.function.Predicate;

public class PredicateDemo1


{
public static void main(String[] args)
{
//Verify a number is even or odd
Predicate<Integer> p1 = num -> num%2 ==0;
Scanner sc = new Scanner(System.in);
System.out.print("Enter a number :");
int num = sc.nextInt();
System.out.println(num +" is even ?"+p1.test(num));
sc.close();

}
------------------------------------------------------------------------
package com.ravi.predicate_demo;

import java.util.Scanner;
import java.util.function.Predicate;

public class PredicateDemo2


{
public static void main(String[] args)
{
//Verify my name starts with A or not
Predicate<String> p2 = str -> str.startsWith("A");

Scanner sc = new Scanner(System.in);


System.out.print("Enter Your name :");
String name = sc.next();

System.out.println(name +" starts with A ? :"+p2.test(name));


sc.close();
}

-----------------------------------------------------------------------
package com.ravi.predicate_demo;

import java.util.Scanner;
import java.util.function.Predicate;

public class PredicateDemo3 {

public static void main(String[] args)


{
Scanner sc = new Scanner(System.in);

//Verify my name is Ravi or not


Predicate<String> p3 = str -> str.equals("Ravi");
System.out.print("Enter your Name :");
String name = sc.next();
System.out.println("Are you Ravi ?"+p3.test(name));

//Verify a person is eligible for voting or not


Predicate<Integer> p4 = age -> age>=18;
System.out.print("Enter your Age :");
int age = sc.nextInt();
System.out.println("Are you eligible 4 vote :"+p4.test(age));
}

}
-----------------------------------------------------------------------
07-01-2024
----------
Consumer<T> functional interface :
-----------------------------------------
It is a predefined functional interface available in java.util.function sub package.

It contains an abstract method accept() and returns nothing. It is used to accept the parameter value or
consume the value.

@FunctionalInterface
public interface Consumer<T>
{
void accept(T x);
}
-----------------------------------------------------------------------
package com.ravi.consumer_demo;

import java.util.function.Consumer;

public class ConsumerDemo


{
public static void main(String[] args)
{
Consumer<Integer> conInt = num -> System.out.println("Integer value is :"+num);
conInt.accept(12);

Consumer<String> conString = str -> System.out.println("String value is :"+str);


conString.accept("NIT");

Consumer<Employee> conEmp = emp -> System.out.println(emp);


conEmp.accept(new Employee());
}

class Employee
{
@Override
public String toString()
{
return "To String method of Employee class";
}
}
----------------------------------------------------------------------
Function<T,R> functional interface :
-----------------------------------------
Type Parameters:
T - the type of the input to the function.
R - the type of the result of the function.
It is a predefined functional interface available in java.util.function sub package.

It provides an abstract method apply that accepts one argument(T) and produces a result(R).

Note :- The type of T(input) and the type of R(Result) both will be decided by the user.

@FunctionalInterface
public interface Function<T,R>
{
R apply(T x);
}
----------------------------------------------------------------------

package com.ravi.function_interface;

import java.util.Scanner;
import java.util.function.Function;

public class FunctionDemo


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);

//Finding the square of the number


Function<Integer,Integer> fn = num -> num*num;

System.out.print("Enter a number :");


int num = sc.nextInt();

System.out.println("Square of "+num+" is :"+fn.apply(num));


sc.close();

}
}
-----------------------------------------------------------------------

package com.ravi.function_interface;

import java.util.Scanner;
import java.util.function.Function;

public class FunctionDemo1


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
//Finding the length of the name

Function<String,Integer> fn = str -> str.length();

System.out.print("Enter your Name :");


String name = sc.next();

System.out.println("Length of "+name+ " is :"+fn.apply(name));


}

}
---------------------------------------------------------------------
package com.ravi.function_interface;

import java.util.Scanner;
import java.util.function.Function;

public class FunctionDemo1


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
//Finding the length of the name

Function<String,Integer> fn = str -> str.length();

System.out.print("Enter your Name :");


String name = sc.next();

System.out.println("Length of "+name+ " is :"+fn.apply(name));

}
----------------------------------------------------------------------
package com.ravi.function_interface;

import java.util.Scanner;
import java.util.function.Function;

public class FunctionDemo2


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
//Verify whether my name starts with ’A’ or not
Function<String,Boolean> fn = str -> str.startsWith("A");

System.out.println("Enter your Name :");


String name = sc.next();

System.out.println(name+" starts with A ? "+fn.apply(name));


sc.close();
}

}
-----------------------------------------------------------------
Supplier<T> prdefined functional interface :
--------------------------------------------
It is a predefined functional interface available in java.util.function sub package. It provides an abstract
method get() which does not take any argument but produces/supply a value of type T.
@FunctionalInterface
public interface Supplier<T>
{
T get();
}
-----------------------------------------------------------------------
package com.ravi.supplier;

import java.util.function.Supplier;

public class SupplierDemo3 {

public static void main(String[] args)


{
Supplier<String> sup = ()-> 89+90+"NIT"+67 + 67;
System.out.println(sup.get());
}

}
-----------------------------------------------------------------
package com.ravi.supplier;

import java.util.Scanner;
import java.util.function.Supplier;

class Employee
{
private Integer employeeId;
private String employeeName;
private Double employeeSalary;

public Employee(Integer employeeId, String employeeName, Double employeeSalary) {


super();
this.employeeId = employeeId;
this.employeeName = employeeName;
this.employeeSalary = employeeSalary;
}

@Override
public String toString() {
return "Employee [employeeId=" + employeeId + ", employeeName=" + employeeName + ",
employeeSalary="
+ employeeSalary + "]";
}
}

public class SupplierDemo


{
public static void main(String[] args)
{
Supplier<Employee> emp = ()->
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter Employee id ");
int id = sc.nextInt();
System.out.print("Enter Employee Name :");
String name = sc.nextLine();
name = sc.nextLine();
System.out.print("Enter Employee Salary :");
double sal = sc.nextDouble();

Employee e1 = new Employee(id, name, sal);

return e1;
};

Employee employee = emp.get();


System.out.println(employee);

}
-----------------------------------------------------------------------
package com.ravi.supplier;

import java.util.function.Supplier;

class Player
{
int playerId;
String playerName;

public Player(int playerId, String playerName)


{
super();
this.playerId = playerId;
this.playerName = playerName;
}

@Override
public String toString() {
return "Player [playerId=" + playerId + ", playerName=" + playerName + "]";
}
}

public class SupplierDemo2 {

public static void main(String[] args)


{
Supplier<Player> sup = ()-> new Player(111, "raj");
System.out.println(sup.get());

}
-----------------------------------------------------------------
BiPredicate<T,U> functional interface :
-----------------------------------
It is a predefined functional interface available in java.util.function sub package.

It is a functional interface in Java that represents a predicate (a boolean-valued function) OF TWO


ARGUMENTS.

The BiPredicate interface has method named test, which takes two parameters and returns a boolean
value, basically this BiPredicate is same with the Predicate, instead, it takes 2 arguments for the test.

@FunctionalInterface
public interface BiPredicate<T, U>
{
boolean test(T t, U u);
}

Type Parameters:

T - the type of the first argument to the predicate


U - the type of the second argument the predicate

import java.util.function.*;
public class Lambda11
{
public static void main(String[] args)
{

BiPredicate<String, Integer> filter = (x, y) ->


{
return x.length() == y;
};

boolean result = filter.test("Ravi", 4);


System.out.println(result);

result = filter.test("Hyderabad", 10);


System.out.println(result);
}
}
-----------------------------------------------------------------------
import java.util.function.BiPredicate;

public class Lambda12


{
public static void main(String[] args)
{
// BiPredicate to check if the sum of two integers is even
BiPredicate<Integer, Integer> isSumEven = (a, b) -> (a + b) % 2 == 0;

System.out.println(isSumEven.test(2, 3));
System.out.println(isSumEven.test(5, 7));
}
}
------------------------------------------------------------------
BiConsumer<T, U> functional interface :
---------------------------------------
It is a predefined functional interface available in java.util.function sub package.

It is a functional interface in Java that represents an operation that accepts two input arguments and
returns no result.

It takes a method named accept, which takes two parameters and performs an action without returning
any result.

@FunctionalInterface
public interface BiConsumer<T, U>
{
void accept(T t, U u);
}
-----------------------------------------------------------------------
import java.util.function.BiConsumer;

public class Lambda13


{
public static void main(String[] args)
{
BiConsumer<Integer, String> updateVariables = (num, str) -> {
num = num * 2;
str = str.toUpperCase();
System.out.println("Updated values: " + num + ", " + str);
};

int number = 15;


String text = "nit";

updateVariables.accept(number, text);

// Values after the update (note that the original values are unchanged)
System.out.println("Original values: " + number + ", " + text);
}
}
------------------------------------------------------------------
BiFunction<T, U, R> Functional interface :
---------------------------------
It is a predefined functional interface available in java.util.function sub package.

It is a functional interface in Java that represents a function that accepts two arguments and produces a
result.

The BiFunction interface has a method named apply that takes two arguments and returns a result.

@FunctionalInterface
public interface BiFunction<T, U, R>
{
R apply(T t, U u);
}
----------------------------------------------------------------------
import java.util.function.BiFunction;

public class Lambda14


{
public static void main(String[] args)
{
// BiFunction to concatenate two strings
BiFunction<String, String, String> concatenateStrings = (str1, str2) -> str1 + str2;

String result = concatenateStrings.apply("Hello", " Java");


System.out.println(result);
}
}
----------------------------------------------------------------------
08-01-2024
----------
Method Reference :
------------------
It is a new feature introduced from java 8 version.

It is used to concise our code.

We can use this technique in the body of Lambda expression just to refer an existing method (already
available method) to pass as an implementation of Functional interface.

Method reference using non static method :


------------------------------------------
3 Files :
----------
Worker.java(I)
---------------
package com.ravi.method_reference;

@FunctionalInterface
public interface Worker
{
void work();
}

Employee.java(C)
-----------------
package com.ravi.method_reference;

public class Employee


{
public void work()
{
System.out.println("Smith is working");
}
}

MethodReference.java(C)
-----------------------
package com.ravi.method_reference;

public class MethodReference


{
public static void main(String[] args)
{
//By using Lambda Expression
Worker w1 = () -> System.out.println("Scott is working");
w1.work();
//By Using Method Reference
Worker w2 = new Employee()::work ;
w2.work();

}
-----------------------------------------------------------------
Method reference using non static method using parameter :
----------------------------------------------------------
3 Files :
----------
Worker.java(I)
--------------
package com.ravi.method_reference;

@FunctionalInterface
public interface Worker
{
void work(double salary);
}

Employee.java(C)
---------------
package com.ravi.method_reference;

public class Employee


{
public void work(double salary)
{
System.out.println("Smith salary is = "+salary);
}
}

MethodReference.java(C)
-----------------------
package com.ravi.method_reference;

public class MethodReference


{
public static void main(String[] args)
{
Worker w = new Employee()::work ;
w.work(40000);

}
------------------------------------------------------------------
Can we override Object class method inside an interface as a default method ?

NO, we cannot override, Object class method as a default method inside an ineterface because interface
does not extends from Object class.

If interface will contain Object class method as a default method then for any implementer class it will be
confusion.

Printable.java
---------------
package com.ravi.method_reference;

public interface Printable


{
public default String toString() //Invalid not possible to override
{ java.lang.Object method
return "";
}
}
------------------------------------------------------------------
Does An Interface extends Object Class In Java.?
-------------------------------------------------
No Interface does not inherits Object class,but it provide accessibility to all methods of Object class.

This is because, for every public method in Object class, there is an implicit abstract and public method
declared in every interface which does not have direct super interfaces. (Java language Specification 9.2
about interface members)

package com.ravi.method_reference;

interface Drawable
{

}
public class ELC
{
public static void main(String[] args)
{
Drawable d = null;
d.toString();
d.equals(null);
d.hashCode();
d.getClass();
}

}
---------------------------------------------------------------------
package com.ravi.method_reference;

public interface Moveable


{
@Override
public String toString();
@Override
public int hashCode();

@Override
public boolean equals(Object obj);

@Override
public Class getClass(); //error becoz it is final method

}
---------------------------------------------------------------------
Can a functional interface contains the method of Object class?
---------------------------------------------------------------
Yes, Functional interface contains the method of Object class.

package com.ravi.method_reference;

@FunctionalInterface
public interface Moveable
{
@Override
public String toString();

@Override
public int hashCode();

@Override
public boolean equals(Object obj);

void m1();

}
------------------------------------------------------------------
Interface from java 9v version
-------------------------------
Yes, From java 9 onwards we can also write private static and private non-static methods inside an
interface.

These private methods will improve code re-usability inside interfaces.

For example, if two default methods needed to share common and confidential code, a private method
would allow them to do so, but without exposing that private method to its implementing classes.

Using private methods in interfaces have four rules :

1) private interface method cannot be abstract.


2) private method can be used only inside interface.
3) private static method can be used inside other static and non-static interface methods.
4) private non-static methods cannot be used inside private static methods.

----------------------------------------------------------------------
//Program that describes how many methods we can write inside interface upto java 9

package com.ravi.method_reference;
public interface Moveable
{
//abstract method
public abstract void m1();

//default method [1.8] //by default public


public default void m2()
{
System.out.println("It is a default method");
m4();
m5();
}

//static method [1.8] //by default public


public static void m3()
{
System.out.println("It is a Static method");
m4();

//private static method [Java 9]


private static void m4()
{
System.out.println("Private static method");
}

//private non static method [Java 9]


private void m5()
{
System.out.println("Private non static method");
}

}
----------------------------------------------------------------------
//Interface private Method

package com.ravi.method_reference;

interface Nine
{
public default void m1()
{
System.out.println("Default method m1");
common();
}

public default void m2()


{
System.out.println("Default method m2");
common();
}

private void common()


{
System.out.println("Common Data");
}

}
class JavaNine implements Nine
{

}
public class PrivateMethod {

public static void main(String[] args)


{
JavaNine jn = new JavaNine();
jn.m1();
jn.m2();

}
---------------------------------------------------------------------
09-01-2024
----------
What is marker interface in Java ?
-----------------------------------
If an interface does not contain any field or method then it is called Marker interface OR tag interface Or
Empty interface.

It is used to provide runtime type information regarding the object so, JVM is having additional information
regarding the obejct that is, Object is Cloneable (duplicate object is possible) and Object is Serializable
(Object data we can store in a file)

Note :- In java we have two predefined marker interface

1) java.lang.Cloneable
2) java.io.Serializable
-----------------------------------------------------------------------
*What is difference between abstract class and interface ?
------------------------------------------------------------------
The following are the differences between abstract class and interface.

1) An abstract class can contain instance variables but interface variables are by default public , static
and final

2) An abstract class can contain constructor but inside an interface we can’t define constructor

3) An abstract class can contain instance and static blocks but inside an interface we can’t define any
blocks.

4) Abstract class can’t refer Lambda expression but using Functional interface we can refer Lambda
Expression.

5) An abstract class can have state (properties) of an object but interface can’t have state of an object.

6) We can write concrete method inside an abstract class but inside an interface we can’t write concrete
method, only abstract , default and static methods are allowed.

Note :- From java 9v we can also write private method inside an interface.

From java 1.8 onwards interface is fully abstract or not?


---------------------------------------------------------
interface A
{
void m1();

default void m2()


{
m4();
m5();
}

public static void m3() // Implementer class cannot access it


{
}

private static void m4(){}

private void m5(){}

class B implements A
{
}

B b1 = new B();
b1.m2();

Note :- From java 8 we can define default method which describes the
default behavior of interface. By Writing the code in private method we can achieve 100 %
abstraction inside interface from java 9v.
--------------------OOPS ENDED----------------------------------------

10-01-2024
-----------
Class loader sub system with JVM Architecture :
------------------------------------------------------
The three main components of JVM

1) class loader sub system

2) Runtime Data Areas

3) Execution engine

class loader sub system internally performs 3 task

a) Loading b) Linking c) Initialization (Diagram 9th JAN)


Loading:
----------
In order to load the required .class file, JVM makes a request to class loader sub system. The class
loader sub system follows delegation hierarchy algorithm to load the required .class files from different
areas.

To load the required .class file we have 3 different kinds of class loaders.

1) Bootstrap/Primordial class loader

2) Extension/Platform class loader

3) Application/System class loader

Bootstrap/Primordial class Loader :-


---------------------------------
It is responsible to load the required .class file from java API that means all the predfined classes
(provided by java software people) .class file will be loaded by Bootstrap class loader.
It is the super class of Extension class loader as well as It has the highest priority among all the class
loader.

Extension/Platform class Loader :-


--------------------------------------
It is responsible to load the required .class files from ext (extension) folder. Inside the extension folder we
have jar file(Java level zip file) given by some third party or user defined jar file.
It is the super class of Application class loader as well as It has more priority than Application class
loader.

Note :- Command to create the jar file

jar cf NIT.jar FileName.class

Here FileName.class will be placed inside the jar file.

Application/System class Loader :-


--------------------------------------
It is responsible to load the required .class file from class path level i.e Environment variable. It has lowest
priority as well as It is the sub class of Extension/Platform class loader.

Note :-
------
If all the class loaders are failed to load the .class file into JVM memory then we will get a Runtime
exception i.e java.lang.ClassNotFoundException.
--------------------------------------------------------------------
The following program explains that Any .class file return type is java.lang.Class

DotClassReturnType.java
----------------------
package com.nit;

class Employee{}

class Student{}
class Customer{}

public class DotClassReturnType


{
public static void main(String[] args)
{
java.lang.Class cls = Employee.class;
System.out.println(cls.getName());

cls = Student.class;
System.out.println(cls.getName());

cls = Customer.class;
System.out.println(cls.getName());
}

---------------------------------------------------------------------
getClassLoader() is a predefined method of class called Class available in java.lang package and it’s
return type is ClassLoader.

The following explains that Application class loader is responsible to load userdefined .class file.

ClassLoaderInformation.java
----------------------------
package com.nit;

class Test
{
}
public class ClassLoaderInformation {

public static void main(String[] args)


{
System.out.println("Test.class file will be loaded by :"+Test.class.getClassLoader());

}
-----------------------------------------------------------------------
getParent() is a predefined method of ClassLoader class in java, available in java.lang package. It is an
abstract class.

Example :
----------
Student.class.getClassLoader().getParent()

getParent() method of ClassLoader class will provide the parent class name.

package com.nit;

class Player
{
}

public class ParentClassLoader {

public static void main(String[] args)


{
System.out.println("Parent of Application class Loader is :"+Player.class.getClassLoader().getParent());

System.out.println("Parent of Platform class Loader is


:"+Player.class.getClassLoader().getParent().getParent());

Note :- BootStrap class loader implemntation is not provided because


It is used to load predefined .class file.
-----------------------------------------------------------------------
Linking :
---------
verify :-
-------
It ensures the correctness of the .class files, If any suspicious activity is there in the .class file then It will
stop the execution immediately by throwing an exception i.e java.lang.VerifyError.

There is something called ByteCodeVerifier(Component of JVM), responsible to verify the loaded .class
file i.e byte code. Due to this verify module JAVA is highly secure language.

java.lang.VerifyError is the sub class of java.lang.linkageError


---------------------------------------------------------------------
prepare: (static variable memory allocation + Initialization )
--------
It will allocate the memory for all the static data members, here all the static data member will get the
default values so if we have
static int x = 100;

then for variable x memory will be allocated and now it will initialize with default value i.e 0.
-----------------------------------------------------------------------
Resolve :-
-----------
All the symbolic references will be converted to direct references or actual reference.

javap -verbose FileName.class

Note :- By using above command we can read the internal details of .class file.
----------------------------------------------------------------------
Initialization :-
-----------------
In Initialization, all the static data member will get their actual (Original) value as well as if any static block
is present in the class then the static block will start executing from here.
-----------------------------------------------------------------------
11-01-2024
-----------
Static Block :
--------------
It is a very special block which will be automatically executed at the time of loading the .class file into JVM
memory.

Example :
static
{
}

Static blocks are executed only once because class loading is possible only once.

The main purpose of static block to initialize the static data member of the class so it is also known static
initializer.

A blank static final variable can also be initialized through static block only.

If a class contains multiple static blocks then it will be executed according to the order.

Automatically static block will not be executed everytime, whenever class will be loaded (user request)
then only static block will be executed.

static block will be executed before main method or any static method.

The compiler will generate illegal forward reference, if a user try to access the static variable value from
static block without declaration.

[Without declaration of static variable, we can initialize the static variable inside static block (because
memory is already allocated in the prepare phase) but accessing of static variable is not possible]

----------------------------------------------------------------------
//static block
class Foo
{
Foo()
{
System.out.println("No Argument constructor..");
}

{
System.out.println("Instance block..");
}

static
{
System.out.println("Static block...");
}
}
public class StaticBlockDemo
{
public static void main(String [] args)
{
System.out.println("Main Method Executed ");

}
}
Note :- static block will not be executed because Foo.class file is
not loaded into JVM memory.
----------------------------------------------------------------------
//static blocks are executed according to the order.
class Test
{
static int x;

static
{
x = 100;
System.out.println("x value is :"+x);
}

static
{
x = 200;
System.out.println("x value is :"+x);
}

static
{
x = 300;
System.out.println("x value is :"+x);
}

static
{
x = 400;
System.out.println("x value is :"+x);
}
}
public class StaticBlockDemo1
{
public static void main(String[] args)
{
System.out.println(Test.x);
}
}
-----------------------------------------------------------------------
//static variables are initialized with default value

class Foo
{
static int x;

static
{
System.out.println("x value is :"+x);
}

public class StaticBlockDemo2


{
public static void main(String[] args)
{
new Foo();
}
}
-----------------------------------------------------------------------
//static blank final variable can’t be initialized by class loader in prepare phase, it must be initialized by
user, either at the time of declarartion or through static block.

class Demo
{

final static int a ; //blank final static variable

static
{
a = 100; //Initialization is compulsory
System.out.println(a);
}
}
public class StaticBlockDemo3
{
public static void main(String[] args)
{
System.out.println("a value is :"+Demo.a);
}
}
---------------------------------------------------------------------
Output
//AD BC EF
class A
{
static
{
System.out.println("A");
}

{
System.out.println("B");
}

A()
{
System.out.println("C");
}
}
class B extends A
{
static
{
System.out.println("D");
}
{
System.out.println("E");
}

B()
{
System.out.println("F");
}

}
public class StaticBlockDemo4
{
public static void main(String[] args)
{
new B();
}
}
-----------------------------------------------------------------------
//illegal forward reference

class Demo
{
static
{
i = 100; //Initialization is possible
// System.out.println(i); //Invalid, accessing is not possible
}

static int i;
}

public class StaticBlockDemo5


{

public static void main(String[] args)


{
System.out.println(Demo.i);
}
}
-----------------------------------------------------------------------
class Demo
{
static
{
i = 100; //before defining initialization is possible
}

static int i;
}

public class StaticBlockDemo6


{

public static void main(String[] args)


{
System.out.println(Demo.i);
}
}
-----------------------------------------------------------------------
class StaticBlockDemo7
{
static
{
System.out.println("Static Block");
}

public static void main(String[] args)


{
System.out.println("Main Method");
}
}

static block will be executed and then main method will be executed.
-----------------------------------------------------------------------
Can we execute a Java program without main method ?
---------------------------------------------------------------
We can’t execute a java program without main method, Upto jdk 1.6 it was possible to execute a java
program without main method by writing the static block.

From JDK 1.7 onwards now we can’t execute java program without main method because JVM verifies
the presence of the main method before initializing the class.

Eg:-
class WithoutMain
{
static
{
System.out.println("Hello world");
System.exit(0);
}
}
The above program was possible to execute upto JDK 1.6.
----------------------------------------------------------------------
How many ways we can load the .class file into JVM memory :
----------------------------------------------------------------
There are multiple ways to load the .class file into JVM memory.The following are the common examples
:-

1) By using java tools [java command]


2) By using Constructor [Object creation]
3) By accessing the static member of the class.
4) By using Inheritance
5) By Reflection API

1) By using Java tools


javac Test.java
java Test [Load the Test.class file into JVM memoy]
2) By using Constructor [Object creation]

3) By Calling static variable and static method using class name.

Program on class loading by constructor and static Member


---------------------------------------------------------
class Demo
{
static int x = 10;
static
{
System.out.println("Static Block of Demo class Executed!!! :"+x);
}
}
public class ClassLoading
{
public static void main(String[] args)
{
new Demo();
//System.out.println(Demo.x);
}
}
-----------------------------------------------------------------------
4) By Using Inheritance
----------------------------
When we create the Object for Sub class then, first of all super class .class file will be loaded then only
sub class .class file will be loaded.

Note :- Always Object is the first class to be loaded into JVM memory

class Alpha
{
static
{
System.out.println("Static Block of super class Alpha!!");
}
}
class Beta extends Alpha
{
static
{
System.out.println("Static Block of Sub class Beta!!");
}
}
class InheritanceLoading
{
public static void main(String[] args)
{
new Beta();
}
}
--------------------------------------------------------------------
19-01-2024
----------
5) By Reflection API (Explicit class loading)
-----------------------------------------------

Java software people has provided a predefined class called "Class" available in java.lang package.

This class called Class contains a predefined static method forName(String className), through which
we can load the required .class file into JVM memory dynamically.

It throws a checked exception i.e java.lang.ClassNotFoundException

Class.forName("com.ravi.Test"); //Fully Qualified Name


----------------------------------------------------------------
class Demo
{
static
{
System.out.println("Static Block of Demo class");
}
}
public class DynamicLoading
{
public static void main(String[] args) throws Exception
{
Class.forName("Demo");
}
}
--------------------------------------------------------------------
Program on Eclipse IDE (Fully Qualified Name required)

ClassLoading.java
------------------
package com.ravi.class_loading;

class Foo
{
static
{
System.out.println("static block of Foo class");
}
}

public class ClassLoading


{
public static void main(String[] args) throws Exception
{
System.out.println("Main method");
Class.forName("com.ravi.class_loading.Foo");

Note :- The return type of forName(String className) method is java.lang.Class. The method whose
return type is same class name is known as Factory Method.
Example :-

Class cls = Class.forName("Demo");


-------------------------------------------------------------------
*What is the limitation of ’new’ keyword ?
OR
What is the difference between new keyword and newInstance() method?
OR
How to create the Object for the classes which are coming dynamically from the database or from some
file.

The limitation with new keyword is, It demands the class name at the begning or at the time of compilation
so new keyword is not suitable to create the object for the classes which are coming from database or
files at runtime.

In order to create the object for the classes which are coming at runtime from database or files, we should
use newInstance() method available in java.lang.Class class.
-------------------------------------------------------------------
public class CreateObjectDynamically
{
public static void main(String [] args) throws Exception
{
Object obj = Class.forName(args[0]).newInstance();
System.out.println("Object created for :"+ obj.getClass().getName()+" class");
}
}

class Employee{}
class Player{}
class Customer{}

javac CreateObjectDynamically.java (Compilation)


java CreateObjectDynamically Employee

The above command will create the Object for Employee class
-------------------------------------------------------------------
//Program that describes how to call Manager class non static greet() method by creating the object
through newInstance() method

class Manager
{
public void greet()
{
System.out.println("Hello Manager, Good Evening");
}
}

public class CreateObjectDynamically


{
public static void main(String [] args) throws Exception
{
Object obj = Class.forName(args[0]).newInstance();
Manager m = (Manager) obj; // Down Casting

m.greet();
}
}
-------------------------------------------------------------------
* What is the difference between java.lang.ClassNotFoundException and
java.lang.NoClassDefFoundError :

java.lang.ClassNotFoundException :-
-----------------------------------------
It occurs when we try to load the required .class file at runtime by using Class.forName() statement or
loadClass() static of ClassLoader class and if the required .class file is not available at runtime then we
will get an exception i.e java.lang.ClassNotFoundException

Note :- It does not have any concern at compilation time, at run time, JVM will simply check whether the
required .class file is available or not.
----------------------------------------------------------------
class Foo
{
static
{
System.out.println("static block gets executed...");
}
}
public class ClassNotFoundExceptionDemo
{
public static void main(String[] args) throws ClassNotFoundException
{
Class.forName("Player");
}
}

If Player.class file is not available at runtime then we will get ClassNotFoundExcption


-------------------------------------------------------------------
java.lang.NoClassDefFoundError :
--------------------------------------
It occurs when the class was present at the time of COMPILATION but at runtime the required .class file
is not available(manually deleted by user) Or it is not available in the current directory (folder) then we will
get an exception i.e java.lang.NoClassDefFoundError.

class NIT
{
public void getEnrollment()
{
System.out.println("Enrollment Done");
}
}
public class NoClassDefFoundErrorDemo
{
public static void main(String[] args)
{
NIT n = new NIT();
n.getEnrollment();
}
}

From the above program if we delete NIT.class file manually then


we will get java.lang.NoClassDefFoundError.
Now we need to re-compile to get the NIT.class file back

So the conclusion is :
java.lang.ClassNotFoundException does not have any concern at compilation time where as
java.lang.NoClassDefFoundError was checking the class name at the time of compilation.
-------------------------------------------------------------------
20-01-2024
----------
Runtime Data Areas :
--------------------
a) Method Area :
-------------------
In this area all class level information is available. Actually the .class file is dumpped here hence we have
all kinds of information related to class is available like name of the class, name of the immediate super
class, package name, method name , variable name, static variable, all method available in that particular
class and so on.

This method area return type java.lang.Class class , this java.lang.Class class object can hold any .class
file
(Class c = AnyClass.class)

There is only one method area per JVM.


--------------------------------------------------------------------------
The following program explains how to get the complete information regarding the class.

2 files :
---------
Student.java
-------------
package com.ravi.class_information;

public class Student


{
int roll = 101;
String name = "Ravi";
String address = "Ameerpet";
static String collegeName = "NIT";

public Student() {}

public void input() {}

public void accept() {}

public void display() {}

public void show() {}


}

ClassDescription.java
----------------------
package com.ravi.class_information;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ClassDescription


{
public static void main(String[] args) throws Exception
{
Class cls = Class.forName(args[0]);

System.out.println("Class Name is :"+cls.getName());


System.out.println("Package Name is :"+cls.getPackageName());

System.out.println("Methods available in the class :");

Method[] methods = cls.getDeclaredMethods();


int count = 0;
for(Method method : methods)
{
System.out.println(method.getName());
count++;
}
System.out.println("Total Methods are :"+count);

System.out.println("Constructor Information");
Constructor[] constructors = cls.getDeclaredConstructors();
for(Constructor constructor : constructors)
{

System.out.println(constructor.getName());
}

System.out.println("Field Information :");

Field[] fields = cls.getDeclaredFields();


for(Field field : fields)
{
System.out.println(field.getName());
}

Note :- getDeclaredMethods() is a predefined method available in java.lang.Class class , the return type
of this method is Method array where Method is a predefined class available in java.lang.reflect sub
package
getDeclaredFieldss() is a predefined method available in java.lang.Class class , the return type of this
method is Field array where Method is a predefined class available in java.lang.reflect sub package

getDeclaredConstructors() is a predefined method available in java.lang.Class class , the return type of


this method is Constructor array where Method is a predefined class available in java.lang.reflect sub
package
-------------------------------------------------------------------------
b) HEAP memory :-
--------------------
It stores information regarding object and instance variables. All the objects are created as a part of
HEAP memory so automatically all the instance variables are also the part of HEAP memory.

There is only one HEAP area per JVM.


-------------------------------------------------------------------
c) Stack Area
--------------
All the methods are executed as a part of Stack Area.
We can have multiple Stack area per JVM.

Whenever we call a method then one STACK FRAME will be created, this Stack Frame is responsible to
hold local variable and parameter variable.
Once method execution is over then Stack frame will be deleted from the Stack.
Stacke Frame contains 3 parts
a) Local Variable
b) Frame Data
c) Operand Stack
-------------------------------------------------------------------------
Garbage Collector :-
----------------------
In older languages like C++, It is the responsibility of the programmer to allocate the memory as well as to
de-allocate the memory otherwise there may be chance of getting OutOfMemoryError

But in Java a user is not responsible to de-allocate the memory that means memory allocation is the
responsibility of user but memory de-allocation is automatically done by Garbage Collector.

Garbage collection is the process of looking at heap memory, identifying which objects are in use and
which are not in use, and deleting the unused objects (The object which does not contain any
references).

It is an automatic memory management in java. JVM internally contains a thread called Garbage collector
which is daemon thread, It is responsible to delete the unused objects or the objects which are not
containing any references in the heap memory.

Note :- GC uses an algorithm mark and sweep to make an un-used objects eligible for Garbage
Collection.

The garbage Collector thread is visiting our program at regular interval to delete the unused objects but
as a programmer we can call garbge collector explicitly to visit our program by using the following code.

System.gc(); //explicitly calling the garbage collector

gc() is a predefined static method of System class.


-----------------------------------------------------------------------
There are 3 ways to make an Object eligible for Garbage Collector:
----------------------------------------------------------------
1) Assigning a null literal to reference variable

Employee e1 = new Employee();


e1 = null;

2) Creating an object inside the method

public void createObject()


{
Employee e2 = new Employee();
}
Note :- Once the method execution is over automatically Object is eligible for Garbage Collector

3) Assigning new object to the Existing reference variable

Employee e3 = new Employee();

e3 = new Employee();
-----------------------------------------------------------------------
HEAP and STACK Diagram :
-----------------------
HEAP and STACK Diagram for Sample.java
--------------------------------------

public class Sample


{
private Integer i1 = 900;

public static void main(String[] args)


{
Sample s1 = new Sample();

Sample s2 = new Sample();

Sample s3 = modify(s2);

s1 = null;

//GC [4 Objects 1000x, 2000x, 5000x and 6000x are eligible]

System.out.println(s2.i1);
}
public static Sample modify(Sample s)
{
s.i1=9;
s = new Sample();
s.i1= 20;
System.out.println(s.i1);
s=null;
return s;
}
}

//20 9
----------------------------------------------------------------------
Heap and Stack diagram for Employee.java
-----------------------------------------
public class Employee
{
int id = 100;

public static void main(String[] args)


{
int val = 200;

Employee e1 = new Employee();

e1.id = val;

update(e1);

System.out.println(e1.id);

Employee e2 = new Employee();

e2.id = 500;

switchEmployees(e2,e1); //3000x 1000x

//GC [ 2 Objects are eligible 2000x and 4000x]

System.out.println(e1.id);
System.out.println(e2.id);
}

public static void update(Employee e)


{
e.id = 500;
e = new Employee();
e.id = 400;
}

public static void switchEmployees(Employee e1, Employee e2)


{
int temp = e1.id;
e1.id = e2.id; //500
e2 = new Employee();
e2.id = temp;
}
}
-----------------------------------------------------------------------
Heap and Stack diagram for Beta.java
------------------------------------
class Alpha
{
int val;
static int sval = 200;
static Beta b = new Beta();
public Alpha(int val)
{
this.val = val;
}
}

public class Beta


{
public static void main(String[] args)
{
Alpha am1 = new Alpha(9);
Alpha am2 = new Alpha(2);

Alpha []ar = fill(am1, am2);

ar[0] = am1;
System.out.println(ar[0].val);
System.out.println(ar[1].val);
}

public static Alpha[] fill(Alpha a1, Alpha a2)


{
a1.val = 15;

Alpha fa[] = new Alpha[]{a2, a1};

return fa;
}
}
-----------------------------------------------------------------------
PC Register :-
--------------
The Java Virtual Machine can support many threads of execution at once . Each Java Virtual Machine
thread has its own pc (program counter) register.

In order to hold the current executing instruction of a thread we use PC register. For a single JVM we can
have multiple PC Registers ecah PC register refers to a particular thread.
------------------------------------------------------------------------
Native method stack :-
--------------------------
For every thread in java a seperate native stack is created. It stores the native method information.

native code means the code written in native languages like C, C++ .
In order to convert java into native code language we need native method libraries.
-------------------------------------------------------------------
Interpreter :-
---------------
JVM stands for Java Virtual Machine. It is a software in the form of Interpreter written in ’C’ language.

The main purpose of JVM to load and execute the .class file.JVM has a component called class loader
subsystem responsible to load the required .class file as well as It allocates the necessary memory
needed by the java program.

JVM executes our program line by line. It is slow in nature (Execution is slow) so java software people
has provided a special compiler i.e JIT compiler to boost up the execution.
------------------------------------------------------------------------
JIT compiler :-
-----------------
It stands for just in time compiler. It is the part of JVM which boost the speed of execution of a java
program(boost up the execution).

It holds the frequently used instruction or repeated method instruction and make it available to the JVM at
the time of executing java program directly so the execution will become faster.
----------------------------------------------------------------------
23-01-2024
-----------
Exception Handling :
--------------------
What is an Exception
---------------------
An exception is an abnormal situation or an unexpected situation in a normal execution flow.

Due to an exception our execution of the program will be disturbed first and then terminated permanently.

An exception occurs due to dependency, when one part of the program is dependent to another part in
order to complete the task then there might be a chance of getting an exception.

EXCEPTION ALSO OCCURS DUE TO THE WRONG INPUT GIVEN BY THE USER.

Note :- Exception always occurs at runtime only.

Exception Hierarchy :-
--------------------
(Diagram is available in paint window = Exception_Hierarchy)

As a developer we are responsible to handle the exception where as errors are taken care by System
admin because error we can not recover where as Exception we can recover that means we can handle.
-----------------------------------------------------------------
Note :-
Exception is the super class of all the exceptions we have in java whether it is a predefined Exception or
userdefined Exception
-----------------------------------------------------------------
Criteria of Exception in java :
---------------------------------
Java software people has provided some predefined classes for some specific exception criteria :

1) java.lang.ArithmeticException

Whenever we try to divide a number by 0 (an int value) then we will get java.lang.ArithmeticException

int x = 100;
int y = 0;
int z = x/y; //ArithmeticException

2) java.lang.ArrayIndexOutOfBoundsException

Whenever we try to access the index of an array which is not available then we will get
java.lang.ArrayIndexOutOfBoundsException
int []arr = {10,20};
System.out.println(arr[2]);

3) java.lang.NullPointerException
Whenever we try to call a method on null then we will get java.lang.NullPointerException

String str = null;


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

4) java.lang.NumberFormatException
Whenever we try to convert String into integer but the given String is not in a proper format then we will
get java.lang.NumberFormatException

String str = "ravi";


int no = Integer.parseInt(str);
System.out.println(no);

5) java.lang.NegativeArraySizeException
Whenever we pass the array size in negative then it will generate java.lang.NegativeArraySizeException

int []arr = new int[-2];

6) java.lang.ArrayStoreException
Whenever we try to insert wrong data in the Array then we will get
java.lang.ArrayStoreException

Object [] arr = new String[3];


arr[0] = "NIT";
arr[1] = "HYD";
arr[2] = 90;

---------------------------------------------------------------------
WAP in java that describes Exception is the super class of all the Exceptions we have in java

package com.racvi.treemap_comparator;

public class ExceptionTest {

public static void main(String[] args)


{
Exception e1 = new ArithmeticException();
System.out.println(e1);

Exception e2 = new ArrayIndexOutOfBoundsException();


System.out.println(e2);
}

}
---------------------------------------------------------------------
WAP that describes whenever an exception will encounter the execution of the program will halt in the
middle.

package com.racvi.treemap_comparator;
import java.util.Scanner;

public class ExceptionTest {

public static void main(String[] args)


{
System.out.println("Main Started");

Scanner sc = new Scanner(System.in);


System.out.print("Enter the value of x :");
int x = sc.nextInt();

System.out.print("Enter the value of y :");


int y = sc.nextInt();

int result = x/y;


System.out.println("Result is :"+result);

System.out.println("Main method ended");


sc.close();
}

Note :- In the above program whenever the value of y is 0(zero) then our program will halt in the middle
and it is an abnormal termination.
Here the program will halt in the middle, JVM has a default Exception handler, this handler will generate
a message i.e java.lang.ArithmeticException and it will terminate the program abnormally
----------------------------------------------------------------------
In order to work with Exception handling mechanism, OOP has provided the following keyword which are
as below

1) try
2) catch
3) finally (try with resources available from 1.7)
4) throw
5) throws
----------------------------------------------------------------------
Some Key points to remember :
--------------------------------
-> With try block we can write either catch block or finally block or both.
-> In between try and catch we can’t write any kind of statement.
-> try block will trace our program line by line.
-> If we have any exception inside the try block, try block will automatically create the appropriate
Exception object and then throw the Exception Object to the nearest catch block.
-> In the try block whenever we get an exception the control will directly jump to the nearest catch block
and the remaining code of try block will not be executed.
-> catch block is responsible to handle the exception.
-> catch block will only execute if there is an exception inside try block.
----------------------------------------------------------------
try :-
-----
Whenever our statement is error suspecting statement or Risky code then put that statement inside the
try block.
The try block will trace the program line by line and if any exception occurs then It will automatically
create the appropriate exception object and throw the exception object to the nearest catch block.

try block must be followed either by catch block or finally block or both. In between the try-catch we can’t
write any kind of statement.

The line in the try block where we got the exception after that line the remaining code in the try block will
never be executed.

---------------------------------------------------------------------
catch :
-------
The main purpose of catch block to handle the exception which is thrown by try block.

The catch block will only execute if there is an exception inside the try block otherwise catch block will not
be executed.
-----------------------------------------------------------------------
Program that describes, if we use try catch then our program will beterminated noramally even we have
an exception

package com.ravi.basic;

import java.util.Scanner;

public class TryDemo {

public static void main(String[] args)


{
System.out.println("Main method started....");
Scanner sc = new Scanner(System.in);

try
{
System.out.print("Enter the value of x :");
int x = sc.nextInt();

System.out.print("Enter the value of y :");


int y = sc.nextInt();

int result = x/y;


System.out.println("Result is :"+result);

}
catch(Exception e)
{
System.err.println(e);
}
System.out.println("Main method ended....");
sc.close();
}
}

In the above program we have normal termination.


----------------------------------------------------------------------
class Test
{
public static void main(String[] args)
{
try
{

System.out.println(10/0);
//throw new ArithmeticException("Divide by Zero");

}
catch (Exception e)
{
System.err.println(e);
}

}
}

Note :- From the above code it is clear that, try block is responsible
to create and throw the exception object implicitly.

------------------------------------------------------------------------
package com.ravi.basic;

import java.util.Scanner;

public class CustomerDemo


{
public static void main(String[] args)
{
System.out.println("Hello Client, Welcome to my application");
Scanner sc = new Scanner(System.in);

try
{
System.out.print("Enter the value of x :");
int x = sc.nextInt();

System.out.print("Enter the value of y :");


int y = sc.nextInt();

int result = x/y;


System.out.println("Result is :"+result);

}
catch(Exception e)
{
System.err.println("Please don’t provide zero");
}
System.out.println("Thank you for using my application..");
sc.close();
}
}

Note :- The main purpose of exception handling to provide user-friendly messages to our client as shown
in the above program.
----------------------------------------------------------------------
Methods of Throwable class :
----------------------------
1) public String getMessage() :- Predefined method of Throwable class which provides only message
details from the exception.

2) public void printStackTrace() :- Predefined method of Throwable class which provides complete details
like package name, class name , exception message, file name, method name and exception location
(line number)

package com.ravi.basic;

public class PrintStackTrace


{
public static void main(String[] args)
{
System.out.println("Main method started...");
try
{
String x = "Ravi";
int y = Integer.parseInt(x);
System.out.println(y);
}
catch(Exception e)
{
e.printStackTrace(); //For complete Exception details
System.out.println("---------------------------");
System.out.println("............................");
System.err.println(e.getMessage()); //only for Exception message
}
System.out.println("Main method ended...");

}
-----------------------------------------------------------------------
Working with Specific exception :
--------------------------------------
In order to the handle the exception in the catch block we can write Exception super class OR we can
also write appropriate type of exception like ArithmeticException, ArrayIndexOutOfBoundsException and
so on.
-----------------------------------------------------------------
package com.ravi.basic;

import java.util.InputMismatchException;
import java.util.Scanner;

public class SpecificException


{
public static void main(String[] args)
{
System.out.println("Main started");

Scanner sc = new Scanner(System.in);

try
{
System.out.print("Enter your Roll :");
int roll = sc.nextInt();
System.out.println("Your Roll is :"+roll);
}
catch(InputMismatchException e)
{
System.err.println("Input is not in proper format");
}
sc.close();
System.out.println("Main ended");
}
}

While reading the data from the user, if user will enter anything apart from numeric value then it will
generate InputMismatchException, predefined class availale in java.util package
----------------------------------------------------------------------
25-01-2024
-----------
Working with Infinity and Not a number(NaN) :
---------------------------------------------
10/0 -> Infinity (Java.lang.ArithmeticException)
10/0.0 -> Infinity

0/0 -> Undefined (Java.lang.ArithmeticException)


0/0.0 -> Undefined (NaN)

While working with Integral literal in both the cases i.e Infinity (10/0) and Undefined (0/0) we will get
java.lang.ArithmeticException because java software people has not provided any final variable support to
deal with Infinity and Undefined.

On the other hand while working with floating point literal in the both cases i.e Infinity (10/0.0) and
Undefined (0/0.0) we have final variable support so the program will not be terminated in the middle which
are as follows

10/0.0 = POSITIVE_INFINITY
-10/0.0 = NEGATIVE_INFINITY
0/0.0 = NaN
----------------------------------------------------------------------
InfinityFloatingPoint.java
---------------------------
package com.ravi.basic;

public class InfinityFloatingPoint


{
public static void main(String[] args)
{
System.out.println("Main Started");
System.out.println(10/0.0);
System.out.println(-10/0.0);
System.out.println(0/0.0);
System.out.println(10/0);
System.out.println("Main Ended");
}

}
----------------------------------------------------------------------
Working with multiple try catch :
---------------------------------
According to our application requirement we can provide multiple try-catch in my application to work with
multiple execptions.

package com.ravi.basic;
public class MultipleTryCatch
{
public static void main(String[] args)
{
System.out.println("Main method started!!!!");

try
{
int arr[] = {10,20,30};
System.out.println(arr[3]);
}
catch(ArrayIndexOutOfBoundsException e)
{
System.err.println("Array is out of limit!!!");
}

try
{
String str = null;
System.out.println(str.length());
}
catch(NullPointerException e)
{
System.err.println("ref variable is pointing to null");
}

System.out.println("Main method ended!!!!");


}
}
-----------------------------------------------------------------------
* Multiple catch block with single try block :
--------------------------------------------
According to industry standard we should write try with multiple catch block so we can provide proper
information for each and every exception.

While working with multiple catch block always the super class catch block must be last catch block.

From java 1.7 this multiple catch block we can also represent by using | symobl.
-----------------------------------------------------------------------
package com.ravi.basic;
public class MultyCatch
{
public static void main(String[] args)
{
System.out.println("Main Started...");
try
{
int c = 10/0;
System.out.println("c value is :"+c);

int []x = {12,78,56};


System.out.println(x[5]);
}

catch(ArrayIndexOutOfBoundsException e1)
{
System.err.println("Array is out of limit...");
}
catch(ArithmeticException e1)
{
System.err.println("Divide By zero problem...");
}
catch(Exception e1)
{
System.out.println("General");
}
System.out.println("Main Ended...");
}
}

Note :- In the try block if we have multiple exceptions then try block will will entertain only the first
exception.
-----------------------------------------------------------------------
package com.ravi.basic;

public class MultyCatch1


{
public static void main(String[] args)
{
System.out.println("Main method started!!!");
try
{
String str1 = "India";
System.out.println(str1.toUpperCase());

String str2 = "Ravi";


int x = Integer.parseInt(str2);
System.out.println("Number is :"+x);
}
catch(NumberFormatException | NullPointerException e)
{
e.printStackTrace();
}

System.out.println("Main method ended!!");


}
}
-----------------------------------------------------------------------
finally block :
---------------
finally is a block which is meant for Resource handling purposes.

According to Software Engineering, the resources are memory creation, buffer creation, opening of a
database, working with files, working with network resourses and so on.

Whenever the control will enter inside the try block always the finally block would be executed even we
don’t have catch block Or finally block is containing ant retun statement.

We should write all the closing statements inside the finally block because irrespective of exception finally
block will be executed every time.

If we use the combination of try and finally then only the resources will be handled but not the execption,
on the other hand if we use try-catch and finally then execption and resourses both will be handled.

FinallyBlock.java
------------------
package com.ravi.basic;

public class FinallyBlock


{
public static void main(String[] args)
{
System.out.println("Main method started");

try
{
System.out.println(10/0);
}
finally
{
System.out.println("Finally Block");
}

System.out.println("Main method ended");


}

Note :- In the above program we are handling only the resource.


----------------------------------------------------------------------
package com.ravi.basic;

public class FinallyWithCatch


{
public static void main(String[] args)
{
try
{
int []x = new int[-2]; //We can’t pass negative size of an array in negative
x[0] = 12;
x[1] = 15;
System.out.println(x[0]+" : "+x[1]);
}
catch(NegativeArraySizeException e)
{
System.err.println("Array Size is in negative value...");
}
finally
{
System.out.println("Resources will be handled here!!");
}
System.out.println("Main method ended!!!");
}
}

Note :- In the above program we are handling both i.e Exception and resource.
-----------------------------------------------------------------------
26-01-2024
----------
Limitation of finally block :
-----------------------------
The following are the limitations of finally block :

1) User is responsible to close the resources manually.


2) Due to finally block the length of the code will be increased.
3) While using finally block we should declare all our resources
outside of the try block otherwise the resourses will become
block level variable.

package com.ravi.finally_demo;

import java.util.InputMismatchException;
import java.util.Scanner;

public class FinallyLimitation


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
try
{
System.out.print("Enter Roll Number :");
int roll = sc.nextInt();
System.out.println("Your Roll Number is :"+roll);

}
catch(InputMismatchException e)
{
System.err.println("Input is Invalid");
}
finally
{
System.out.println("Finally Block executed");
sc.close();
}
}

}
-------------------------------------------------------------------------
try with resources :
--------------------
To avoid all the limitation of finally block, Java software people introduced a separate concept i.e try with
resources from java 1.7 onwards.

Case 1:
-------
try(resource1 ; resource2) //Only the resources will be handled
{
}

Case 2 :
----------
//Resources and Exception both will be handled
try(resource1 ; resource2)
{
}
catch(Exception e)
{
}

There is a predefined interface available in java.lang package called AutoCloseable which contains
predefined abstract method i.e close() which throws Exception.

There is another predefined interface available in java.io package called Closeable, this Closeable
interface is the sub interface for Auto Closeable interface.

public interface java.lang.AutoCloseable


{
public abstract void close() throws Exception;
}
public interface java.io.Closeable extends java.lang.AutoCloseable
{
void close() throws IOException;
}

Whenever we pass any resourse class as part of try with resources then that class must implements
either Closeable or AutoCloseable interface so, try with resourses will automatically call the respective
class
close() method even an exception is encountered in the try block.

try(ResourceClass rc = new ResourceClass())


{
}
catch(Exception e)
{

//This ResourceClass must implements either Closeable or AutoCloseable interface so, try block will
automatically call the close() method.
The following program explains how try block is invoking the close() method available in
DatabaseResource class and FileResource class.

3 Files :
---------
DatabaseResource.java
---------------------
package com.ravi.try_with_resource;

public class DatabaseResource implements AutoCloseable


{
@Override
public void close() throws Exception
{
System.out.println("Database close method invoked");
}

FileResource.java
------------------
package com.ravi.try_with_resource;

import java.io.Closeable;
import java.io.IOException;

public class FileResource implements Closeable


{
@Override
public void close() throws IOException
{
System.out.println("File close method invoked");
}

Main.java
----------
package com.ravi.try_with_resource;

public class Main {

public static void main(String[] args) throws Exception


{
DatabaseResource dr = new DatabaseResource();
FileResource fr = new FileResource();

try(dr ; fr)
{
System.out.println(10/0);
}
catch(ArithmeticException e)
{
System.err.println("Divide by zero prob..");
}

System.out.println("Main method ended");


}

Note :- In the parameter of try, we have passed two resource classes references i.e DatabaseResource
and FileResource.

Now try block is resposible to call the close() automatically even we have an exception in the try block.
-----------------------------------------------------------------------
package com.ravi.try_with_resource;

import java.util.InputMismatchException;
import java.util.Scanner;

public class TryWithResources


{
public static void main(String[] args)
{
System.out.println("Main method started");
Scanner sc = new Scanner(System.in);

try(sc)
{
System.out.print("Enter your Roll number :");
int roll = sc.nextInt();
System.out.println("Your roll number is :"+roll);
}
catch(InputMismatchException e)
{
System.err.println("Input is not valid");
}
System.out.println("Main method ended");
}
}

Note :- Scanner class internally implementing Closeable interface so it is providing auto closing facility, as
a user we need to pass the reference of Scanner class inside try with resources try()
-------------------------------------------------------------------------
27-01-2024
----------
Nested try block :
------------------
If we write a try block inside another try block then it is called Nested try block.

try //Outer try


{
statement1;
try //Inner try
{
statement2;
}
catch(Exception e) //Inner catch
{
}

}
catch(Exception e) //Outer Catch
{
}

The execution of inner try block depends upon outer try block that means if we have an exception in the
Outer try block then inner try block will not be executed.
-------------------------------------------------------------------------
package com.ravi.basic;

public class NestedTryBlock


{
public static void main(String[] args)
{
try //outer try
{
String x = null;
System.out.println("It’s length is :"+x.length());

try //inner try


{
String y = "NIT";
int z = Integer.parseInt(y);
System.out.println("z value is :"+z);
}
catch(NumberFormatException e)
{
System.err.println("Number is not in a proper format");
}
}
catch(NullPointerException e)
{
System.err.println("Null pointer Problem");
}
}
}
------------------------------------------------------------------------
Writing try-catch inside catch block :
---------------------------------------
We can write try-catch inside catch block but this try-catch block will be exceuted if the catch block will
execute that means if we have an exception in the try block.

package com.ravi.basic;

import java.util.InputMismatchException;
import java.util.Scanner;

public class TryWithCatchInsideCatch


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);

try(sc )
{
System.out.print("Enter your Roll number :");
int roll = sc.nextInt();
System.out.println("Your Roll is :"+roll);

}
catch(InputMismatchException e)
{
System.err.println("Provide Valid input!!");

try
{
System.out.println(10/0);
}
catch(ArithmeticException e1)
{
System.err.println("Divide by zero problem");
}

}
}

}
-----------------------------------------------------------------
try-catch with return statement
-------------------------------
If we write try-catch block inside a method and that method is returning some value then we should write
return statement in both the places i.e inside the try block as well as inside the catch block.

We can also write return statement inside the finally block only, if the finally block is present. After this
return statement we cannot write any kind of statement. (Unrechable)

Always finally block return statement having more priority then try-catch return statement.
------------------------------------------------------------------------
package com.ravi.advanced;
public class ReturnExample
{
public static void main(String[] args)
{
System.out.println(methodReturningValue());
}

public static int methodReturningValue()


{
try
{
System.out.println("Try block");
return 10;
}
catch (Exception e)
{
System.out.println("catch block");
return 20; //return statement is compulsory
}

}
}
-------------------------------------------------------------------------
package com.ravi.advanced;

public class ReturnExample1 {

public static void main(String[] args)


{
System.out.println(m1());
}

public static int m1()


{
try
{
System.out.println("Inside try");
}
catch(Exception e)
{
System.out.println("Inside Catch");
}
finally
{
System.out.println("Inside finally");
return 10;
}
}
}

We have return keyword in the program then after this return keywoyd, outside of the finally block we
cannot write any kind of statement.
------------------------------------------------------------------------
package com.ravi.advanced;

public class ReturnExample1 {

public static void main(String[] args)


{
System.out.println(m1());
}

@SuppressWarnings("finally")
public static int m1()
{
try
{
System.out.println("Inside try");
return 100;
}
catch(Exception e)
{
System.out.println("Inside Catch");
return 200;
}
finally
{
System.out.println("Inside finally");
return 300;
}

}
}

finally block return statement is having more priority than try-catch return statement.
------------------------------------------------------------------------
Initialization of a variable in try and catch :
-----------------------------------------------
A local variable must be initialized inside try block as well as catch block OR at the time of declaration.

If we initialize inside the try block only then from catch block we cannot access local variable value, Here
initialization is compulsory inside catch block.

package com.ravi.basic;

public class VariableInitialization


{
public static void main(String[] args)
{
int x;
try
{
x = 12;
System.out.println(x);
}
catch(Exception e)
{
x = 15;
System.out.println(x);
}

System.out.println("Main completed!!!");
}

}
-------------------------------------------------------------------------
* Difference between Checked Exception and Unchecked Exception :
----------------------------------------------------------------
Checked Exception :
----------------------
In java some exceptions are very common exceptions are called Checked excption here compiler takes
very much care and wanted the clarity regarding the exception by saying that, by using this code you may
face some problem at runtime and you did not report me how would you handle this situation at runtime
are called Checked exception, so provide either try-catch or declare the method as throws.
All the checked exceptions are directly sub class of java.lang.Exception

Eg:
---
FileNotFoundException, IOException, InterruptedException,ClassNotFoundException, SQLException,
CloneNotSupportedException and so on

Unchecked Exception :-
--------------------------
The exceptions which are rarely occurred in java and for these kinds of exception compiler does not take
any care are called unchecked exception.

Unchecked exceptions are directly entertain by JVM because they are rarely occurred in java.

All the un-checked exceptions are sub class of RuntimeException

Eg:
---
ArithmeticException, ArrayIndexOutOfBoundsException, NullPointerException, NumberFormatException,
ClassCastException, ArrayStoreException and so on.
-----------------------------------------------------------------
Some Bullet points regarding Checked and Unchecked :
-----------------------------------------------------
Checked Exception :
------------------
1) Common Exception
2) Compiler takes care (Will not compile the code)
3) Handling is compulsory (try-catch OR throws)
4) Directly the sub class of java.lang.Exception

Unchecked Exception :
----------------------
1) Rare Exception
2) Comiler will not take any care
3) Handling is not Compulsory
4) Sub class of RuntimeException
--------------------------------------------------------------------------
When to provide try-catch or declare the method as throws :-
---------------------------------------------------------------------
We should provide try-catch if we want to handle the exception by own as well as if we want to provide
user-defined messages to the client but on the other hand we should declare the method as throws when
we are not interested to handle the exception and try to send it to the JVM for handling purpose.

Note :- It is always better to use try catch so we can provide appropriate user defined messages to our
client.
-------------------------------------------------------------------------
*Why compiler takes very much care regarding the checked Exception ?
---------------------------------------------------------------------
As we know Checked Exceptions are very common exception so in case of checked exception "handling
is compulsory" because checked Exception depends upon other resources as shown below.

IOException (we are depending upon System Keyboard OR Files )


FileNotFoundException(We are depending upon the file)
InterruptedException (Thread related problem)
ClassNotFoundException (class related problem)
SQLException (SQL related or database related problem)
CloneNotSupportedException (While creating clone object support is required)
---------------------------------------------------------------------------
* What is the difference between throw and throws :
----------------------------------------------------
throw :
--------
In case of predefined exception, try block is responsible to create the exception object and throw the
exception object to the nearest catch block but it works with predefined exception only.

If a user wants to throw an exception based on his own requirement and specification by using
userdefined exception then we should write throw keyword to throw the user defined exception object
explicitly. (throw new LowBalanceException())

THROWING THE EXCEPTION OBJCET EXPLICITLY.

throws :-
---------
In case of checked Exception if a user is not interested to handle the exception and wants to throw the
exception to JVM, wants to skip from the current situation then we should declare the method as throws.
It is mainly used to work with Checked Exception.
--------------------------------------------------------------------------

Types of exception in java :


-------------------------------
Exception can be divided into two types :

1) Predefined Exception OR Built-in Exception

2) Userdefined Exception OR Custom Exception

Predefined Exception :-
-------------------------
The Exceptions which are already defined by Java software people for some specific purposes are called
predefined Exception or Built-in exception.
Ex :
----
IOException, ArithmeticException and so on

Userdefined Exception :-
---------------------------
The exceptions which are defined by user according to their own use and requirement are called
User-defined Exception.

Ex:-
----
InvalidAgeException, GreaterMarksException
----------------------------------------------------------------------
30-01-2024
-----------
Steps to create userdefined exception :
------------------------------------------
In order to create user defined exception we should follow the following steps.
1) A userdefined exception class must extends either Exception(Checked Exception) Or
RuntimeException(Unchecked Exception) as a super class.

a) If our userdefined class extends RuntimeException that menas we are creating


UncheckedException.

b) If our userdefined class extends Exception that menas we are creating checkedException and
exception handling is compulsory here.

2) The user-defined class must contain No argument constructor as well as parameterized construtor(in
case we want to pass some userdefined message).

We should take No argument constructor if we don’t want to send any message where as we should
take parameterized constructor with super keyword if we want to send the message to the super class.

3) We should use throw keyword to throw the Exception object explicitly.


---------------------------------------------------------------------
Program on Checked Exception that describes user is eligible for
Voting app or not ?

UserdefinedCheckedException.java
--------------------------------

package com.ravi.custom_exception;

import java.util.Scanner;

class InvalidAgeException extends Exception


{
public InvalidAgeException()
{
}

public InvalidAgeException(String message)


{
super(message);
}
}

public class UserdefinedCheckedException


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);

try(sc)
{
System.out.print("Enter your Age :");
int age = sc.nextInt();

if(age < 18)


{
throw new InvalidAgeException("Age is Invalid");
}
else
{
System.out.println("Welcome to voting app");

}
}
catch(InvalidAgeException e)
{
System.err.println(e);
System.out.println(e.getMessage());
}

}
---------------------------------------------------------------------
Program on unchecked Exception that describes marks is valid or not

UserdefinedUncheckedException.java
-----------------------------------
package com.ravi.custom_exception;

import java.util.Scanner;

class InvalidMarksException extends RuntimeException


{
public InvalidMarksException()
{

public InvalidMarksException(String errorMessage)


{
super(errorMessage);
}
}

public class UserdefinedUncheckedException


{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
try(sc)
{
System.out.print("Enter your Marks :");

int marks = sc.nextInt();

if(marks > 100)


{
throw new InvalidMarksException("Marks is Invalid");
}
else
{
System.out.println("Your Marks is :"+marks);
}
}
catch(Exception e)
{
System.err.println(e);
}
System.out.println("Main method completed");
}

}
---------------------------------------------------------------------
Some important rules to follow :
---------------------------------
a) If the try block does not throw any checked exception then in the corresponding catch block we can’t
handle checked exception.It will generate compilation error i.e "exception never thrown from the
corresponding try statement"

Example :-

try
{
//try block is not throwing any checked Exception
}
catch(IOException e) //Error
{

Program :
---------
package com.ravi.method_related_rule;

import java.io.IOException;

public class CatchingCheckedWithoutThrow


{
public static void main(String[] args)
{
try
{
//throw new IOException();
}
catch(IOException e) //error
{
System.err.println("Input Output Exception");
}

}
----------------------------------------------------------------------
b) If the try block does not throw any exception then in the corresponding catch block we can write
Exception, Throwable because both are the super classes for all types of Exception whether it is checked
or unchecked.

CatchingWithSuperClass.java
-----------------------------
package com.ravi.method_related_rule;

public class CatchingWithSuperClass


{
public static void main(String[] args)
{
try
{
//throw new IOException();
}
catch(Exception e)
{
e.printStackTrace();
}

}
---------------------------------------------------------------------
c) At the time of method overriding if the super class method does
not reporting or throwing checked exception then the overridden method of sub class not allowed to
throw checked exception. otherwise it will generate compilation error.(Sub class method can throws
un-checked Exception)

package com.ravi.method_related_rule;

import java.io.IOException;

class Super
{
public void show()
{
System.out.println("Super class method not throwing checked Exception");
}
}
class Sub extends Super
{
@Override
public void show() throws IOException //[error]
{
System.out.println("Sub class method should not throw checked Exception");
}
}

public class MethodOverridingWithChecked {

public static void main(String[] args) {


// TODO Auto-generated method stub

}
---------------------------------------------------------------------
d) If the super class method declare with throws keyword to throw a checked exception, then at the time
of method overriding, sub class method may or may not use throws keyword.
If the Overridden method is also using throws
keyword to throw checked exception then it must be either same exception class or sub class, it should
not be super class as well as we can’t add more exceptions in the overridden method.

package com.ravi.method_related_rule;

import java.io.FileNotFoundException;
import java.io.IOException;

class Base
{
public void show() throws FileNotFoundException
{
System.out.println("Super class method ");
}
}
class Derived extends Base
{
//throws is applicable but must be equal or sub class
public void show() throws IOException
{
System.out.println("Sub class method ");
}
}

public class MethodOverridingWithThrows


{
public static void main(String[] args)
{
System.out.println("Overridden method may or may not throw checked exception but if it is throwing
then must be same or sub class");
}

Note : Overridden show() method will generate Compilation error because IOException is the super class
for FileNotFoundException.
---------------------------------------------------------------------
Exception propagation :- [Exception object will shift from callee to caller]
--------------------------
Whenever we call a method and if the the callee method contains any kind of exception and if callee
method doesn’t contain any kind of exception handling mechanism (try-catch) then JVM will propagate
the exception to caller method for handling purpose. This is called Exception Propagation.

If the caller method also does not contain any exception handling mechanism then JVM will terminate the
method from the stack frame hence the remaining part of the method(m1 method) will not be executed
even if we handle the exception in another caller method like main.

If any of the the caller method does not contain any exception handling mechanism then exception will be
handled by JVM, JVM has default exception handler which will provide the exception message and
terminates the program abnormally.

ExceptionPropagation.java
---------------------------
package com.ravi.method_related_rule;

public class ExceptionPropagation


{
public static void main(String [] args)
{
System.out.println("Main started");
try
{
m1();
}
catch(ArithmeticException e)
{
System.err.println("AE Handled in main method");
}
System.out.println("Main ended");
}

public static void m1()


{
System.out.println("m1 started");
m2();
System.out.println("m1 ended"); //This line will not be executed
}

public static void m2()


{
System.out.println(10/0);
}

Here m1() method remaining part will not be printed because it is terminted by JVM because it does not
contain any exception handling mechanism
----------------------------------------------------------------------
Method calling Rule :
----------------------
package com.ravi.method_related_rule;

class Parent
{
public void m1() throws InterruptedException
{
System.out.println("Parent class m1 method");
}
}

class Child extends Parent


{
public void m1()
{
super.m1(); //error
System.out.println("Child class m1 method");
}
}

public class CallingSuperClassMethodWithThrows {

public static void main(String[] args) {


// TODO Auto-generated method stub

Note :- In the above program we are calling super class method which is throwing a checked Exception
but the caller method does not have any protection so compilation error hence provide either try-catch or
declare the method as throws. (Same will not be applicable for Un checked Exception)
----------------------------------------------------------------------
package com.ravi.method_related_rule;

import java.io.IOException;

class Parent1
{
public void m1() throws IOException
{
System.out.println("Parent class m1 method");
}
}

class Child1 extends Parent1


{
public void m1() throws IOException
{
super.m1();
System.out.println("Child class m1 method");
}
}

public class CallingSuperClassMethodWithThrows1 {

public static void main(String[] args)


{
System.out.println("Main");

Here we are calling the super class method by declaring the method as
throws because super class method is throwing checked Exception.
--------------------------------------------------------------------
package com.ravi.method_related_rule;

import java.util.Scanner;
class Parent2
{
public void m1() throws InterruptedException
{
System.out.println("Parent class m1 method");
}
}

class Child2 extends Parent2


{

public void m1()


{
try
{
super.m1();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
public class CallingSuperClassMethodWithThrows2 {

public static void main(String[] args)


{
System.out.println("main");

}
}

So the Conclusion is, if we are calling any method and that method is throwing any checked exception
then the caller method must have either try-catch or throws (Protection is reqd).
----------------------------------------------------------------------
31-01-2024
-----------
Input Output in java :
-----------------------
In order to work with input and output concept, java software people has provided a separate package
called java.io package.

By using this java.io package we can read the data from the user, creating file, reading/writing the data
from the file and so on.

How to take the input from the user using java.io package :
------------------------------------------------------------
Scanner class is available from java 1.5 onwards but before 1.5, In order to read the data we were using
the following two classes which are available in java.io package.

1) DataInputStream (Deprecated)
2) BufferedReader

How to create the object for these classes :


--------------------------------------------
DataInputStream :
-----------------
DataInputStream d = new DataInputStream(System.in);

By using DataInputStream class we can read the data from the user, readLine() method of
DataInputStream class is deprecated.

BufferedReader :
----------------
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
OR

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

In BufferedReader class, It provides buffer facility so, the execution of the program will be more faster
then DataInputStream class.

Methods :
---------
1) public int read() : It is used to read a single character only from
the source and returns the UNICODE value of the character. If the data is not available
then it will return -1.

2) public String readLine() : It is used to read the complete line or


multiple characters from the source and return type of this method is String.

---------------------------------------------------------------------
WAP to read the name from the keyboard

import java.io.*;
public class ReadName
{
public static void main(String args[]) throws IOException
{
DataInputStream d = new DataInputStream(System.in);
System.out.print("Enter your Name :");
String name = d.readLine();
System.out.println("Your Name is :"+name);
}
}
---------------------------------------------------------------------
Reading an int value from Client
--------------------------------
package com.ravi.custom_exception;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadAge {


public static void main(String[] args)
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try(br)
{
System.out.print("Enter your Age :");
String ag = br.readLine();

int age = Integer.parseInt(ag);

if(age>18)
{
System.out.println("Go for a movie");
}
else
{
System.out.println("Try after some year");
}

}
catch(IOException e)
{
e.printStackTrace();
}

}
------------------------------------------------------------------------
package com.ravi.custom_exception;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadFloat {

public static void main(String[] args) throws Exception


{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter your Salary :");

float salry = Float.parseFloat(br.readLine());


System.out.println("Your Salary is :"+salry);

}
------------------------------------------------------------------------
WAP to read a character from the keyboard :
-------------------------------------------
package com.ravi.custom_exception;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadChar {

public static void main(String[] args) throws IOException


{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter your Gender [M/F]:");
char read = (char) br.read();
System.out.println("You Are :"+read);

}
-----------------------------------------------------------------------
WAP in java to read the employee data :
---------------------------------------
package com.ravi.custom_exception;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadEmployeeData {

public static void main(String[] args) throws Exception


{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter Employee Id :");


int id = Integer.parseInt(br.readLine());

System.out.print("Enter Employee Gender :");


char gen = br.readLine().charAt(0); //Buffer Problem

System.out.print("Enter Employee Name :");


String name = br.readLine();

System.out.println("Employee Id is :"+id);
System.out.println("Employee Gender is :"+gen);
System.out.println("Employee Name is :"+name);
}

}
---------------------------------------------------------------------
01-02-2024
-----------
What is the need of File Handling ?
-----------------------------------
As we know variables are used to store some meaningful value in our program but once the execution of
the program is over, now we can’t get those values so to hold those values permanently in our memory
we use files.

Files are stored in the secondary storage devices so, we can use/read the data stored in the file anytime
according to our requirement.

In order to work with File system java software people has provided number of predefined classes like
File, FileInputStream, FileOutputStream and so on. All these classes are available in java.io package. We
can read and write the data in the form of Stream.
-----------------------------------------------------------------
Streams in java :
--------------------
A Stream is nothing but flow of data or flow of characters to both the end.
Stream is divided into two categories

1) byte oriented Stream :-


------------------------
It used to handle characters, images, audio and video file in binary format.

2) character oriented Stream :-


--------------------------------
It is used to handle the data in the form of characters or text.

Now byte oriented or binary Stream can be categorized as "input stream" and "output stream". input
streams are used to read or receive the data where as output streams are used to write or send the data.

Again Character oriented Stream is divided into Reader and Writer. Reader is used to read() the data
from the file where as Writer is used to write the data to the file.

All Streams are represented by classes in java.io package.

InputStream is the super class for all kind of input operation where as OutputStream is the super class for
all kind of output Operation for byte oriented stream.

Where as Reader is the super class for all kind reading operation where as Writer is the super class for all
kind of writing operation in character oriented Stream.
---------------------------------------------------------------------

File :-
-----
It is a predefined class in java.io package through which we can create file and directory. By using this
class we can verify whether the file is existing or not.

File f = new File("abc.txt");

The above statement will not create any file, It actually create the file object and perform one of the
following two task.
a) If abc.txt does not exist, It will not create it
b) if abc.txt does exist, the new file object will be refer to the referenec variable f

Now if the file does not exist then to create the file and verify whether file is existing or not, we should use
the following two methods :

1) public boolean exists() : Will verify whether file is existing or not?

2) public boolean createNewFile() : Will Create a new file , if


file is already available then return false.

File class has also a predefined method called getName(), to get the name of the file.
---------------------------------------------------------------------
import java.io.*;
public class File0
{
public static void main(String[] args)
{
try
{
File f = new File("C:\\Batch27\\India.txt");

if(f.exists())
{
System.out.println("File is existing");
}
else
{
System.out.println("File is not existing");
}

if (f.createNewFile())
{
System.out.println("File created: " + f.getName());
}
else
{
System.out.println("File is already existing....");
}
}
catch (IOException e)
{
System.err.println(e);
}
}
}

Assignment :
------------
create a directory by using File class.
----------------------------------------------------------------------
FileOutputStream :
------------------
It is a predefined class available in java.io package.

It is used to create a new file every time and after creating the file we can write the data to the file but the
data must be available in binary format.
-----------------------------------------------------------------
String class has provided a predefined method getBytes() through which we can convert the String data
into byte array (Binary format) as shown below.

String str = "Hello Hyderabad";

byte [] arr = str.getBytes();

Here arr will print the UNICODE value of the character


------------------------------------------------------------------------
//Creating and writing the data to the file

import java.io.*;
public class File1
{
public static void main(String args[]) throws IOException
{
var fout = new FileOutputStream("C:\\Batch27\\Hyderabad.txt");
try(fout)
{
String s = "Hyd is a popular IT City in India";
byte b[] = s.getBytes();

fout.write(b);

System.out.println("Success....");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
----------------------------------------------------------------------
FileInputStream :-
-----------------
It is a predefined class available in java.io package. It is used to read the file data/content. If we want to
print the file data in console then data must be available in char format.

Note :- Whenever we want to write the data in the file then data must be available in byte format where as
If we want to print the data to the console then the data must be converted into char format.
----------------------------------------------------------------------
//Reading tha data from the file
import java.io.*;
public class File2
{
public static void main(String s[]) throws IOException
{
var fin = new FileInputStream("C:\\batch27\\Hyderabad.txt");

try(fin)
{
int i = 0;
while(true)
{
i = fin.read();
if(i==-1)
break;
System.out.print((char)i);
}

}
catch(Exception e)
{
System.out.println(e);
}
System.out.println();
}
}
---------------------------------------------------------------------
//wap in java to read the data from one file and to write the data to another file.
import java.io.*;
public class File3
{
public static void main(String s[]) throws IOException
{
//Outside of try (Java 9 enhancement in try with resource)

var fin = new FileInputStream("File2.java");

var fout = new FileOutputStream("C:\\Batch27\\f2.txt");

try(fin; fout)
{
while(true)
{
int i = fin.read();
if(i==-1) break;
System.out.print((char)i);
fout.write((byte)i);
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
----------------------------------------------------------------------
Limitation of FileInputStream class :
-------------------------------------
As we know FileInputStream class is used to read the content from the file but it can read the data from a
single file only that means if we want to read the data from two files at the same time then we should use
a separate Stream called SequenceInputStream.

SequenceInputStream :
-------------------------
It is a predefined class available in java.io package. This class is used to read the data from two files at
the same time.
----------------------------------------------------------------------
//Proram to read the data from two files at the same time
import java.io.*;
public class File4
{
public static void main(String args[]) throws IOException
{
var f1 = new FileInputStream("File1.java");
var f2 = new FileInputStream("File2.java");
var s = new SequenceInputStream(f1,f2);

try(f1; f2; s)
{
int i;
while(true)
{
i = s.read();
if(i==-1)
break;
System.out.print((char)i);
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
----------------------------------------------------------------------
02-02-2024
-----------
Limitation of FileOutputStream :
--------------------------------
By using this FileOutputStream class, we can write the data to single file only.
If we want to write the data to multiple files at the same time then we should use a separate stream called
ByteArrayOutputStream.

ByteArrayOutputStream :-
---------------------------
It is a predefined class available in java.io package. By using this class we can write the data to multiple
files. ByteArrayOutputStream class provides a method called writeTo(), through which we can write the
data to multiple files.

//Program to write the data on multiple files.


import java.io.*;
public class File6
{
public static void main(String args[]) throws IOException
{
var fin = new FileInputStream("File1.java");

var f1 = new FileOutputStream("C:\\Batch27\\a1.txt");


var f2 = new FileOutputStream("C:\\Batch27\\b1.txt");
var f3 = new FileOutputStream("C:\\Batch27\\c1.txt");

var bout = new ByteArrayOutputStream();

try(fin; f1; f2; f3; bout)


{
int i;
while((i = fin.read()) != -1)
{
bout.write((byte)i); //writing tha data to ByteArrayOutputStream
}
bout.writeTo(f1);
bout.writeTo(f2);
bout.writeTo(f3);

bout.flush(); //clear the buffer for reusing of ByteArrayOutputStream


System.out.println("Success");
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
----------------------------------------------------------------------
//Working with images
import java.io.*;
public class File7
{
public static void main(String[] args) throws IOException
{
var fin = new FileInputStream("C:\\Batch27\\image.jpg");

var f1 = new FileOutputStream("C:\\Batch27\\a1.jpg");


var f2 = new FileOutputStream("C:\\Batch27\\a2.jpg");
var f3 = new FileOutputStream("C:\\Batch27\\a3.jpg");

var bout = new ByteArrayOutputStream();

try(fin; f1; f2; f3; bout)


{
int i;
while((i = fin.read()) != -1)
{
bout.write((byte)i);
}
bout.writeTo(f1);
bout.writeTo(f2);
bout.writeTo(f3);
System.out.println("success...");
bout.flush();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
------------------------------------------------------------------
BufferedOutputStream :-
--------------------------
It is a predefined class available in java.io package.

Whenever we use the class FileOutputStream the data will be available on the Stream but not in the
buffer so there may be chance of miss memory management, It is always preferable that the data should
be available in the buffer.

By using this BufferedOutputStrean now the data is in the buffer so the execution will become more
faster.

//Program to put the data in the buffer for fast execution

import java.io.*;
class File8
{
public static void main(String args[]) throws IOException
{
var fout = new FileOutputStream("C:\\Batch27\\Hyderabad.txt");

var bout = new BufferedOutputStream(fout);

try(fout ; bout)
{
String s = "Hyderabad is a nice city";
byte b[] = s.getBytes();
bout.write(b);
System.out.print("success...");
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
----------------------------------------------------------------------
BufferedInputStream :-
-------------------------
It is a predefined class available in java.io package. Whenever we use FileInputStream to read the
data/content from the file the data will be available on the Stream but not in the buffer so there may be a
chance of miss memory management so we should take the data into the buffer by using
BufferedInputStream class so overall the execution will become faster.

//BufferedInputStream
import java.io.*;
public class File9
{
public static void main(String args[]) throws IOException
{
var fin = new FileInputStream("File1.java");
var bin = new BufferedInputStream(fin);

try(fin ; bin)
{
int i;
while((i = bin.read()) != -1)
{
System.out.print((char)i);
}
}
catch(IOException e)
{
e.printStackTrace();
}
System.out.println();
}
}
---------------------------------------------------------------------
Writing and Reading the primitive data to the files :-
----------------------------------------------------------
It is possible to write the primitive data(byte,short,int, long, float, double, char and boolean) to the file.

In order to write primitive data to the file we should use a predefined class available in java.io package
called DataOutputStream.

var fos = new FileOutputStream("data.txt");


var dos = new DataOutputStream(fos);

now by using this dos we can write primitive data to the file.

It provides various methods like writeByte(), writeShort(), writeInt() and so on to write the data to the file.

If we want to read the primitive data from the file we can use a predefined class available in java.io
package called DataInputStream, this class provides various methods like readByte(), readShort(),
readInt() and so on.

var fin = new FileInputStream("data.txt");


var dis = new DataInputStream(fin);

Note :- For writing String into a file we have writeBytes() and to read the String data from the file we have
readLine() method.

[DataInputStream class readLine() method is deprecated now, so compilation warning]

//DataOutputStream and DataInputStream


import java.io.*;
public class File10
{
public static void main(String args[]) throws IOException
{
var fout = new FileOutputStream("C:\\Batch27\\Primitive.txt");
var dout = new DataOutputStream(fout);

try(fout ; dout)
{
dout.writeBoolean(true);
dout.writeChar(’A’);
dout.writeByte(Byte.MAX_VALUE);
dout.writeShort(Short.MAX_VALUE);
dout.writeInt(Integer.MAX_VALUE);
dout.writeLong(Long.MAX_VALUE);
dout.writeFloat(Float.MAX_VALUE);
dout.writeDouble(Math.PI);//PI is a final static variable
dout.writeBytes("Hello India...");
dout.flush();//For reuse purpose
}
catch(IOException e)
{
e.printStackTrace();
}

System.out.println("Reading the Primitive data from the file!!!");

var fin = new FileInputStream("C:\\batch27\\Primitive.txt");


var din = new DataInputStream(fin);
try(fin ; din)
{
boolean f = din.readBoolean();
char c = din.readChar();
byte b = din.readByte();
short s = din.readShort();
int i = din.readInt();
long l = din.readLong();
float ft = din.readFloat();
double d = din.readDouble();
String x= din.readLine();//for reading String (deprecated)

System.out.println(f +"\n"+c+"\n"+b+"\n"+s+"\n"+i+"\n"+l+"\n"+ft+"\n"+d+"\n"+x);
}
catch(IOException e)
{
e.printStackTrace();
}

}
}
---------------------------------------------------------------------
03-02-2024
-----------
IQ :
----

* Serialization and De-serialization :


---------------------------------------
It is a technique through which we can store the object data in a file. Storing the object data into a file is
called Serialization on the other hand Reading the object data from a file is called De-serialization.

In order to perform serialization, a class must implements Serializable interfcae, predefined marker
interface in java.io package.

Java.io package has also provided a predfined class called ObjectOutputStream to perform serialization
i.e writing Object data to a file using writeObject() method.

where as ObjectInputStream is also a predefined class available in java.io package through which we can
read the Object data from a file using readObject(). The return type of readObject() is Object.

While reading the object data from the file, if the object is not available in the file then it will throw an
execption java.io.EOFException. (End of file Exception)
---------------------------------------------------------------------
Employee.java
-------------
package com.ravi.serialization;

import java.io.Serializable;
import java.util.Date;
import java.util.Scanner;

public class Employee implements Serializable


{
private Integer employeeId;
private String employeeName;
private Double employeeSalary;
private Date hireDate;

public Employee(Integer employeeId, String employeeName, Double employeeSalary, Date hireDate) {


super();
this.employeeId = employeeId;
this.employeeName = employeeName;
this.employeeSalary = employeeSalary;
this.hireDate = hireDate;
}

public static Employee getEmployeeObject()


{
Scanner sc = new Scanner(System.in);
System.out.print("Enter Employee Id :");
Integer id = sc.nextInt();

System.out.print("Enter Employee Name :");


String name = sc.nextLine();
name = sc.nextLine();

System.out.print("Enter Employee Salary :");


Double sal = sc.nextDouble();

Date d1 = new Date();

return new Employee(id, name, sal, d1);

@Override
public String toString() {
return "Employee [employeeId=" + employeeId + ", employeeName=" + employeeName + ",
employeeSalary="
+ employeeSalary + ", hireDate=" + hireDate + "]";
}
}

StoringEmployeeObject.java
--------------------------
package com.ravi.serialization;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.Scanner;
public class StoringEmployeeObject
{
public static void main(String[] args) throws Exception
{
var fout = new FileOutputStream("C:\\Batch27\\Empdata.txt");
var oos = new ObjectOutputStream(fout);
var sc = new Scanner(System.in);

try(fout; oos; sc)


{
System.out.print("How many employee object you want to store :");
int numberOfObj = sc.nextInt();

for(int i=1; i<=numberOfObj; i++)


{
Employee obj = Employee.getEmployeeObject();
oos.writeObject(obj);
}

}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("Employee data stored successfully");
}

RetrievingEmployeeObject.java
------------------------------
package com.ravi.serialization;

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class RetrievingEmployeeObject


{
public static void main(String[] args) throws Exception
{
var fin = new FileInputStream("C:\\Batch27\\Empdata.txt");
var ois = new ObjectInputStream(fin);

try(fin; ois)
{
Employee emp = null;
while((emp = (Employee)ois.readObject())!=null)
{
System.out.println(emp);
}

}
catch(EOFException e)
{
System.err.println("End of file reached!!!");

}
}
---------------------------------------------------------------------
transient keyword :
-------------------
If we want that some of our field (variable) will not serialized then we should declare that variables with
transient keyword so, we will get the defualt value for the variables.

public class Player


{
private transient int playerId;
private transient String playerName;
}

Now if we perform serialization operation on Player object then for playerId we will get 0 and for
playerName we will get null.

3 files :
----------
Product.java
------------
package com.ravi.ser;

import java.io.Serializable;
import java.util.Scanner;

public class Product implements Serializable


{
private transient Integer productId;
private String productName;
private transient double productPrice;

public Product(Integer productId, String productName, double productPrice) {


super();
this.productId = productId;
this.productName = productName;
this.productPrice = productPrice;
}

public static Product getProductObject()


{
Scanner sc = new Scanner(System.in);
System.out.print("Enter product Id :");
int id = sc.nextInt();

System.out.print("Enter product Name :");


String name = sc.nextLine();
name = sc.nextLine();

System.out.print("Enter product Price :");


double price = sc.nextDouble();

return new Product(id, name, price);


}

@Override
public String toString() {
return "Product [productId=" + productId + ", productName=" + productName + ", productPrice=" +
productPrice
+ "]";
}

StoreProductData.java
----------------------
package com.ravi.ser;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Scanner;

public class StoreProductData


{
public static void main(String[] args) throws IOException
{
var fos = new FileOutputStream("C:\\Batch27\\prod.txt");
var oos = new ObjectOutputStream(fos);
Scanner sc = new Scanner(System.in);
try(fos; oos; sc)
{
System.out.print("How many Product Object :");
int noOfObj = sc.nextInt();

for(int i=1; i<=noOfObj; i++)


{
Product prod = Product.getProductObject();
oos.writeObject(prod);
}

}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("Product file is created");
}

RetrieveProductData.java
-------------------------
package com.ravi.ser;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class RetrieveProductData {

public static void main(String[] args) throws IOException


{
var fin = new FileInputStream("C:\\Batch27\\prod.txt");
var ois = new ObjectInputStream(fin);

try(fin; ois)
{
Product p = null;
while((p= (Product)ois.readObject())!=null)
{
System.out.println(p);
}
}
catch(Exception e)
{
System.err.println("End of file Reached");
}
}

}
----------------------------------------------------------------------
05-02-2024
----------
Working With Character Oriented Stream :
----------------------------------------
FileWriter class :
------------------
It is a predefined class available in java.io package,By using this class we can create a file and write
character data to the file.

By using this class we can directly write String (collection of characters) Or character array to the file.

Actually It is a character oriented Stream where as if we work with FileOutputStream class, It is byte
oriented Stream.
--------------------------------------------------------------
//FileWriter
import java.io.*;
public class File11
{
public static void main(String args[]) throws IOException
{
var fw = new FileWriter("C:\\Batch27\\HelloIndia.txt");
var bw = new BufferedWriter(fw);

try(fw; bw)
{
bw.write("It is in Asia");
System.out.println("Success....");
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
----------------------------------------------------------------------
//FileWriter
import java.io.*;
class File12
{
public static void main(String args[]) throws IOException
{
var fw = new FileWriter("C:\\Batch27\\Data.txt");
var bw = new BufferedWriter(fw);

try(fw;bw)
{
char c[ ] = {’H’,’E’,’L’,’L’,’O’, ’ ’,’ ’,’W’,’O’,’R’,’L’,’D’};

bw.write(c);
System.out.println("Success....");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
----------------------------------------------------------------------
FileReader class :
--------------------
It is a predefined class available in java.io package, It is a character oriented Stream. The main purpose
of this class to read the data in the character format directly from the file.

//FileReader
import java.io.*;
public class File13
{
public static void main(String args[]) throws IOException
{
var fr = new FileReader(args[0]); //Command Line Arg
var br = new BufferedReader(fr);

try(fr ; br)
{
while(true)
{
int i = br.read();
if(i == -1)
break;
System.out.print((char)i);
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
----------------------------------------------------------------------
import java.io.*;
public class File14
{
public static void main(String[] args) throws IOException
{
var fr = new FileReader("C:\\Batch27\\image.jpg");
var fw = new FileWriter("C:\\Batch27\\MyPic.jpg");

try(fr;fw)
{
int i;
while((i=fr.read())!= -1)
{
fw.write(i);
}
}
catch(Exception e)
{
}
System.out.println("Success");
}
}

Note :- Here we are trying to write the image file using FileWriter class which is not possible because
image internally contains binary data and FileWriter is used to write character Stream.
---------------------------------------------------------------------
PrintWriter :
--------------
It is a predefined class available in java.io package. The main purpose of this class to write the primitive
data into text format.

Methods :
-----------
printf() :- It is a predefined method of PrintWriter class which takes two parameters
a) Specification of the data so we can print the data according to specification(Formatted String)
b) Parameter to print the actual data.

//PrintWriter
import java.io.*;
public class File15
{
public static void main(String[] args) throws IOException
{
PrintWriter writeData = new PrintWriter("C:\\Batch27\\Roll.txt");

try(writeData)
{
int roll = 15;
//Writing primitive data into text format
writeData.printf("My roll number is : %d ", roll);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
---------------------------------------------------------------------
How to append the text in the Existing file :
---------------------------------------------
Every time we will call FileWriter class with Single parameter i.e file name it will create new file
(Overriding the existing file).

If we want that my existing data should not be overridden then we should use the following constructor of
FileWriter class

FileWriter fw = new FileWriter(String filePath, boolean data);

import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;

public class File16


{
public static void main(String[] args) throws IOException
{
var filename = "C:\\Batch27\\append.txt";
//wants to write the data in the existing file
var fileWriter = new FileWriter(filename, true);
var bufferedWriter = new BufferedWriter(fileWriter);

try(fileWriter;bufferedWriter)
{

// Append text to the file


String textToAppend = "My Name is Raj";
bufferedWriter.write(textToAppend);

//Moving the cursor to the next line


bufferedWriter.newLine();

textToAppend = "I lives in hyderabad";


bufferedWriter.write(textToAppend);

System.out.println("Text appended successfully to the file.");


}
catch (IOException e)
{
System.out.println("An error occurred while appending the text to the file: " + e.getMessage());
}
}
}
---------------------------------------------------------------------
Multithreading :
----------------
Uniprocessing :-
----------------
In uniprocessing, only one process can occupy the memory So the
major drawbacks are

1) Memory is westage
2) Resources are westage
3) Cpu is idle

To avoid the above said problem, multitasking is introduced.

In multitasking multiple tasks can concurrently work with CPU so, our task will be completed as soon as
possible.

Multitasking is further divided into two categories.

a) Process based Multitasking


b) Thread based Multitasking

Process based Multitasking (Diagram 05-FEB-24)


-------------------------------------------------
If a CPU is switching from one subtask(Thread) of one process to
another subtask of another process then it is called Process based Multitasking.

Thread based Multitasking :


---------------------------
If a CPU is switching from one subtask(Thread) to another subtask within the same process then it is
called Thread based Multitasking.
----------------------------------------------------------------
Thread :-
----------
A thread is light weight process and it is the basic unit of CPU which can run concurrently with another
thread within the same context (process).

It is well known for independent execution. The main purpose of multithreading to boost the execution
sequence.

A thread can run with another thread at the same time so our task will be completed as soon as possible.
---------------------------------------------------------------
In java whenever we define a main method then JVM internally creates a thread called main thread.

Thread is a predefined class available in java.lang package, It contains a predefined static method
currentThread() [Which is factory method] which will provide the currently executing thread at that
particular area.

Thread class has also provided getName() method so, we can get the name of the Thread.
----------------------------------------------------------------
MainThread.java
---------------
package com.ravi.thread;

public class MainThread


{
public static void main(String[] args)
{
Thread t1 = Thread.currentThread();
System.out.println(t1.getName());

//OR
System.out.println(Thread.currentThread().getName());

//OR
String name = Thread.currentThread().getName();
System.out.println("Current thread name is :"+name);
}

}
---------------------------------------------------------------
How to create a userdefined Thread in java ?
---------------------------------------------
As we know whenever we define the main method then JVM internally creates a thread called main
thread.

The purpose of main thread to execute the entire main method so at the time of execution of main method
a user can create our own userdefined thread.

In order to create the userdefined Thread we can use one of the following two ways :-

1) By extending java.lang.Thread class


2) By implementing java.lang.Runnable interface

Note :- Thread is a predefined class available in java.lang package where as Runnable is a predefined
interface available in java.lang Package.
----------------------------------------------------------------

public synchronized void start() :


-----------------------------------
start() is a predefined method of Thread class and this method internally performs two tasks

1) It makes a request to opearting system to assign a new thread to perform concurrent execution.

2) It internally invokes the run() method as a part a separate Stack.

Note :- For every individual thread, JVM creates a separate runtime stack.
----------------------------------------------------------------
The following program explains how to create a userdefined Thread by extending Thread approach.

package com.ravi.thread;

class Test extends Thread


{
@Override
public void run()
{
System.out.println("Child Thread is running");
}
}

public class UserThread {

public static void main(String[] args)


{
System.out.println("Main thread started.");

Test t1 = new Test();

t1.start();

System.out.println("main thread ended.");


}

}
---------------------------------------------------------------
public boolean isAlive() :-
-----------------------------
It is a predefined method of Thread class through which we can find out whether a thread has started or
not ?

As we know a new thread is created after calling start() method so if we use isAlive() method before
start() method, it will return false but if the same isAlive() method if we invoke after the start() method, it
will return true.

We can’t restart a thread in java if we try to restart then It will generate an exception i.e
java.lang.IllegalThreadStateException

package com.ravi.basic;

class Foo extends Thread


{
@Override
public void run()
{
System.out.println("Child thread is running...");
System.out.println("It is running with separate stack");
}
}
public class IsAlive
{
public static void main(String[] args)
{
System.out.println("Main Thread is started..");
Foo f = new Foo();
System.out.println("Thread has not started yet so :"+f.isAlive());

f.start(); //new Thread has created

System.out.println("Thread has started so :"+f.isAlive());


// f.start(); java.lang.IllegalThreadStateException
}
}
--------------------------------------------------------------
07-02-2024
-----------
package com.ravi.basic;

class Stuff extends Thread


{
@Override
public void run()
{
System.out.println("Child Thread is Running!!!!");
}
}
public class ExceptionDemo
{
public static void main(String[] args)
{
System.out.println("Main Thread Started");

Stuff s1 = new Stuff();


Stuff s2 = new Stuff();

s1.start();
s2.start();

System.out.println(10/0);

System.out.println("Main Thread Ended");


}

Note : Due to ArithmeticException, main thread will be interrupted but still child thread will be executed.
---------------------------------------------------------------
package com.ravi.basic;

class Sample extends Thread


{
@Override
public void run()
{
String name = Thread.currentThread().getName();

for(int i = 1; i<=10; i++)


{
System.out.println("i value is :"+i+" by "+name+" thread" );
}
}
}
public class ThreadLoop
{
public static void main(String[] args)
{
System.out.println("Main thread started.....");

Sample s = new Sample();


s.start();//child thread is created

String name = Thread.currentThread().getName();

for(int i = 1; i<=10; i++)


{
System.out.println("i value is :"+i+" by "+name+ " thread");
}

int x =1;
do
{
System.out.println("Hello");
x++;
}
while(x<=10);
}
}
---------------------------------------------------------------
How to set and get the name of the Thread :
--------------------------------------------------
Whenever we create a Thread in java then by default JVM assigns the name of thread is Thread-0,
Thread-1, Thread-2 and so on.

If a user wants to assign some user defined name of the Thread, then Thread class has provided a
predefined method called setName(String name) to set the name of the Thread.

On the other hand we want to get the name of the Thread then Thread class has provided a predefined
method called getName().

public void setName(String name)

public String getName()


----------------------------------------------------------------
package com.ravi.basic;
class Test extends Thread
{
@Override
public void run()
{
String name = Thread.currentThread().getName();
System.out.println(name +" thread is running Here!!!!");
}
}
public class ThreadName
{
public static void main(String[] args)
{
Test t1 = new Test();
Test t2 = new Test();

t1.start();
t2.start();

System.out.println(Thread.currentThread().getName()+" thread is running.....");


}
}

Note :- Explicitly we have not provided the name of the thread


so by default the name would be Thread-0 and Thread-1
---------------------------------------------------------------
package com.ravi.basic;
class Demo extends Thread
{
@Override
public void run()
{
System.out.println(Thread.currentThread().getName()+" thread is running.....");
}
}
public class ThreadName1
{
public static void main(String[] args)
{
Thread t = Thread.currentThread();
t.setName("Parent"); //Changing the name of the main thread

Demo d1 = new Demo();


Demo d2 = new Demo();

d1.setName("Child1");
d2.setName("Child2");

d1.start(); d2.start();

String name = Thread.currentThread().getName();


System.out.println(name + " Thread is running..");
}
}
---------------------------------------------------------------
Thread.sleep(long milisecond) :
-------------------------------
If we want to put a thread into temporarly waiting state then we should use sleep() method.

The waiting time of the Thread depends upon the time specified by the user as parameter to sleep()
method.

Thread.sleep(1000); //Thread will wait for 1 second

It is a static method of Thread class.

It is throwing a checked Exception i.e InterruptedException because there may be chance that this
sleeping thread may be interrupted by some another thread.
package com.ravi.basic;

class Sleep extends Thread


{
@Override
public void run()
{
for(int i=1; i<=10; i++)
{
System.out.println("i value is :"+i);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
System.err.println("Thread is Interrupted "+e);
}
}
}
}
public class SleepDemo
{
public static void main(String[] args)
{
Sleep s = new Sleep();
s.start();
s.interrupt();
}
}
---------------------------------------------------------------
package com.ravi.basic;

class MyTest extends Thread


{
@Override
public void run()
{
for (int i = 1; i <= 5; i++)
{
try
{
Thread.sleep(1000); //child1
}
catch(Exception e)
{
System.err.println("thread has interrupted");
}

System.out.println(i + " by " + Thread.currentThread().getName());


}
}
}
public class SleepDemo1
{
public static void main(String[] args)
{
System.out.println(Thread.currentThread().getName() + " thread");

MyTest t1 = new MyTest();


MyTest t2 = new MyTest();

t1.setName("Child1");
t2.setName("Child2");

t1.start();
t2.start();

}
}
---------------------------------------------------------------
Thread life cycle in java :
-----------------------------
As we know a thread is well known for Independent execution and it contains a life cycle which internally
contains 5 states (Phases).

During the life cycle of a thread, It can pass from thses 5 states. At a time a thread can reside to only one
state of the given 5 states.

1) NEW State (Born state)

2) RUNNABLE state (Ready to Run state) [Thread Pool]

3) RUNNING state

4) WAITING / BLOCKED state

5) EXIT/Dead state

New State :-
-------------
Whenever we create a thread instance(Thread Object) a thread comes to new state OR born state. New
state does not mean that the Thread has started yet only the object or instance of Thread has been
created.

Runnable state :-
-------------------
Whenever we call start() method on thread object, A thread moves to Runnable state i.e Ready to run
state. Here Thread schedular is responsible to select/pick a particular Thread from Runnable state and
sending that particular thread to Running state for execution.

Running state :-
-----------------
If a thread is in Running state that means the thread is executing its own run() method.

From Running state a thread can move to waiting state either by an order of thread schedular or user has
written some method(wait(), join() or sleep()) to put the thread into temporarly waiting state.

From Running state the Thread may also move to Runnable state directly, if user has written
Thread.yield() method explicitly.

Waiting state :-
------------------
A thread is in waiting state means it is waiting for it’s time period to complete. Once the time period will be
completed then it will re-enter inside the Runnable state to complete its remaining task.

Dead or Exit :
----------------
Once a thread has successfully completed its run method then the thread will move to dead state. Please
remember once a thread is dead we can’t restart a thread in java.

IQ :- If we write Thread.sleep(1000) then exactly after 1 sec the Thread will re-start?

Ans :- No, We can’t say that the Thread will directly move from waiting state to Running state.

The Thread will definetly wait for 1 sec in the waiting mode and then again it will re-enter into Runnable
state which is control by Thread Schedular so we can’t say that the Thread will re-start just after 1 sec.
---------------------------------------------------------------
Creating Thread class object by using Anonymous inner class approach using reference

package com.ravi.thread;

public class AnonymousThreadClassWithReference {

public static void main(String[] args)


{
//Anonymous inner class

Thread t1 = new Thread()


{
@Override
public void run()
{
System.out.println(Thread.currentThread().getName());
}
};
t1.start();

}
--------------------------------------------------------------
Creating Thread class object by using Anonymous inner class approach without reference

package com.ravi.thread;

public class AnonymousThreadClassWithoutReference {

public static void main(String[] args)


{
//Anonymous inner class

new Thread()
{
@Override
public void run()
{
System.out.println(Thread.currentThread().getName());
}
}.start();

}
---------------------------------------------------------------
08-02-2024
----------
join() method of Thread class :
------------------------------------
The main purpose of join() method to put the one thread into waiting mode until the other thread finish its
execution.

Here the currently executing thread stops its execution and the thread goes into the waiting state. The
current thread remains in the wait state until the thread on which the join() method is invoked has
achieved its dead state.

It also throws checked exception i.e InterruptedException so better to use try catch or declare the method
as throws.

It is an instance method so we can call this method with the help of Thread object reference.
----------------------------------------------------------------
package com.ravi.basic;

class Join extends Thread


{
@Override
public void run()
{
for(int i=1; i<=5; i++)
{
try
{
Thread.sleep(1000);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("i value is :"+i);
}
}
}

public class JoinDemo


{
public static void main(String[] args) throws InterruptedException
{
System.out.println("Main thread started....");
Join j1 = new Join();
Join j2 = new Join();
Join j3 = new Join();

j1.start();

j1.join();

j2.start();
j3.start();

System.out.println("Main thread ended....");


}

}
-----------------------------------------------------------------
package com.ravi.basic;

public class JoinDemo1


{
public static void main(String[] args) throws InterruptedException
{
System.out.println("Main thread started");
Thread thread = Thread.currentThread();
String name = thread.getName();

for(int i=1; i<=10; i++)


{
System.out.println(i + " by "+name+ " thread ");
Thread.sleep(1000);
thread.join();
}

System.out.println("Main thread ended");

Here main thread is waiting for main thread to complete so, this is known as Deadlock state.
-----------------------------------------------------------------
package com.ravi.basic;

class Alpha extends Thread


{
@Override
public void run()
{
Thread t = Thread.currentThread();
String name = t.getName(); //Alpha_Thread

Beta b1 = new Beta();


b1.setName("Beta_Thread");
b1.start();
try
{
b1.join(); //Alpha thread is Blocked
}
catch (InterruptedException e)
{
e.printStackTrace();
}

for(int i=1; i<=10; i++)


{
System.out.println(i+" by "+name);
}

}
}

public class JoinDemo2


{
public static void main(String[] args)
{
Alpha a1 = new Alpha();
a1.setName("Alpha_Thread");
a1.start();
}
}

class Beta extends Thread


{
@Override
public void run()
{
Thread t = Thread.currentThread();
String name = t.getName();
for(int i=1; i<=20; i++)
{
System.out.println(i+" by "+name);
}
System.out.println(".............");
}
}

Here Alpha thread is waiting for Beta thread to complete


-----------------------------------------------------------------
Creating a user thread by using implements Runnable approach :
--------------------------------------------------------------
package com.ravi.thread;

class Demo implements Runnable


{
@Override
public void run()
{
String name = Thread.currentThread().getName();
System.out.println(name +" thread is running in Demo class");
}
}

public class RunnableDemo


{
public static void main(String[] args)
{
Thread t1 = new Thread(new Demo(),"Child1");
t1.start();

Thread t2 = new Thread(new Foo(),"child2");


t2.start();

class Foo implements Runnable


{
@Override
public void run()
{
String name = Thread.currentThread().getName();
System.out.println(name +" thread is running in Foo class");
}

In implements Runnable approach we need to pass the sub class object as a reference to Thread class
constructor to define the target for the Thread.
-----------------------------------------------------------------
package com.ravi.thread;

public class AnonymousRunnable {

public static void main(String[] args)


{
Runnable r1 = new Runnable()
{
@Override
public void run()
{
String name = Thread.currentThread().getName();
System.out.println(name);
}
};
Thread t1 = new Thread(r1);
t1.start();

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

Runnable r2 = ()-> System.out.println(Thread.currentThread().getName());


Thread t2 = new Thread(r2); t2.start();

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

new Thread(()-> System.out.println(Thread.currentThread().getName()),"C1").start();

}
-----------------------------------------------------------------
*In between extends Thread and implements Runnable, which one is better and why?

In between extends Thread and implements Runnable approach, implements Runnable is more better
due to the following reasons

1) When we use extends Thread, all the methods and properties of Thread class is available to sub class
so it is heavy weight but this is not the case while implementing Runnable interface.

2) As we know Java does not support multiple inheritance using classes so in the extends Thread
approach we can’t extend another class but if we use implments Runnable interface still we have chance
to extend another class(Only one class) and we can also implement one or more interfaces.

3) implements Runnable is a better approach to create multiple threads on a single sub class object.

4) We can implement Lambda for Runnable interface (Functional interface) only but not for Thread class.
-----------------------------------------------------------------
Thread class constructor :
--------------------------
In Thread class we have total 9 constructors are available but among all these 9 constructors we are
commonly using 5 constructors which are as follows :

1) Thread t1 = new Thread();

2) Thread t2 = new Thread(String name);

3) Thread t3 = new Thread(Runnable target);

4) Thread t4 = new Thread(Runnable target, String name);

5) Thread t5 = new Thread(ThreadGroup tg, Runnable target);

6) Thread t6 = new Thread(ThreadGroup tg, Runnable target, String name);


------------------------------------------------------------------
Problem with multithreading :-
----------------------------------
Multithreading is very good to complete our task as soon as possible but in some situation, It provides
some wrong data or wrong result.

In Data Race or Race condition, all the threads try to access the resource at the same time so the result
will be corrupted.

In multithreading if we want to perform read operation and data is not updatable then multithreading is
good but if the data is updatable data (modifiable data) then multithreading may produce some wrong
result or wrong data as shown in the diagram.(09-FEB-24)
-----------------------------------------------------------------
Program on Banking application where multiple threads are accessing the balance :

package com.ravi.bank;

class Client
{
int availableBalance = 20000;
int withdrawBalance;

public Client(int withdrawBalance)


{
this.withdrawBalance = withdrawBalance;
}
}

public class BankingApplication


{
public static void main(String[] args)
{
Client c1 = new Client(20000);

Runnable r1 = ()->
{
String name = null;
if(c1.withdrawBalance <= c1.availableBalance)
{
name = Thread.currentThread().getName();
System.out.println(c1.withdrawBalance+" amount withdraw by :"+name);
c1.availableBalance = c1.availableBalance - c1.withdrawBalance;
}
else
{
name = Thread.currentThread().getName();
System.err.println("Sorry "+name+ " insufficient balance");
}

};

Thread t1 = new Thread(r1,"Virat");


Thread t2 = new Thread(r1,"Rohit");

t1.start(); t2.start();

}
}

Here both the threads can withdraw the amount.


-----------------------------------------------------------------
Program on Railway Reservation apploication where multiple threads are accessing the berth :

package com.ravi.railway_booking;

class Customer implements Runnable


{
private int availableSeat = 1;
private int wantedSeat;

public Customer(int wantedSeat)


{
this.wantedSeat = wantedSeat;
}

@Override
public void run()
{
String name = null;

if(availableSeat >= wantedSeat)


{
name = Thread.currentThread().getName();
System.out.println(wantedSeat +" seat is reserved for "+name);
availableSeat = availableSeat-wantedSeat;
}
else
{
name = Thread.currentThread().getName();
System.err.println("Sorry!!"+name+" berth is not available");
}

public class RailwayReservation


{
public static void main(String[] args)
{
Customer c1 = new Customer(1);

Thread t1 = new Thread(c1,"Virat");


Thread t2 = new Thread(c1,"Rohit");

t1.start(); t2.start();

}
-----------------------------------------------------------------
WAP in java that describes we cannot perform parallel task with thread.

Theatre.java
-------------
package com.ravi.advanced;

class MyThread implements Runnable


{
private String str;
public MyThread(String str)
{
this.str=str;
}

@Override
public void run()
{
for(int i=1; i<=10; i++)
{
System.out.println(str+ " : "+i);
try
{
Thread.sleep(100);
}
catch (Exception e)
{
System.err.println(e);
}
}
}
}
public class Theatre
{
public static void main(String [] args)
{
MyThread obj1 = new MyThread("sell the Ticket");
MyThread obj2 = new MyThread("Allocate the Seat");

Thread t1 = new Thread(obj1);


Thread t2 = new Thread(obj2);

t1.start();
t2.start();
}
}
-----------------------------------------------------------------
* Synchronization :
------------------
In order to solve the problem of multithreading java software people has introduced synchronization
concept.

In order to acheive synchronization in java we have a keyword called "synchronized".

It is a technique through which we can control multiple threads but accepting only one thread at all the
time.

Synchronization allows only one thread to enter inside the synchronized area for a single object.

Synchronization can be divided into two categories :-

1) Method level synchronization

2) Block level synchronization


Method level synchronization :-
-----------------------------------
In method level synchronization, the entire method gets synchronized so all the thread will wait at method
level and only one thread will enter inside the synchronized area as shown in the diagram.(10-FEB-24)

Block level synchronization :-


---------------------------------
In block level synchronization the entire method does not get synchronized, only the part of the method
gets synchronized so all the thread will enter inside the method but only one thread will enter inside the
synchronized block as shown in the diagram (10-FEB-24)

Note :- In between method level synchronization and block level synchronization, block level
synchronization is more preferable because all the threads can enter inside the method so only the PART
OF THE METHOD GETS synchronized so only one thread will enter inside the synchronized block.
----------------------------------------------------------------
How synchronization logic controls multiple threads ?
------------------------------------------------------
Every Object has a lock(monitor) in java environment and this lock can be given to only one Thread at a
time.

The thread who acquires the lock from the object will enter inside the synchronized area, it will complete
its task without any disturbance because at a time there will be only one thread inside the synchronized
area(for single Object). *This is known as Thread-safety in java.

The thread which is inside the synchronized area, after completion of its task while going back will release
the lock so the other threads (which are waiting outside for the lock) will get a chance to enter inside the
synchronized area by again taking the lock from the object and submitting it to the synchronization
mechanism.
This is how synchronization mechanism controls multiple Threads.

Note :- Synchronization logic can be done by senior programmers in the real time industry because due to
poor synchronization there may be chance of getting deadlock.
----------------------------------------------------------------
//Program on Method level synchronization :
-------------------------------------------
package com.ravi.synchronization;

class Table
{
public synchronized void printTable(int num)
{
for(int i=1; i<=20; i++)
{
System.out.println(num+" X "+i+" = "+(num*i));
try
{
Thread.sleep(500);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println(".................");
}
}

public class MethodLevelSynchronization {

public static void main(String[] args)


{
Table obj = new Table(); //lock is created

Thread t1 = new Thread()


{
@Override
public void run()
{
obj.printTable(5);
}
};

Thread t2 = new Thread()


{
@Override
public void run()
{
obj.printTable(10);
}
};

t1.start(); t2.start();
}

}
----------------------------------------------------------------
Program on Block level synchronization :
----------------------------------------
package com.ravi.advanced;

//Block level synchronization

class ThreadName
{
public void printThreadName()
{
String name = Thread.currentThread().getName();
System.out.println("Thread inside the method is :"+name);

synchronized(this) //synchronized Block


{
for(int i=1; i<=9; i++)
{
System.out.println("i value is :"+i+" by :"+name);
}
System.out.println(".............................");
}
}
}
public class BlockSynchronization
{
public static void main(String[] args)
{
ThreadName obj1 = new ThreadName(); //lock is created

Runnable r1 = () -> obj1.printThreadName();

Thread t1 = new Thread(r1,"Child1");


Thread t2 = new Thread(r1,"Child2");
t1.start(); t2.start();
}
}
-----------------------------------------------------------------
Problem with Object Level Synchronization :
-------------------------------------------
From the given diagram it is clear that there is no interference between t1 and t2 thread because they are
passing throgh Object1 where as on the other hand there is no interferenec even in between t3 and t4
threads because they are also passing through Object2 (another object).

But there may be chance that with t1 Thread, t3 or t4 thread can enter inside the synchronized area at the
same time, simillarly it is also possible that with t2 thread, t3 or t4 thread can enter inside the
synchronized area so the conclusion is synchronization mechanism does not work with multiple
Objects.(Diagram 10-FEB-24)
---------------------------------------------------------------
package com.ravi.advanced;
class PrintTable
{
public synchronized void printTable(int n)
{
for(int i=1; i<=10; i++)
{
System.out.println(n+" X "+i+" = "+(n*i));
try
{
Thread.sleep(500);
}
catch(Exception e)
{
}
}
System.out.println(".......................");
}
}

public class ProblemWithObjectLevelSynchronization


{
public static void main(String[] args)
{
PrintTable pt1 = new PrintTable(); //lock1
PrintTable pt2 = new PrintTable(); //lock2

Thread t1 = new Thread() //Anonymous inner class concept


{
@Override
public void run()
{
pt1.printTable(2); //lock1
}
};

Thread t2 = new Thread()


{
@Override
public void run()
{
pt1.printTable(3); //lock1
}
};

Thread t3 = new Thread()


{
@Override
public void run()
{
pt2.printTable(6); //lock2
}
};

Thread t4 = new Thread()


{
@Override
public void run()
{
pt2.printTable(9); //lock2
}
};
t1.start(); t2.start(); t3.start(); t4.start();
}
}

So, from the above program it is clear that synchronization will not work with multiple objects.

Now, to avoid this Static Synchronization is came into the picture.


----------------------------------------------------------------
12-02-2024
-----------
Static Synchronization :
------------------------
If We declare a synchronized method as a static method then it is called static synchronization.

Now with static synchronization lock will be available at class level but not Object level.

To call the static synchronized method, object is not required so we can call the static method with the
help of class name.

Unlike objects we can’t create multiple classes for the same application.

Program on static synchronization


---------------------------------
package com.ravi.static_syn;
class Table
{
public static synchronized void printTable(int n)
{
for(int i=1; i<=10; i++)
{
System.out.println(n+" X "+i+ " = "+(n*i));
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("...................");
}
}

public class StaticSynchronization


{
public static void main(String[] args)
{

Thread t1 = new Thread()


{
@Override
public void run()
{
Table.printTable(5);
}
};

Thread t2 = new Thread()


{
@Override
public void run()
{
Table.printTable(10);
}
};

Runnable r1 = ()-> Table.printTable(15);


Thread t3 = new Thread(r1);

t1.start(); t2.start(); t3.start();

Here the thread will take the lock from Table class.
----------------------------------------------------------------
** Inter Thread Communication(ITC) :
------------------------------------
It is a mechanism to communicate two synchronized threads within the context to achieve a particular
task.

In ITC we put a thread into wait mode by using wait() method and other thread will complete its
corresponding task, after completion of the task it will call notify() method so the waiting thread will get a
notification to complete its remaining task.

ITC can be implemented by the following method of Object class.

1) public final void wait() throws InterruptedException

2) public native final void notify()

3) public native final void notifyAll()

public final void wait() throws InterruptedException :-


-------------------------------------------------------------
It will put a thread into temporarly waiting state and it will release the lock.
It will wait till the another thread invokes notify() or notifyAll() for this object.

public native final void notify() :-


-------------------------------------
It will wake up the single thread that is waiting on the same object.

public native final void notifyAll() :-


----------------------------------------
It will wake up all the threads which are waiting on the same object.

*Note :- wait(), notify() and notifyAll() methods are defined in Object class but not in Thread class because
these methods are related to lock(because we can use these methods from the synchronized area ONLY)
and Object has a lock so, all these methods are defined inside Object class.

*What is the difference between sleep() and wait()


----------------------------------------------------------
(Given in the diagram 12-FEB-24)
----------------------------------------------------------------
//Program that describes if we don’t use ITC then the problem is

class Test implements Runnable


{
int var = 0;
@Override
public void run()
{
for(int i=1; i<=10; i++)
{
var = var + i; //var = 1 3 6 10 15 21 28
try
{
Thread.sleep(200);
}
catch (Exception e)
{
}
}

}
}
public class ITCProblem
{
public static void main(String[] args)
{
Test t = new Test();
Thread t1 = new Thread(t);
t1.start();
try
{
Thread.sleep(200);
}
catch (Exception e)
{
}

System.out.println(t.var);
}
}

Note :- In the above program there is no communication between


main thread and child thread so when main thread will print the value of var then it depends upon the loop
iteration.
-----------------------------------------------------------------
//Communication between main thread and child thread using ITC

class SecondThread extends Thread


{
int x = 0;

@Override
public void run()
{
//child thread is waiting for lock
synchronized(this)
{
for(int i=1; i<=100; i++)
{
x = x + i;
}
System.out.println("Sending notification");
notify();
}
}
}
public class InterThreadComm
{
public static void main(String [] args)
{
SecondThread b = new SecondThread();
b.start();

synchronized(b) //lock is taken by main thread


{
//main thread is suspended by Thread Schedular
try
{
System.out.println("Waiting for b to complete...");
b.wait(); //main thread will wait and release the lock

System.out.println("Main thread wake up");


}
catch (InterruptedException e)
{
}
System.out.println("Value is: " + b.x);
}
}
}
-----------------------------------------------------------------
class Customer
{
int balance = 10000;

public synchronized void withdraw(int amount) //amount = 15000


{
System.out.println("going to withdraw...");
if(balance < amount)
{
System.out.println("Less balance; waiting for deposit...");
try
{
wait(); //waiting and releasing the lock
}
catch(Exception e){}
}
balance = balance - amount;
System.out.println("withdraw completed..."+balance+" is remaining balance");
}

public synchronized void deposit(int amount) //amount = 9000


{
System.out.println("going to deposit...");
balance = balance + amount;
System.out.println("Balance after deposit is :"+balance);
System.out.println("deposit completed... ");
notify();
}
}
public class InterThreadBalance
{
public static void main(String args[])
{
Customer c = new Customer(); //lock is created here
Thread son = new Thread() //anonymous class concept
{
@Override
public void run()
{
c.withdraw(15000);
}
};
son.start();

Thread father = new Thread()


{
public void run()
{
c.deposit(9000);
}
};

father.start();
}
}
-----------------------------------------------------------------
13-02-2024
----------
Program on notifyAll() method which will wake up all threads which are waiting on the same objecct
class Resource
{
private boolean flag = false;

public synchronized void waitMethod()


{
System.out.println("Wait");
while (!flag)
{
try
{
System.out.println(Thread.currentThread().getName() + " is waiting...");
wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " thread completed!!");
}

public synchronized void setMethod()


{
System.out.println("notifyAll");
this.flag = true;
System.out.println(Thread.currentThread().getName() + " has make flag value as a true");
notifyAll(); // Notify all waiting threads that the signal is set
}
}
public class InterThreadNotifyAll
{
public static void main(String[] args)
{
Resource r1 = new Resource();

Thread t1 = new Thread(() -> r1.waitMethod(), "Child1");


Thread t2 = new Thread(() -> r1.waitMethod(), "Child2");
Thread t3 = new Thread(() -> r1.waitMethod(), "Child3");

Thread setter = new Thread(() -> r1.setMethod(), "Setter_Thread");

t1.start();
t2.start();
t3.start();

try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}

setter.start();
}
}
-----------------------------------------------------------------
Thread Priority :
------------------
It is possible in java to assign priority to a Thread. Thread class has provided two predefined methods
setPriority(int newPriority) and getPriority() to set and get the priority of the thread respectively.

In java we can set the priority of the Thread in number from 1- 10 only where 1 is the minimum priority
and 10 is the maximum priority.

Whenever we create a thread in java by default its priority would be 5 that is normal priority.

The user-defined thread created as a part of main thread will acquire the same priority of main Thread.

Thread class has also provided 3 final static variables which are as follows :-

Thread.MIN_PRIORITY :- 01

Thread.NORM_PRIORITY : 05

Thread.MAX_PRIORITY :- 10

Note :- We can’t set the priority of the Thread beyond the limit(1-10) so if we set the priority beyond the
limit (1 to 10) then it will generate an exception java.lang.IllegalArgumentException.
----------------------------------------------------------------
//Program that describes child thraed will acquire main thread
priority

package com.ravi.advanced;

public class MainPriority


{
public static void main(String[] args)
{
Thread t = Thread.currentThread();

System.out.println(t.getPriority());

Thread t1 = new Thread();


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

}
----------------------------------------------------------------
package com.ravi.advanced;

class ThreadP extends Thread


{
@Override
public void run()
{
int priority = Thread.currentThread().getPriority();

System.out.println("Child Thread priority is :"+priority);


}
}
public class MainPriority1
{
public static void main(String[] args)
{
Thread t = Thread.currentThread();
t.setPriority(8);

//t.setPriority(11); Invalid java.lang.IllegalArgumentException

System.out.println("Main thread priority is :"+t.getPriority());

ThreadP t1 = new ThreadP();


t1.start();
}
}
----------------------------------------------------------------
package com.ravi.advanced;

class ThreadPrior1 extends Thread


{
@Override
public void run()
{
int count = 0;

for(int i=1; i<=1000000; i++)


{
count++;
}

System.out.println("Thread name is:"+Thread.currentThread().getName());


System.out.println("Thread priority is:"+Thread.currentThread().getPriority());
}

public static void main(String args[])


{
ThreadPrior1 m1 = new ThreadPrior1();
ThreadPrior1 m2 = new ThreadPrior1();

m1.setPriority(Thread.MIN_PRIORITY);//1
m2.setPriority(Thread.MAX_PRIORITY);//10

m1.setName("Last");
m2.setName("First");

m1.start();
m2.start();
}
}

Most of time the thread having highest priority will complete its task but we can’t say that it will always
complete its task first.
----------------------------------------------------------------
Thread.yield() :
----------------
It is a static method of Thread class.

It will send a notification to thread schedular to stop the currently executing Thread (In Running state) and
provide a chance to Threads which are in Runnable state to enter inside the running state having same
priority or highest priority. Here The running Thread will directly move from Running state to Runnable
state.

The Thread schedular can ignore this notification message given by currently executing Thread.

Here there is no guarantee that after using yield() method the running Thread will move to Runnable
state and from Runnable state the thread can move to Running state.[That is the reason yield() method is
throwing InterruptedExecption]

If the thread which is in runnable state is having low priority then the same running thread will continue its
execution.

class Test implements Runnable


{
@Override
public void run()
{
for(int i=1; i<=10; i++)
{
String name = Thread.currentThread().getName();

System.out.println("i value is :"+i+" by thread :"+name);

if(name.equals("Child1"))
{
Thread.yield(); //Give a chance to Child2 Thread
}

}
}
}
public class ThreadYieldMethod
{
public static void main(String[] args)
{
Test obj = new Test();

Thread t1 = new Thread(obj, "Child1");


Thread t2 = new Thread(obj, "Child2");

t1.start(); t2.start();
}
}

Note :- In real time if a thread is acquiring more time of CPU then to release that Thread we call yield()
method the currently executing Thread.
-----------------------------------------------------------------
15-02-2024
----------
interrupt Method of Thread class :
----------------------------------
It is a predefined method of Thread class. The main purpose of this method to disturb the execution of the
Thread, if the thread is in waiting or sleeping state.

Whenever a thread is interupted then it throws InterruptedException so the thread (if it is in sleeping or
waiting mode) will get a chance to come out from a particular logic.

Points :-
---------
If we call interrupt method and if the thread is not in sleeping or waiting state then it will behave normally.

If we call interrupt method and if the thread is in sleeping or waiting state then we can stop the thread
gracefully.

*Overall interrupt method is mainly used to interrupt the


thread safely so we can manage the resources easily.

Methods :
---------
1) public void interrupt () :- Used to interrupt the Thread but the thread must be in sleeping or waiting
mode.

2) public boolean isInterrupted() :- Used to verify whether thread is interrupted or not.


----------------------------------------------------------------
Program where main thread is interrupting child thread

InterruptThread.java
--------------------
class Interrupt extends Thread
{
@Override
public void run()
{
Thread t = Thread.currentThread();
System.out.println(t.isInterrupted());

for(int i=1; i<=10; i++)


{
System.out.println(i);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
System.err.println("Thread is Interrupted ");
e.printStackTrace();
}
}
}
}
public class InterruptThread
{
public static void main(String[] args)
{
Interrupt it = new Interrupt();
System.out.println(it.getState()); //NEW STATE
it.start();
it.interrupt(); //main thread is interrupting the child thread
}
}
----------------------------------------------------------------
Program where child thread is interruping child thread itself.

class Interrupt extends Thread


{
public void run()
{
try
{
Thread.currentThread().interrupt();

for(int i=1; i<=10; i++)


{
System.out.println("i value is :"+i);
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
System.err.println("Thread is Interrupted :"+e);
}
System.out.println("Child thread completed...");
}
}
public class InterruptThread1
{
public static void main(String[] args)
{
System.out.println("Main thread is started");
Interrupt it = new Interrupt();
it.start();
System.out.println("Main thread is ended");
}
}
-----------------------------------------------------------------
public class InterruptThread2
{
public static void main(String[] args)
{
Thread thread = new Thread(new MyRunnable());
thread.start();

try
{
Thread.sleep(3000); //main thread is waiting for 2 sec
}
catch (InterruptedException e)
{
e.printStackTrace();
}

thread.interrupt();
}
}

class MyRunnable implements Runnable


{
@Override
public void run()
{
try
{
while (!Thread.currentThread().isInterrupted())
{
System.out.println("Thread is running...");
Thread.sleep(500);
}
}
catch (InterruptedException e)
{
System.out.println("Thread interrupted gracefully.");
}
finally
{
System.out.println("Thread resource can be release here.");
}
}
}

Note :- Here main thread is in sleeping mode for 3 sec, after wake up main thread is interrupting child
thread so child thread will come out from infinite loop and if any resource is attached with child thread that
will be released because child thread execution completed.
finally block is there to close the resource.
----------------------------------------------------------------
Thread Group :-
--------------
There is a predefined class called ThreadGroup available in java.lang package.

In Java it is possible to group multiple threads in a single object so, we can perform a particular operation
on a group of threads by a single method call.

The Thread class has the following constructor for ThreadGroup

new Thread(ThreadGroup groupName, Runnable target, String name);

-----------------------------------------------------------------
public class ThreadGroupDemo1
{
public static void main(String[] args)
{
ThreadGroup myThreadGroup = new ThreadGroup("NIT_Thread");

// Create and start threads within the ThreadGroup

Thread thread1 = new Thread(myThreadGroup, new MyRunnable(), "Thread 1");

Thread thread2 = new Thread(myThreadGroup, new MyRunnable(), "Thread 2");

Thread thread3 = new Thread(myThreadGroup, new MyRunnable(), "Thread 3");

thread1.start();
thread2.start();
thread3.start();

// Display information about the ThreadGroup and its threads


System.out.println("ThreadGroup Name: " + myThreadGroup.getName());

System.out.println("Active Count: " + myThreadGroup.activeCount());


}
static class MyRunnable implements Runnable //static nested inner
{
@Override
public void run()
{
for (int i = 1; i <= 3; i++)
{
System.out.println(Thread.currentThread().getName() + ": " + i);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}

Note :- We can create our own Thread group to put multiple threads into single group, Whenever we are
creating multiple threads under main thraede then all these threads are belonging to main thread
group.
------------------------------------------------------------------
Deadlock :
------------
It is a situation where two or more than two threads are in blocked state forever, here threads are waiting
to acquire another thread resource without releasing it’s own resource.

This situation happens when multiple threads demands same resource without releasing its own attached
resource so as a result we get Deadlock situation and our execution of the program will go to an infinite
state as shown in the diagram. (03-FEB-24)

public class DeadlockExample


{
public static void main(String[] args)
{
String resource1 = "Ameerpet";
String resource2 = "S R Nagar";

// t1 tries to lock resource1 then resource2

Thread t1 = new Thread()


{
@Override
public void run()
{
synchronized (resource1)
{
System.out.println("Thread 1: locked resource 1");
try
{
Thread.sleep(1000);
}
catch (Exception e)
{}

synchronized (resource2) //Nested synchronized block


{
System.out.println("Thread 1: locked resource 2");
}
}
}
};

// t2 tries to lock resource2 then resource1


Thread t2 = new Thread()
{
@Override
public void run()
{
synchronized (resource2)
{
System.out.println("Thread 2: locked resource 2");
try
{
Thread.sleep(1000);
}
catch (Exception e)
{}

synchronized (resource1) //Nested synchronized block


{
System.out.println("Thread 2: locked resource 1");
}
}
}
};
t1.start();
t2.start();
}
}

Here both the Threads are waiting for the alternate resources without releasing the attached resource so
this situation is known as Deadlock.
------------------------------------------------------------------
16-02-2024
-----------
Daemon Thread [Service Level Thread]:
--------------------------------------
Daemon thread is a low- priority thread which is used to provide background maintenance.

The main purpose of of Daemon thread to provide services to the user thread.

JVM can’t terminate the program till any of the non-daemon (user) thread is active, once all the user
thread will be completed then JVM will terminate all Daemon threads, which are running in the
background to support user threads.
The example of Daemon thread is Garbage Collection thread, which is running in the background for
memory management.

In order to make a thread as a Daemon thread , we should use setDaemon(true)


----------------------------------------------------------------
public class DaemonThreadDemo1
{
public static void main(String[] args)
{
System.out.println("Main Thread Started...");

Thread daemonThread = new Thread(() ->


{
while (true)
{
System.out.println("Daemon Thread is running...");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
});

daemonThread.setDaemon(true);
daemonThread.start();

Thread userThread = new Thread(() ->


{
for (int i = 1; i <= 9; i++)
{
System.out.println("User Thread: " + i);
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
});

userThread.start();

System.out.println("Main Thread Ended...");


}
}
---------------------------------------------------------------
Remaining method of Object class :
----------------------------------
Object cloning in java :
----------------------------
Object cloning is the process of creating an exact copy of an existing object in the memory.

Object cloning can be done by the following process :

1) Creating Shallow copy

2) Creating Deep copy

3) Using clone() method of java.lang.Object class

4) Passing Object reference to the Constructor.

Shallow Copy :
-----------------
In shallow copy, we create a new reference variable which will point to same old existing object so if we
make any changes through any of the reference variable then original object content will be modified.

Here we have one object and multiple reference variables.

Hashcode of the object will be same.

package com.ravi.clone_method;

class Student
{
int id;
String name;

@Override
public String toString()
{
return "Id is :" + id + "\nName is :" + name ;
}

}
public class ShallowCopy
{
public static void main(String[] args)
{
Student s1 = new Student();
s1.id = 111;
s1.name = "Ravi";

System.out.println(s1);

System.out.println("After Shallow Copy");

Student s2 = s1; //shallow copy


s2.id = 222;
s2.name = "Shankar";

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

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

}
----------------------------------------------------------------
Deep Copy :
--------------
In deep copy, We create a copy of object in a different memory location. This is called a Deep copy.

Here objects are created in two different memory locations so if we modify the content of one object it will
not reflect another object.

package com.ravi.clone_method;

class Employee
{
int id;
String name;

@Override
public String toString()
{
return "Employee [id=" + id + ", name=" + name + "]";
}
}

public class DeepCopy


{
public static void main(String[] args)
{
Employee e1 = new Employee();
e1.id = 111;
e1.name = "Ravi";

Employee e2 = new Employee();


e2.id = e1.id;
e2.name = e1.name;

System.out.println(e1 +" : "+e2);

e2.id = 222;
e2.name = "shankar";
System.out.println(e1 +" : "+e2);

System.out.println(e1.hashCode() +" : "+e2.hashCode());


}

}
---------------------------------------------------------------

protected native Object clone() throws CloneNotSupportedException


----------------------------------------------------------------
Object cloning in Java is the process of creating an exact copy of the original object. In other words, it is a
way of creating a new object by copying all the data and attributes from the original object.

The clone method of Object class creates an exact copy of an object.

In order to use clone() method , a class must implements Clonable interface because we can perform
cloning operation on Cloneable objects only [JVM must have additional information].

We can say an objeect is a Cloneable object if the corresponding class implements Cloneable interface.

It throws a checked Exception i.e CloneNotSupportedException

Note :- clone() method is not the part of Clonable interface[marker interface], actually it is the method of
Object class.

clone() method of Object class follow deep copy concept so hashcode will be different.
---------------------------------------------------------------
package com.ravi.clone_method;

class Customer implements Cloneable


{
int id;
String name;

@Override
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}

@Override
public String toString()
{
return "Customer [id=" + id + ", name=" + name + "]";
}
}

public class CloneMethod


{
public static void main(String[] args) throws CloneNotSupportedException
{
Customer c1 = new Customer();
c1.id = 222;
c1.name = "Rahul";

Customer c2 = (Customer) c1.clone(); //deep copy


c2.id = 333;
c2.name = "Rohit";

System.out.println(c1);
System.out.println(c2);

System.out.println(c1.hashCode());
System.out.println(c2.hashCode());

}
---------------------------------------------------------------
protected void finalize() throws Throwable :
---------------------------------------------------
It is a predefined method of Object class.

Garbage Collector automatically call this method just before an object is eligible for garbage collection to
perform clean-up activity.

Here clean-up activity means closing the resources associated with that object like file connection,
database connection, network connection and so on we can say resource de-allocation.

Note :- JVM calls finalize method only one per object.

package com.ravi.finalize_method;

public class Student


{
int id;
String name;

public Student(int id, String name)


{
this.id= id;
this.name = name;
}

@Override
public String toString()
{
return "Id is :"+id+"\nName is :"+name;
}

@Override
protected void finalize()
{
System.out.println("JVM call this finalize method...");
}

public static void main(String[] args) throws InterruptedException


{
Student s1 = new Student(111,"Ravi");
System.out.println(s1.hashCode());
System.out.println(s1);

//s1 = null;
System.gc(); //Explicitly calling Garbage Collector
Thread.sleep(3000);
System.out.println(s1);
}

}
----------------------------------------------------------------
*What is the difference between final, finally and finalize

final :- It is a keyword which is used to provide some kind of restriction like class is final, Method is
final,variable is final.

finally :- if we open any resource as a part of try block then


that particular resource must be closed inside
finally block otherwise program will be terminated ab-normally and the corresponding resource will not
be closed (because the remaining lines of try block will not be executed)

finalize() :- It is a method which JVM is calling automatically just before object destruction so if
any resource
(database, file and network) is associated with
that particular object then it will be closed
or de-allocated by JVM by calling finalize().
----------------------------------------------------------------
17-02-2024
----------
Problem Statement:

You are tasked with creating an education institute course enrollment system using Java. The system
should provide courses and offers to students, allowing them to view available courses, ongoing offers,
and enroll in their preferred courses.

Classes:
Take one BLC class Course

Attributes:

-> courseId (int): Unique identifier for the course.

-> courseName (String): Name of the course.

-> corseFee (double): Fee for the course.

Methods:

-> Parameterized Constructor to initialize the instance variable.

-> Generate getters for all field

-> Override toString() method

class Offer:

Attributes:
-> offerText (String): Description of the special offer provided by the education institute.

Methods:

-> Offer(String offerText): Constructor to initialize the offer description.

-> getOfferText(): Returns the offer description.

class EducationInstitute:

Attributes:

-> courses (Course[]): An array to store the available courses.

-> offers (Offer[]): An array to store ongoing offers.

Methods:

-> EducationInstitute(): Constructor to initialize courses and offers.

-> getCourses(): Returns the array of available courses.

-> getOffers(): Returns the array of ongoing offers.

-> enrollStudentInCourse(int courseId, String studentName): Simulates the enrollment process and prints
a message when a student -> enrolls in a course.

class Student:

Attributes:

-> name (String): Name of the student.

-> institute (EducationInstitute): Reference to the education institute where the student interacts.

Methods:

-> Student(String name, EducationInstitute institute): Constructor to initialize the student with their name
and the education institute reference.

-> viewCoursesAndFees(): Displays the available courses and their fees.

-> viewOffers(): Displays the ongoing offers.


-> enrollInCourse(int courseId): Enrolls the student in the specified course using the education institutes
enrollment process.

class Main :

The EducationInstituteApp class is the main program that simulates concurrent student interactions using
threads.

It creates an education institute, initializes students, and allows them to view course details, ongoing
offers, and enroll in courses concurrently without disturbing the execution flow of each thread.

Instructions for Students:

-> Implement the above classes and their methods following the given specifications.

-> Create an instance of EducationInstitute, and initialize courses and offers with hardcoded data for
simplicity.

-> Create two students: Virat and Dhoni. Allow them to view available courses, check ongoing offers, and
enroll in their preferred courses concurrently using threads.

-> Use the Thread class to simulate concurrent student interactions. Ensure that the system provides a
responsive user experience for multiple students.

-> Test your program with multiple executions and verify that students can view course details, offers, and
enroll without conflicts.

-> Feel free to enhance the program with additional features or error handling to further improve its
functionality.

[Note : Include appropriate comments and use meaningful variable names to make your code more
readable and understandable.]

Sample Output :

Available Courses:

1. Mathematics - Fee: Rs.1000.0

2. Science - Fee: Rs.1200.0

3. English - Fee: Rs.900.0


Ongoing Offers:

Special discount: Get 20% off on all courses!

Limited time offer: Enroll in any two courses and get one course free!

Virat has enrolled in the course: Mathematics

Available Courses:

1. Mathematics - Fee: Rs.1000.0

2. Science - Fee: Rs.1200.0

3. English - Fee: Rs.900.0

Ongoing Offers:

Special discount: Get 20% off on all courses!

Limited time offer: Enroll in any two courses and get one course free!

Dhoni has enrolled in the course: Science


---------------------------------------------------------------
5 files :
---------
Course.java
------------
package com.ravi.lab;

public class Course {


private int courseId;
private String courseName;
private double courseFee;

public Course(int courseId, String courseName, double courseFee) {


super();
this.courseId = courseId;
this.courseName = courseName;
this.courseFee = courseFee;
}

public int getCourseId() {


return courseId;
}

public String getCourseName() {


return courseName;
}

public double getCourseFee() {


return courseFee;
}
@Override
public String toString() {
return "Course [courseId=" + courseId + ", courseName=" + courseName + ", courseFee=" + courseFee
+ "]";
}

Offer.java
----------

package com.ravi.lab;

public class Offer {


private String offerText;

public Offer(String offerText) {


super();
this.offerText = offerText;
}

public String getOfferText() {


return offerText;
}

EducationInstitute.java
-------------------------

package com.ravi.lab;

public class EducationInstitute {


private Course[] courses;
private Offer[] offers;

public EducationInstitute(Course[] courses, Offer[] offers) {


super();
this.courses = courses;
this.offers = offers;
}

public Course[] getCourses() {


return courses;
}

public Offer[] getOffers() {


return offers;
}

public void enrollStudentInCourse(int courseId, String studentName)


{
for(int i=0; i<courses.length; i++)
{
if(courseId == courses[i].getCourseId())
{
System.out.println(studentName+" enrolled in :"+courses[i].getCourseName());
}
}

Student.java
------------
package com.ravi.lab;

public class Student {


private String studentName;
private EducationInstitute educationInstitute;

public Student(String studentName, EducationInstitute educationInstitute) {


super();
this.studentName = studentName;
this.educationInstitute = educationInstitute;
}

public void viewCoursesAndFees()


{
Course[] courses = educationInstitute.getCourses();
for(Course course : courses)
{
System.out.println(course.getCourseId()+" : "+course.getCourseName()+" : "+course.getCourseFee());
}
}

public void viewOffers()


{
Offer[] offers = educationInstitute.getOffers();

for(Offer offer : offers)


{
System.out.println(offer.getOfferText());
}

public void enrollInCourse(int courseId)


{
educationInstitute.enrollStudentInCourse(courseId, studentName);
}
}

Main.java
---------
package com.ravi.lab;

public class Main {

public static void main(String[] args) throws InterruptedException


{
Course [] courses = new Course[3];
courses[0] = new Course(1, "Java", 1000);
courses[1] = new Course(2, ".NET", 1200);
courses[2] = new Course(3, "Python", 900);

Offer [] offers = new Offer[2];


offers[0]= new Offer("Special discount: Get 20% off on all courses!");
offers[1] = new Offer("Limited time offer: Enroll in any two courses and get one course free!");

EducationInstitute ei = new EducationInstitute(courses, offers);

Student virat = new Student("Virat", ei);


Student dhoni = new Student("Dhoni", ei);
Student sachin = new Student("Sachin", ei);

Thread t1 = new Thread()


{
@Override
public void run()
{
System.out.println("Available courses and Fess :");
virat.viewCoursesAndFees();
virat.viewOffers();
virat.enrollInCourse(1);
}

};

Thread t2 = new Thread()


{
@Override
public void run()
{
System.out.println("Available courses and Fess :");
dhoni.viewCoursesAndFees();
dhoni.viewOffers();
dhoni.enrollInCourse(2);
}

};

Thread t3 = new Thread()


{
@Override
public void run()
{
System.out.println("Available courses and Fess :");
sachin.viewCoursesAndFees();
sachin.viewOffers();
sachin.enrollInCourse(3);
}

};

t1.start();
t1.join();
System.out.println("------------------------------");
t2.start();
t2.join();
System.out.println("------------------------------");
t3.start();

}
----------------------------------------------------------------
Record class in java :
-----------------------
public abstract class Record extends Object.

It is a new feature introduced from java 17.(In java 14 preview version)

As we know only objects are moving in the network from one place to another place so we need to write
BLC class with nessacery requirements to make BLC class as a Data carrier class.

Records are immutable data carrier so, now with the help of record we can send our immutable data from
one application to another application.

It is also known as DTO (Data transfer object) OR POJO classes.

It is mainly used to concise our code as well as remove the boiler plate code.

In record, automatically constructor will be generated which is known as canonical constructor and the
variables which are known as components are by default final.

In order to validate the outer world data, we can write our own constructor which is known as compact
constructor.

Record will automatically generate the implemenation of toString(), equals(Object obj) and hashCode()
method.

We can define static and non static method as well as static variable inside the record. We cannot define
instance variable inside the record.

We cann’t extend or inherit records because by default every record is implicilty final. It is extending from
java.lang.Reocrd class

We can implement an interface by using record.

We don’t have setter facility in record because by default variables are final.

3 files :
---------
EmployeeClass.java
------------------
package com.ravi.record_demo;

import java.util.Objects;

public class EmployeeClass {


private int employeeId;
private String employeeName;

public EmployeeClass(int employeeId, String employeeName) {


super();
this.employeeId = employeeId;
this.employeeName = employeeName;
}

public int getEmployeeId() {


return employeeId;
}

public void setEmployeeId(int employeeId) {


this.employeeId = employeeId;
}

public String getEmployeeName() {


return employeeName;
}

public void setEmployeeName(String employeeName) {


this.employeeName = employeeName;
}

@Override
public String toString() {
return "EmployeeClass [employeeId=" + employeeId + ", employeeName=" + employeeName + "]";
}

@Override
public int hashCode() {
return Objects.hash(employeeId, employeeName);
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EmployeeClass other = (EmployeeClass) obj;
return employeeId == other.employeeId && Objects.equals(employeeName, other.employeeName);
}
}
EmployeeRecord.java(R)
----------------------

package com.ravi.record_demo;

//Canonical Constructor
public record EmployeeRecord(int empId, String empName)
{

//Compact Constructor
public EmployeeRecord
{
if(empId < 0)
{
throw new IllegalArgumentException("Id is Invalid");
}

Main.java
---------
package com.ravi.record_demo;

public class Main {

public static void main(String[] args)


{
EmployeeClass e1 = new EmployeeClass(111, "Scott");
System.out.println(e1);
EmployeeClass e2 = new EmployeeClass(111, "Scott");
System.out.println(e1.equals(e2));
System.out.println(e1.getEmployeeName());
e1.setEmployeeId(999);
System.out.println(e1);

System.out.println("--------------------");
EmployeeRecord r1 = new EmployeeRecord(-222, "Smith");
System.out.println(r1);
EmployeeRecord r2 = new EmployeeRecord(222, "Smith");
System.out.println(r1.equals(r2));
System.out.println(r1.empName());
}
}
---------------------------------------------------------------
19-02-2024
-----------
Wrapper classes in java :
----------------------------
In java we have 8 primitive data types i.e byte, short, int, long, float, double, char and boolean.
Except these primitives, everything in java is an Object.

If we remove these 8 data types from java then Java will become pure Object Oriented language.

Wrapper class is a technique through which we can convert the primitives to corresponding object. Now it
can be divided into two types from 1.5 onwards

a) Autoboxing
b) Unboxing

Autoboxing
--------------
When we convert the primitive data types into corresponding wrapper object then it is called Autoboxing
as shown below.

Primitive type Wrapper Object


---------------- ------------------
byte - Byte

short - Short

int - Integer

long - Long

float - Float

double - Double

char - Chracter

boolean - Boolean

Note :- Wrapper classes has provided valueOf() method through which we can convert the primitive into
Object.

//Integer.valueOf(int);
public class AutoBoxing1
{
public static void main(String[] args)
{
int a = 12;
Integer x = Integer.valueOf(a); //Upto 1.4 version
System.out.println(x);

int y = 15;
Integer i = y; //From 1.5 onwards compiler takes care
System.out.println(i);
}
}

Note :- Integer class has provided predefined static method called


valueOf(int x), the return type of this method is Integer class.
----------------------------------------------------------------
public class AutoBoxing2
{
public static void main(String args[])
{
int y = 12;
Integer x = y;
System.out.println(x);

double e = 45.90;
Double d = e;
System.out.println(d);

boolean a = true;
Boolean b = a;
System.out.println(b);
}
}
----------------------------------------------------------------
WAP to convert a String into integer using base 2
-------------------------------------------------
By using Integer.parseInt(String str), whenever we convert any String into integer then by default it will
take base 10.

We have overloaded method of parseInt() which is taking two


parameters parseInt(String str, int base/radix) which will the String into integer based on the specified
base or radix as shown in the program.

package com.ravi.wrapper;

public class ParseIntUsingRadix


{
public static void main(String[] args)
{
String str = "111";
int val = Integer.parseInt(str , 2);
System.out.println(val);

Note :- In the above progarm we can pass base OR radix upto 36


i.e A to Z (26) + 0 to 9 (10) -> [26 + 10 = 36], It can be
calculated by using Character.MAX_RADIX.
Output will be generated on the basis of radix
----------------------------------------------------------------Integer class has provided the following overloaded
methods which are as follows :

public Integer valueOf(int x) :- Primitive to Integer Wrapper

public Integer valueOf(String x) :- String to Integer Wrapper


public Integer valueOf(String x, int radix/base) :- String to Integer object by using specified base/radix.

//Integer.valueOf(String str)
//Integer.valueOf(String str, int radix/base)
public class AutoBoxing3
{
public static void main(String[] args)
{
Integer a = Integer.valueOf(15);

Integer b = Integer.valueOf("25");

Integer c = Integer.valueOf("111",2); //Here Base we can take upto 36

System.out.println(a);
System.out.println(b);
System.out.println(c);

}
}
---------------------------------------------------------------
public class AutoBoxing4
{
public static void main(String[] args)
{
Integer i1 = new Integer(100);
Integer i2 = new Integer(100);
System.out.println(i1==i2);

Integer a1 = Integer.valueOf(15);
Integer a2 = Integer.valueOf(15);
System.out.println(a1==a2);
}
}

We will get false and true, new keyword always create different memory location but valueOf() method will
return Integer object and according to above program a1 and a2 both will point to same memory location.
---------------------------------------------------------------
//Converting integer value to String
public class AutoBoxing5
{
public static void main(String[] args)
{
int x = 12;
String str = Integer.toString(x);
System.out.println(str+2);
}
}
---------------------------------------------------------------
package com.ravi.wrapper;

public class AutoBoxing6


{
public static void main(String[] args)
{
char ch = ’A’;
Character chObj = Character.valueOf(ch);
System.out.println(chObj);

boolean b = true;
Boolean boolObj = Boolean.valueOf(b);
System.out.println(boolObj);

}
---------------------------------------------------------------
Unboxing :
----------------
Converting wrapper object to corresponding primitive type is called Unboxing.

Wrapper Primitive
Object type
---------- ----------
Byte - byte

Short - short

Integer - int

Long - long

Float - float

Double - double

Chracter - char

Boolean - boolean
----------------------------------------------------------------
//Converting Wrapper object into primitive
public class AutoUnboxing1
{
public static void main(String args[])
{
Integer obj = 15; //Upto 1.4
int x = obj.intValue();
System.out.println(x);
}
}
----------------------------------------------------------------
public class AutoUnboxing2
{
public static void main(String[] args)
{
Integer x = 25;
int y = x; //JDK 1.5 onwards
System.out.println(y);
}
}

Byte, Short, Integer, Long, Float and Double all these 6 wrapper classes are the sub class of
java.lang.Number class. All these 6 classes are providing the following 6 common methods

1) public byte byteValue()

2) public short shortValue()

3) public int intValue()

4) public long longValue()

5) public float floatValue()

6) public dopuble doubleValue()


----------------------------------------------------------------
public class AutoUnboxing3
{
public static void main(String[] args)
{
Integer i = 15;
System.out.println(i.byteValue());
System.out.println(i.shortValue());
System.out.println(i.intValue());
System.out.println(i.longValue());
System.out.println(i.floatValue());
System.out.println(i.doubleValue());
}
}
----------------------------------------------------------------
public class AutoUnboxing4
{
public static void main(String[] args)
{
Character c1 = ’A’;
char ch = c1.charValue();
System.out.println(ch);
}
}
---------------------------------------------------------------
public class AutoUnboxing5
{
public static void main(String[] args)
{
Boolean b1 = true;
boolean b = b1.booleanValue();
System.out.println(b);
}
}
---------------------------------------------------------------
class BufferTest
{
public static void main(String[] args)
{
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1==i2); //true

Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3==i4); //false

Integer i5 = 128;
Integer i6 = 128;
System.out.println(i5.equals(i6)); //true
}
}
---------------------------------------------------------------
Collection Framework (40 to 45% IQ)
-----------------------------------
Collection Framework in java (40 - 45% IQ):
-------------------------------------------
Collections framework is nothing but handling individual Objects(Collection Interface) and Group of
objects(Map interface).

We know only object can move from one network to another network.

A collections framework is a class library to handle group of Objects.

It is implemented by using java.util package.

It provides an architecture to store and manipulate group of objects.

All the operations that we can perform on data such as searching, sorting, insertion and deletion can be
done by using collections framework because It is the data structure of Java.

The simple meaning of collections is single unit of Objects.


----------------------------------------------------------------

It provides the following sub interfaces :

1) List (Accept duplicate elements)


2) Set (Not accepting duplicate elements)
3) Queue (Storing and Fetching the elements based on some order i.e FIFO)

Collection is an interface in java.util package where as Collections is predefined class which contains
various static method available in java.util package.
-----------------------------------------------------------------
21-02-2024
----------
Methods of Collection interface :
---------------------------------
a) public boolean add(Object element) :- It is used to add an item/element in the collection.

b) public boolean addAll(Collection c) :- It is used to insert the specified collection elements in the existing
collection(For merging the Collection)
c) public boolean retainAll(Collection c) :- It is used to retain all the elements from existing element.
(Common Element)

d) public boolean removeAll(Collection c) :- It is used to delete all the elements from the existing
collection.

e) public boolean remove(Object element) :- It is used to delete an element from the collection.

f) public int size() :- It is used to find out the size of the Collection.

g) public void clear() :- It is used to clear all the elements at once from the Collection.
-----------------------------------------------------------------
Behavior of List interface specific classes :
---------------------------------------------
1) Accepting hetrogeneous types of data.
2) Accepting null element.
3) Accepting duplicate elements.
4) Stores the elements based on the index.
5) Stores everything in the form of Object.
6) By using generics (<>), we can eliminate compilation warning
and still we can take hetrogeneous by using Object class.

Vector<Object> v = new Vector<>(); //valid

7) IT IS DYNAMICALLY GROWABLE. (Except LinkedList)


-----------------------------------------------------------------
22-02-2024
----------
Hierarchy of List interface :
------------------------------
Diagram (22-FEB-24)
------------------------------------------------------------------
List interface :
----------------
It is the sub interface of Collection interface.

It accepts duplicate elements.

It stores the elements based on the index

By using Collections.sort() we can sort List interface.


-----------------------------------------------------------------
Methods of List interface :
------------------------------
1) public boolean isEmpty() :- Verify whether List is empty or not

2) public void clear() :- Will clear all the elements

3) public int size() :- To get the size of the Collections

4) public void add(int index, Object o) :- Insert the element based on the index position.

5) public boolean addAll(int index, Collection c) :- Insert the Collection based on the index position
6) public Object get(int index) :- To retrieve the element based on the index position

7) public Object set(int index, Object o) :- To override or replace the existing element based on the index
position

8) public Object remove(int index) :- remove the element based on the index position

9) public boolean remove(Object element) :- remove the element based on the object element, It is the
Collection interface method extended by List interface

10) public int indexOf() :- index position of the element

11) public int lastIndex() :- last index position of the element

12) public Iterator iterator() :- To fetch or iterate or retrieve the elements from Collection in forward
direction only.

13) public ListIterator listIterator() :- To fetch or iterate or retrieve the elements from Collection in forward
and backward direction
------------------------------------------------------------------
** How many ways we can fetch the Collection object ?
-----------------------------------------------------
There are 7 ways to fetch the Collection object which are as follows :

1) Using Enumeration interface (JDK 1.0)

2) Using Ordinary for loop (JDK 1.0)

3) Using for each loop (JDK 1.5)

4) Using Iterator interface (JDK 1.2 and enhancement from java 8)

5) Using ListIterator interface (JDK 1.2)

*6) Using forEach(Consumer<T> cons) method (JDK 1.8)

*7) Using Method Reference (::) (JDK 1.8)

Note : Among all these 7 ways, Enumeration, Iterator and ListIterator are cursor (Can move from one
direction to another direction)
------------------------------------------------------------------
Enumeration :
----------------
It is a predefined interface available in java.util package from JDK 1.0 onwards.

We can use Enumeration interface to fetch or retrieve the Objects one by one from the Collection
because it is a cursor.

We can create Enumeration object by using elements() method of the legacy Collection class.

public Enumeration elements();

Enumeration interface contains two methods :


---------------------------------------------------
1) public boolean hasMoreElements() :- It will return true if the Collection is having more elements.

2) public Object nextElement() :- It will return collection object so return type is Object.

Iterator interface :
----------------------
It is a predefined interface available in java.util package available from 1.2 version.

It is used to fetch/retrieve the elements from the Collection in forward direction only because it is also a
cursor.

public Iterator iterator();

Example :
-----------
Iterator itr = v.iterator();

Now, Iterator interface has provided two methods

public boolean hasNext() :-

It will verify, the element is available in the next position or not, if available it will return true otherwise it
will return false.

public Object next() :- It will return the collection object.


-----------------------------------------------------------------
ListIterator interface :
-------------------------
It is a predefined interface available in java.util package and it is the sub interface of Iterator.

It is used to retrieve the Collection object in both the direction i.e in forward direction as well as in
backward direction.

public ListIterator listIterator();

Example :
-----------
ListIterator lit = v.listIterator();

1) public boolean hasNext() :-


It will verify the element is available in the next position or not, if available it will return true otherwise it will
return false.

2) public Object next() :- It will return the next position collection object.

3) public boolean hasPrevious() :-


It will verify the element is available in the previous position or not, if available it will return true otherwise
it will return false.

4) public Object previous () :- It will return the previous position collection object.

Note :- Apart from these 4 methods we have add(), set() and remove() method in ListIterartor interface
By using forEach() method :
--------------------------------
From java 1.8 onwards every collection class provides a method forEach() method, this method takes
Consumer functional interface as a parameter.

Program to fetch the Collection Object by using all 7 ways :


------------------------------------------------------------
package com.ravi.collection;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;

public class FetchingCollectionObject {

public static void main(String[] args)


{
Vector<String> fruits = new Vector<>();
fruits.add("Mango");
fruits.add("Orange");
fruits.add("Apple");
fruits.add("Guava");
fruits.add("Grapes");

System.out.println("FETCHING THE DATA FROM ENUMERATION");

Enumeration<String> ele = fruits.elements();

while(ele.hasMoreElements())
{
System.out.println(ele.nextElement());
}

System.out.println("DATA FROM ORDINARY FOR LOOP");

for(int i=0; i<fruits.size();i++)


{
System.out.println(fruits.get(i));
}

System.out.println("DATA FROM FOR EACH LOOP");

for(String fruit : fruits)


{
System.out.println(fruit);
}

System.out.println("DATA FROM ITERATOR INTERFACE");

Iterator<String> itr = fruits.iterator();


itr.forEachRemaining(fruit-> System.out.println(fruit));

/*while(itr.hasNext())
{
System.out.println(itr.next());
}*/

System.out.println("DATA FROM LISTITERATOR INTERFACE");

ListIterator<String> lst = fruits.listIterator();

System.out.println("IN FORWARD DIRECTION");

while(lst.hasNext())
{
System.out.println(lst.next());
}

System.out.println("IN BACKWARD DIRECTION");

while(lst.hasPrevious())
{
System.out.println(lst.previous());
}

System.out.println("FETCHING BY USING FOR EACH METHOD");


fruits.forEach(fruit-> System.out.println(fruit.toUpperCase()));

System.out.println("BY USING METHOD REFERENCE");


fruits.forEach(System.out::println);
}

}
----------------------------------------------------------------
How forEach(Consumer<T> cons) works internally ?
------------------------------------------------
package com.ravi.collection;

import java.util.Vector;
import java.util.function.Consumer;

public class InternalWorkingOfForEach


{
public static void main(String[] args)
{
Vector<String> fruits = new Vector<>();
fruits.add("Mango");
fruits.add("Orange");
fruits.add("Apple");
fruits.add("Guava");
fruits.add("Grapes");

//1st approach
Consumer<String> cons1 = new Consumer<String>()
{
@Override
public void accept(String t)
{
System.out.println(t.toUpperCase());
}

};

fruits.forEach(cons1);

//2nd approach (Concise form)


Consumer<String> cons2 = (t)-> System.out.println(t);
fruits.forEach(cons2);

//3rd Approach
fruits.forEach((t)-> System.out.println(t));

}
----------------------------------------------------------------
ArrayList :
-----------
public class ArrayList<E> extends AbstractList<E> implements List<E>, Serializable, Clonable,
RandomAccess

It is a predefined class available in java.util package under List interface.

It accepts duplicate elements and null values.

It is dynamically growable array.

It stores the elements on index basis so it is simillar to dynamic array.

Initial capacity of ArrayList is 10. The new capacity of Arraylist can be calculated by using the formula
new capacity = (current capacity * 3)/2 + 1

*All the methods declared inside an ArrayList is not synchronized so multiple thread can access the
method of ArrayList.

*It is highly suitable for fetching or retriving operation when duplicates are allowed and Thread-safety is
not required.

It implements List,Serializable, Clonable, RandomAccess interfcaes

Constructor of ArrayList :
----------------------------
In ArrayList we have 3 types of Constructor:
Constructor of ArrayList :
----------------------------
We have 3 types of Constructor in ArrayList

1) ArrayList al1 = new ArrayList();


Will create ArrayList object with default capacity 10.

2) ArrayList al2 = new ArrayList(int initialCapacity);


Will create an ArrayList object with user specified Capacity
3) ArrayList al3 = new ArrayList(Collection c)
We can copy any Collection interface implemented class data to the current object reference (Coping
one Collection data to another)
----------------------------------------------------------------
import java.util.*;
public class ArrayListDemo1
{
public static void main(String... a)
{
ArrayList<String> arl = new ArrayList<>();//Generic type
arl.add("Apple");
arl.add("Orange");
arl.add("Grapes");
arl.add("Mango");
arl.add("Guava");
arl.add("Mango");

System.out.println("Contents :"+arl); //toString() [Apple,....]

arl.remove(2); //based on the index position [List]


arl.remove("Guava"); //based on the Object [Collection]

System.out.println("Contents After Removing :"+arl);


System.out.println("Size of the ArrayList:"+arl.size());

Collections.sort(arl);

arl.forEach(System.out::println);
}
}
----------------------------------------------------------------
//ArrayList to work with custom object.

2 files :
---------
Product.java(R)
---------------
package com.ravi.collection;

public record Product(int pid, String pname)


{

ArrayListDemo2.java
---------------------
package com.ravi.collection;

import java.util.ArrayList;

public class ArrayListDemo2


{
public static void main(String[] args)
{
ArrayList<Product> listOfProduct = new ArrayList<>();
listOfProduct.add(new Product(333, "Camera"));
listOfProduct.add(new Product(111, "Mobile"));
listOfProduct.add(new Product(222, "Laptop"));

listOfProduct.forEach(System.out::println);
}

}
---------------------------------------------------------------
//Program to merge and retain of two collection
import java.util.*;
public class ArrayListDemo2
{
public static void main(String args[])
{
ArrayList<String> al1=new ArrayList<>();
al1.add("Ravi");
al1.add("Rahul");
al1.add("Rohit");

ArrayList<String> al2=new ArrayList<>();


al2.add("Pallavi");
al2.add("Sweta");
al2.add("Puja");

al1.addAll(al2);

al1.forEach(x -> System.out.println(x.toUpperCase()));

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

ArrayList<String> al3=new ArrayList<>();


al3.add("Ravi");
al3.add("Rahul");
al3.add("Rohit");

ArrayList<String> al4=new ArrayList<>();


al4.add("Pallavi");
al4.add("Rahul");
al4.add("Raj");

al3.retainAll(al4);

al3.forEach(x -> System.out.println(x));


}
}
---------------------------------------------------------------
package com.ravi.collection;

import java.util.Arrays;
import java.util.List;

public class ArrayListDemo2


{
public static void main(String[] args)
{
List<String> list = Arrays.asList("Ravi","NIT","HYD");
list.add("Rahul");//UnsupportedOperationException

list.forEach(System.out::println);
}

java.util.Arrays class is containing a predefined static method


asList(T ...x) through which we can create list of elements, after creating we can’t perform any kind of
operartion otherwise
UnsupportedOperationException will be generated as shown in the above program.
----------------------------------------------------------------
package ConcurrentModification;

import java.util.ArrayList;
import java.util.Iterator;

class Concurrent extends Thread


{
ArrayList<String> al = null;

public Concurrent(ArrayList<String> al) //al = arl


{
this.al = al;
}

@Override
public void run()
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
al.add("Kiwi");
}

public class ArrayListDemo {

public static void main(String[] args) throws InterruptedException


{
ArrayList<String> arl = new ArrayList<>();
arl.add("Apple");
arl.add("Mango");
arl.add("Grapes");
arl.add("Guava");

Concurrent con = new Concurrent(arl);


con.start();

Iterator<String> itr = arl.iterator();

while(itr.hasNext())
{
System.out.println(itr.next());
Thread.sleep(1500);
}
}

ArrayList is not synchronized hence if multiple threads are accessing the al object then it will generate
wrong output.

Here main thraed is iterating the String object from arraylist meanwhile child thread is modifying the
original list so
java.util.ConcurrentModificationException
----------------------------------------------------------------
//Program to fetch the elements in forward and backward
//direction using ListIterator interface

package com.ravi.arraylist;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

public class ArrayListDemo3


{
public static void main(String args[])
{
List<String> listOfName = Arrays.asList("Rohit","Akshar","Pallavi","Sweta");

Collections.sort(listOfName);

//Fetching the data in both the direction


ListIterator<String> lst = listOfName.listIterator();

System.out.println("In Forward Direction..");


while(lst.hasNext())
{
System.out.println(lst.next());
}
System.out.println("In Backward Direction..");
while(lst.hasPrevious())
{
System.out.println(lst.previous());
}
}
}
----------------------------------------------------------------
//Serialization and De-serialization on ArrayList Object
package com.ravi.arraylist;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class ArrayListDemo4


{
public static void main(String [] args) throws Exception
{
ArrayList<String> listOfCity = new ArrayList<>();
listOfCity.add("Hyderabad");
listOfCity.add("Mumbai");
listOfCity.add("Delhi");
listOfCity.add("Kolkata");

listOfCity.forEach(System.out::println);

//Serialization
var fos = new FileOutputStream("C:\\new\\City.txt");
var oos = new ObjectOutputStream(fos);

try(oos; fos)
{
oos.writeObject(listOfCity);
}
catch(Exception e)
{
e.printStackTrace();
}

//De-serialization
var fin = new FileInputStream("C:\\new\\City.txt");
var ois = new ObjectInputStream(fin);

ArrayList<String> al = (ArrayList<String>) ois.readObject();


System.out.println(al);

}
----------------------------------------------------------------

public void ensureCapacity(int minimumCapacity) :


--------------------------------------------------
It is a predefined method of ArrayList class, by using this method we can resize the capacity of ArrayList
Object.

Here by specifying the parameter it ensures that it can hold at least the number of elements specified by
the minimum capacity argument.

ArrayList class does not provide capacity() method support.

package com.ravi.arraylist;

import java.util.ArrayList;
import java.util.LinkedList;

public class ArrayListDemo5


{
public static void main(String[] args)
{
ArrayList<String> city= new ArrayList<>();

city.ensureCapacity(3); //resize the capacity of Arraylist


city.add("Hyderabad");
city.add("Mumbai");
city.add("Delhi");

city.add("Kolkata");
System.out.println("ArrayList: " + city);
}
}

----------------------------------------------------------------
package com.ravi.arraylist;

//Program on ArrayList that contains null values as well as we can pass the element based on the index
position
import java.util.ArrayList;
import java.util.LinkedList;
public class ArrayListDemo6
{
public static void main(String[] args)
{
ArrayList<Object> al = new ArrayList<>(); //Generic type
al.add(12);
al.add("Ravi");
al.add(12);
al.add(3,"Hyderabad"); //add(int index, Object o)method of List interface
al.add(1,"Naresh");
al.add(null);
al.add(11);
System.out.println(al); //12 Naresh Ravi 12 Hyderabad
}
}
----------------------------------------------------------------
27-02-2024
-----------
Limitation of ArrayList :
-------------------------
The time complexcity of ArrayList to insert and delete an element from the middle would be O(n) because
’n’ number of elements will be re-located so it is not a good choice to perform insertion and deletion
operation in the middle of the List. [26-FEB-24]

To avoid this we introduced LinkedList.


-----------------------------------------------------------------
LinkedList :
------------
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>,
Cloneable, Serializable

It is a predefined class available in java.util package under List interface.

It is ordered by index position like ArrayList except the elements (nodes) are doubly linked to one another.
This linkage provide us new method for adding and removing the elements from the middle of LinkedList.

*The important thing is, LikedList may iterate more slowely than ArrayList but LinkedList is a good choice
when we want to insert or delete the elements frequently in the list.

From jdk 1.6 onwards LinkedList class has been enhanced to support basic queue operation by
implementing Deque<E> interface.

LinkedList methods are not synchronized.

ArrayList is using Array data structure but LinkedList class is using LinkedList data structure.

Constructor:
-------------
It has 2 constructors

1) LinkedList list1 = new LinkedList();


It will create a LinkedList object with 0 capacity.

2) LinkedList list2 = new LinkedList(Collection c);


Interconversion between the collection

Methods of LinkedList class:


-------------------------------
1) void addFirst(Object o)
2) void addLast(Object o)

3) Object getFirst()
4) Object getLast()

5) Object removeFirst()
6) Object removeLast()

Note :- It stores the elements in non-contiguous memory location.

The time complexcity for insertion and deletion is O(1)

The time complexcity for seraching O(n)


-----------------------------------------------------------------
import java.util.*;
public class LinkedListDemo
{
public static void main(String args[])
{
List list=new LinkedList();
list.add("Ravi");
list.add("Vijay");
list.add("Ravi");
list.add(null);
list.add(42);

System.out.println(list.get(1));

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

list.forEach(x -> System.out.println(x));


}
}
----------------------------------------------------------------
import java.util.*;
public class LinkedListDemo1
{
public static void main(String args[])
{
LinkedList<String> list= new LinkedList<>(); //generic
list.add("Item 2");//2
list.add("Item 3");//3
list.add("Item 4");//4
list.add("Item 5");//5
list.add("Item 6");//6
list.add("Item 7");//7

list.add("Item 9"); //10

list.add(0,"Item 0");//0
list.add(1,"Item 1"); //1

list.add(8,"Item 8");//8
list.add(9,"Item 10");//9
System.out.println(list);

list.remove("Item 5");
System.out.println(list);

list.removeLast();
System.out.println(list);

list.removeFirst();
System.out.println(list);

list.set(0,"Ajay"); //set() will replace the existing value


list.set(1,"Vijay");
list.set(2,"Anand");
list.set(3,"Aman");
list.set(4,"Suresh");
list.set(5,"Ganesh");
list.set(6,"Ramesh");
list.forEach(x -> System.out.println(x));

}
}
-----------------------------------------------------------------
//Methods of LinkedList class
import java.util.LinkedList;
public class LinkedListDemo2
{
public static void main(String[] argv)
{
LinkedList<String> list = new LinkedList<>();
list.addFirst("Ravi");
list.add("Rahul");
list.addLast("Anand");
System.out.println(list.getFirst());
System.out.println(list.getLast());
list.removeFirst();
list.removeLast();
System.out.println(list);
}
}
-----------------------------------------------------------------
//ListIterator methods [add(), set() and remove()]
import java.util.*;
public class LinkedListDemo3
{
public static void main(String[] args)
{
LinkedList<String> city = new LinkedList<>();
city.add("Kolkata");
city.add("Bangalore");
city.add("Hyderabad");
city.add("Pune");
System.out.println(city);

ListIterator<String> lt = city.listIterator();

while(lt.hasNext())
{
String x = lt.next();

if(x.equals("Kolkata"))
{
lt.remove();
}
else if(x.equals("Hyderabad"))
{
lt.add("Ameerpet");
}
else if(x.equals("Pune"))
{
lt.set("Mumbai");
}
}
city.forEach(System.out::println); //Method Reference
}
}
---------------------------------------------------------------
//Insertion, deletion, displaying and exit

import java.util.LinkedList;
import java.util.Scanner;

public class LinkedListDemo4


{
public static void main(String[] args)
{
LinkedList<Integer> linkedList = new LinkedList<>();
Scanner scanner = new Scanner(System.in);

while (true)
{
System.out.println("Linked List: " + linkedList);//[]
System.out.println("1. Insert Element");
System.out.println("2. Delete Element");
System.out.println("3. Display Element");
System.out.println("4. Exit");
System.out.print("Enter your choice: ");

int choice = scanner.nextInt();


switch (choice)
{
case 1:
System.out.print("Enter the element to insert: ");
int elementToAdd = scanner.nextInt();
linkedList.add(elementToAdd);
break;
case 2:
if (linkedList.isEmpty())
{
System.out.println("Linked list is empty. Nothing to delete.");
}
else
{
System.out.print("Enter the element to delete: ");
int elementToDelete = scanner.nextInt();
boolean removed = linkedList.remove(Integer.valueOf(elementToDelete));

if (removed)
{
System.out.println("Element " + elementToDelete + " deleted from the linked list.");
}
else
{
System.out.println("Element not found in the linked list.");
}
}
break;
case 3:
System.out.println("Elements in the linked list.");
linkedList.forEach(System.out::println);
break;
case 4:
System.out.println("Exiting the program.");
scanner.close();
System.exit(0);
default:
System.out.println("Invalid choice. Please try again.");
}
}
}
}
-----------------------------------------------------------------
package com.ravi.linked_list;

import java.util.Iterator;
import java.util.LinkedList;

class Dog
{
private String dogName;

public Dog(String dogName)


{
super();
this.dogName = dogName;
}

@Override
public String toString() {
return "Dog [dogName=" + dogName + "]";
}

public String getDogName() {


return dogName;
}
}

public class LinkedListDemo


{
public static void main(String[] args)
{
LinkedList<Dog> listOfDog = new LinkedList<>();
Dog d1 = new Dog("Tiger");
listOfDog.add(d1);
listOfDog.add(new Dog("Tommy"));
listOfDog.add(new Dog("Rocky"));
Iterator<Dog> itr = listOfDog.iterator();
itr.forEachRemaining(d -> System.out.println(d.getDogName()));

System.out.println("1st position Dog Name is : "+listOfDog.get(1).getDogName());


}

}
----------------------------------------------------------------
import java.util.Deque;
import java.util.LinkedList;

public class LinkedListDemo6


{
public static void main(String[] args)
{
// Create a LinkedList and treat it as a Deque
Deque<String> deque = new LinkedList<>();

// Adding elements to the front of the deque


deque.addFirst("Ravi");
deque.addFirst("Raj"); //Raj Ravi Pallavi Sweta

// Adding elements to the back of the deque


deque.addLast("Pallavi");
deque.addLast("Sweta");

System.out.println("Deque: " + deque);

String first = deque.removeFirst();


String last = deque.removeLast();

System.out.println("Removed first element: " + first);


System.out.println("Removed last element: " + last);
System.out.println("Updated Deque: " + deque);
}
}
-----------------------------------------------------------------
28-02-2024
----------
Vector :
--------
Vector :
--------
public class Vector<E> extends AbstractList<E> implements List<E>, Serializable, Clonable,
RandomAccess

Vector is a predefined class available in java.util package under List interface.

Vector is always from java means it is available from jdk 1.0 version.

Vector and Hashtable, these two classes are available from jdk 1.0, remaining Collection classes were
added from 1.2 version. That is the reason Vector and Hashtable are called legacy(old) classes.
The main difference between Vector and ArrayList is, ArrayList methods are not synchronized so multiple
threads can access the method of ArrayList where as on the other hand most the methods are
synchronized in Vector so performance wise Vector is slow.

*We should go with ArrayList when Threadsafety is not required on the other hand we should go with
Vector when we need ThreadSafety for reterival operation.

It also stores the elements on index basis.It is dynamically growable with initial capacity 10. The next
capacity will be 20 i.e double of the first capacity.

new capacity = current capacity * 2;

Just like ArrayList it also implements List, Serializable, Clonable, RandomAccess interfaces.

Constructors in Vector :
-------------------------
We have 4 types of Constructor in Vector

1) Vector v1 = new Vector();


It will create the vector object with default capacity is 10

2) Vector v2 = new Vector(int initialCapacity);


Will create the vector object with user specified capacity.

3) Vector v3 = new Vector(int initialCapacity, int incrementalCapacity);


Eg :- Vector v = new Vector(1000,5);

Initially It will create the Vector Object with initial capacity 1000 and then when the capacity will be full
then increment by 5 so the next capacity would be 1005, 1010 and so on.

4) Vector v4 = new Vector(Collection c);


Interconversion between the Collection.
-----------------------------------------------------------------
//Vector Program on capacity

package com.ravi.vector;

import java.util.*;

public class VectorDemo1 {


public static void main(String[] args) {
Vector<Integer> v = new Vector<>(100, 20); // initial capacity is 100
System.out.println("Initial capacity is :" + v.capacity());

for (int i = 0; i < 100; i++) {


v.add(i);
}

System.out.println("After adding 100 elements capacity is :" + v.capacity()); // 100


v.add(101);
System.out.println("After adding 101th elements capacity is :" + v.capacity()); // 110

for (Integer i : v) {
System.out.print(i + "\t");
if (i % 5 == 0)
System.out.println();
}

}
}

Note :- By default the next capacity would be double so, by passing incrementalCapacity we can control
the next capacity of Vector.
---------------------------------------------------------------
Collection interface has provided a predefined method stream() through which we can process the
collection object

public Stream stream()

Stream is a predefined interface available in java.util.stream


sub pacakge.

filter(Predicate<T> p) is a predefined method of Stream interafce which will test the given expression
based on boolean condition

package com.ravi.vector;

import java.util.Vector;

public class VectorDemo2


{
public static void main(String[] args)
{
Vector<Integer> v = new Vector<>();
v.add(1); v.add(2); v.add(3);
v.add(4); v.add(5); v.add(6);
v.add(7); v.add(8); v.add(9);

//Without Stream
Vector<Integer> even = new Vector<>();

for(Integer i : v)
{
if(i%2 ==0)
{
even.add(i);
}
}
System.out.println(even);

//With Stream

v.stream().filter(num -> num%2==0).forEach(System.out::println);

}
}
----------------------------------------------------------------
//Program to filter product data based on Predicate

package com.ravi.vector;

import java.util.Vector;

record Product(int pid, String pname, double price)


{

public class VectorStream


{
public static void main(String[] args)
{
Vector<Product> listOfProduct = new Vector<>();
listOfProduct.add(new Product(1, "Camera", 12000));
listOfProduct.add(new Product(2, "Laptop", 82000));
listOfProduct.add(new Product(3, "Mobile", 44000));
listOfProduct.add(new Product(4, "LED", 56000));

listOfProduct.stream().filter(p -> p.price()<30000).forEach(prod -> System.out.println(prod.pname()));

}
----------------------------------------------------------------
package com.ravi.vector;
//Array To Collection
import java.util.*;
public class VectorDemo3
{
public static void main(String args[])
{
Vector<Integer> v = new Vector<>();

int x[]={22,20,10,40,15,58};

//Adding array values to Vector


for(int i=0; i<x.length; i++)
{
v.add(x[i]);
}
Collections.sort(v);
System.out.println("Maximum element is :"+Collections.max(v));
System.out.println("Minimum element is :"+Collections.min(v));
System.out.println("Vector Elements :");
v.forEach(y -> System.out.println(y));
}
}
----------------------------------------------------------------
//Program to describe that ArrayList is better than Vector in performance

package com.ravi.vector;

import java.util.ArrayList;
import java.util.Vector;

public class VectorDemo4


{
public static void main(String[] args)
{
long startTime = System.currentTimeMillis();

ArrayList<Integer> al = new ArrayList<>();

for(int i=0 ; i<=1000000; i++)


{
al.add(i);
}

long endTime = System.currentTimeMillis();


System.out.println("Total time taken by ArrayList :"+(endTime-startTime)+ "ms");

startTime = System.currentTimeMillis();

Vector<Integer> v = new Vector<>();

for(int i=0 ; i<=1000000; i++)


{
v.add(i);
}

endTime = System.currentTimeMillis();
System.out.println("Total time taken by Vector :"+(endTime-startTime)+ "ms");

}
}
---------------------------------------------------------------
29-02-2024
-----------
Stack :
------
public class Stack<E> extends Vector<E>

It is a predefined class available in java.util package. It is the sub class of Vector class introduced from
JDK 1.0 so, It is also a legacy class.

It is a linear data structure that is used to store the Objects in LIFO (Last In first out) order.

Inserting an element into a Stack is known as push operation where as extracting an element from the
top of the stack is known as pop operation.

It throws an exception called EmptyStackException, if Stack is empty and we want to fetch the element.

It has only one constructor as shown below


Stack s = new Stack();

------------------------------------------------------------------------------------
Methods :
----------
push(Object o) :- To insert an element.

pop() :- To remove and return the element from the top of the Stack.

peek() :- Will fetch the element from top of the Stack without removing.

empty() :- Verifies whether the stack is empty or not (return type is boolean)

search(Object o) :- It will search a particular element in the Stack and it returns OffSet position (int value).
If the element is not present in the Stack it will return -1
---------------------------------------------------------------
//Program to insert and fetch the elements from stack
package com.ravi.stack;
import java.util.*;
public class Stack1
{
public static void main(String args[])
{
Stack<Integer> s = new Stack<>();
try
{ s.push(12);
s.push(15);
s.push(22);
s.push(33);
s.push(49);
System.out.println("After insertion elements are :"+s);

System.out.println("Fetching the elements using pop method");


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

System.out.println("After deletion elements are :"+s); //[]


System.out.println("Is the Stack empty ? :"+s.empty());
}
catch(EmptyStackException e)
{
e.printStackTrace();
}
}
}
---------------------------------------------------------------
//add(Object obj) is the method of Collection
package com.ravi.stack;
import java.util.*;
public class Stack2
{
public static void main(String args[])
{
Stack<Integer> st1 = new Stack<>();
st1.add(10);
st1.add(20);
st1.forEach(x -> System.out.println(x));

Stack<String> st2 = new Stack<>();


st2.add("Java");
st2.add("is");
st2.add("programming");
st2.add("language");
st2.forEach(x -> System.out.println(x));

Stack<Character> st3 = new Stack<>();


st3.add(’A’);
st3.add(’B’);
st3.forEach(x -> System.out.println(x));

Stack<Double> st4 = new Stack<>();


st4.add(10.5);
st4.add(20.5);
st4.forEach(x -> System.out.println(x));
}
}
--------------------------------------------------------------
package com.ravi.stack;
import java.util.Stack;

public class Stack3


{
public static void main(String[] args)
{
Stack<String> stk= new Stack<>();
stk.push("Apple");
stk.push("Grapes");
stk.push("Mango");
stk.push("Orange");
System.out.println("Stack: " + stk);

String fruit = stk.peek();


System.out.println("Element at top: " + fruit);
System.out.println("Stack elements are : " + stk);
}
}
--------------------------------------------------------------
//Searching an element in the Stack
package com.ravi.stack;
import java.util.Stack;
public class Stack4
{
public static void main(String[] args)
{
Stack<String> stk= new Stack<>();
stk.push("Apple");
stk.push("Grapes");
stk.push("Mango");
System.out.println("Offset Position is : " + stk.search("Mango")); //1
System.out.println("Offser Position is : " + stk.search("Banana")); //-1
System.out.println("Is stack empty ? "+stk.empty()); //false

System.out.println("Index Position is : " + stk.indexOf("Mango")); //2


}
}
---------------------------------------------------------------
Set interface :
----------------
It is the sub interface of Collection.

Set interface will never accept duplicate elements, Here our best friend is equals(Object obj) method of
Object class. If two objects are identical then it will accept only one object.

Set interface does not follow index and we cannot read the data in backward direction (ListIterator will not
work)

We cannot perform manual sorting operation using Set interface but the same thing will be available using
Comparator interface.

Set interface uses almost all the method of Collection interface.


---------------------------------------------------------------
Set interface Hierarchy :
-------------------------
Diagram [29-FEB-24]
---------------------------------------------------------------
HashSet (UNSORTED, UNORDERED , NO DUPLICATES)
---------------------------------------------
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Clonabale, Serializable

It is a predefined class available in java.util package under Set interface and introduced from JDK 1.2V.

It is an unsorted and unordered set.

It accepts hetrogeneous kind of data.

*It uses the hashcode of the object being inserted into the Collection. Using this hashcode it finds the
bucket location.

It doesn’t contain any duplicate elements as well as It does not maintain any order while iterating the
elements from the collection.

It can accept null value.

HashSet is used for fast searching operation.

It contains 4 types of constructors


1) HashSet hs1 = new HashSet();
It will create the HashSet Object with default capacity is 16. The default load fator or Fill Ratio is 0.75
(75% of HashSet is filled up then new HashSet Object will be created having double capacity)

2) HashSet hs2 = new HashSet(int initialCapacity);


will create the HashSet object with user specified capacity

3) HashSet hs3 = new HashSet(int initialCapacity, float loadFactor);


we can specify our own initialCapacity and loadFactor(by default load factor is 0.75%)

4) HashSet hs = new HashSet(Collection c);


Interconversion of Collection
-------------------------------------------------------------------
//Unsorted, Unordered and no duplicates
import java.util.*;
public class HashSetDemo
{
public static void main(String args[])
{
HashSet<Integer> hs = new HashSet<>();
hs.add(67);
hs.add(89);
hs.add(33);
hs.add(45);
hs.add(12);
hs.add(35);

hs.forEach(str-> System.out.println(str));
}
}

[Diagram is available]
---------------------------------------------------------------
package com.ravi.class_description;

import java.util.HashSet;

public class HashCodeTest {

public static void main(String[] args)


{
HashSet<Object> hs = new HashSet<>();
hs.add(new String("A")); //65 % 16 = 1
hs.add("A"); //65 % 16 = 1
hs.add(65); //65 % 16 = 1

System.out.println(hs);
}

}
--------------------------------------------------------------
import java.util.*;
public class HashSetDemo1
{
public static void main(String[] argv)
{
HashSet<String> hs=new HashSet<>();
hs.add("Ravi");
hs.add("Vijay");
hs.add("Ravi");
hs.add("Ajay");
hs.add("Palavi");
hs.add("Sweta");
hs.add(null);
hs.add(null);
hs.forEach(str -> System.out.println(str));

}
}
----------------------------------------------------------------
package com.ravi.class_description;

import java.util.HashSet;

record Student(int id, String name)


{

public class HashSetDemo


{
public static void main(String[] args)
{
Student s1 = new Student(1,"A");
Student s2 = new Student(2,"B");
Student s3 = new Student(3,"C");
Student s4 = s3;

HashSet<Student> set = new HashSet<>();


set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);

set.forEach(std -> System.out.println(std));

s3 and s4 hashcode are same so It will accept 3 objects.


---------------------------------------------------------------
package com.ravi.class_description;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetBooleanTest {


public static void main(String[] args)
{
boolean ba[] = new boolean[5];

Set<Object> set = new HashSet<>();


ba[0] = set.add(new String("A"));
ba[1] = set.add("A");
ba[2] = set.add("B");
ba[3] = set.add(68);
ba[4] = set.add(new StringBuffer("Hello"));

System.out.println(Arrays.toString(ba));

Iterator<Object> itr = set.iterator();


itr.forEachRemaining(System.out::println);

}
----------------------------------------------------------------
//add, delete, display and exit
import java.util.HashSet;
import java.util.Scanner;

public class HashSetDemo3


{
public static void main(String[] args)
{
HashSet<String> hashSet = new HashSet<>();
Scanner scanner = new Scanner(System.in);

while (true)
{
System.out.println("Options:");
System.out.println("1. Add element");
System.out.println("2. Delete element");
System.out.println("3. Display HashSet");
System.out.println("4. Exit");

System.out.print("Enter your choice (1/2/3/4): ");


int choice = scanner.nextInt();

switch (choice)
{
case 1:
System.out.print("Enter the element to add: ");
String elementToAdd = scanner.next();
if (hashSet.add(elementToAdd))
{
System.out.println("Element added successfully.");
}
else
{
System.out.println("Element already exists in the HashSet.");
}
break;
case 2:
System.out.print("Enter the element to delete: ");
String elementToDelete = scanner.next();
if (hashSet.remove(elementToDelete))
{
System.out.println("Element deleted successfully.");
}
else
{
System.out.println("Element not found in the HashSet.");
}
break;
case 3:
System.out.println("Elements in the HashSet:");
for (String element : hashSet) {
System.out.println(element);
}
break;
case 4:
System.out.println("Exiting the program.");
scanner.close();
System.exit(0);
default:
System.out.println("Invalid choice. Please try again.");
}

System.out.println();
}
}
}
---------------------------------------------------------------
02-03-2024
----------
LinkedHashSet :
---------------
LinkedHashSet :
------------------
public class LinkedHashSet extends HashSet implements Set, Clonable, Serializable

It is a predefined class in java.util package under Set interface and introduced from java 1.4v.

It is the sub class of HashSet class.

It is an orderd version of HashSet that maintains a doubly linked list across all the elements.

It internally uses Hashtable and LinkedList data structures.

We should use LinkedHashSet class when we want to maintain an order.

When we iterate the elements through HashSet the order will be unpredictable, while when we iterate the
elments through LinkedHashSet then the order will be same as they were inserted in the collection.
It accepts hetrogeneous and null value is allowed.

It has same constructor as HashSet class.


-----------------------------------------------------------------
import java.util.*;
public class LinkedHashSetDemo
{
public static void main(String args[])
{
LinkedHashSet<String> lhs=new LinkedHashSet<>();
lhs.add("Ravi");
lhs.add("Vijay");
lhs.add("Ravi");
lhs.add("Ajay");
lhs.add("Pawan");
lhs.add("Shiva");
lhs.add(null);
lhs.add("Ganesh");
lhs.forEach(str -> System.out.println(str));
}
}
----------------------------------------------------------------
public boolean contains(Object obj) :- It will search an object
in the given Set, If object is available it will true otherwise false.

import java.util.LinkedHashSet;

public class LinkedHashSetDemo1


{
public static void main(String[] args)
{
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();

linkedHashSet.add(10);
linkedHashSet.add(5);
linkedHashSet.add(15);
linkedHashSet.add(20);
linkedHashSet.add(5);

System.out.println("LinkedHashSet elements: " + linkedHashSet);

System.out.println("LinkedHashSet size: " + linkedHashSet.size());

int elementToCheck = 15;


if (linkedHashSet.contains(elementToCheck))
{
System.out.println(elementToCheck + " is present in the LinkedHashSet.");
}
else
{
System.out.println(elementToCheck + " is not present in the LinkedHashSet.");
}

int elementToRemove = 10;


linkedHashSet.remove(elementToRemove);
System.out.println("After removing " + elementToRemove + ", LinkedHashSet elements: " +
linkedHashSet);

linkedHashSet.clear();
System.out.println("After clearing, LinkedHashSet elements: " + linkedHashSet); //[]
}
}
-----------------------------------------------------------------
SortedSet :
-----------
It is the sub interface of Set interface which is introduced from
JDK 1.2V.

As we know we can’t perform sorting opeartion on HashSet and LinkedHashSet class manually so, if we
don’t want duplicate elements and want to store the element in sorted order then we should use
SortedSet interface.

SortedSet interface provides default natural sorting order, default natural sorting order means, if numbers
then ascending order, if String then Alphabetical order OR Dictionary order.

In order to sort the elements in natural sorting order as well as user-defined sorting we have two
interfaces java.lang.Comparable and java.util.Comparator.
------------------------------------------------------------------
*** What is the difference between Comparable and Comparator

Program on Comparable ineterface :


-----------------------------------
2 files :
---------
Employee.java(R)
-----------------
package com.ravi.comparable_demo;

public record Employee(int eid, String ename, int age) implements Comparable<Employee>
{

//Sorting based on the Employee Name


@Override
public int compareTo(Employee e2)
{
return this.eid - e2.eid;
}
}

EmployeeComparable.java(C)
--------------------------
package com.ravi.comparable_demo;

import java.util.ArrayList;
import java.util.Collections;

public class EmployeeComparable {

public static void main(String[] args)


{
ArrayList<Employee> al = new ArrayList<>();
al.add(new Employee(333, "Aryan", 22));
al.add(new Employee(444, "Uday", 23));
al.add(new Employee(222, "Bishal", 19));
al.add(new Employee(111, "Zuber", 18));

Collections.sort(al);

al.forEach(System.out::println);

Limitation Of Comparable interface :


------------------------------------
With Comparable we have 2 limitations :
---------------------------------------
1) In comparable interrface we need to modify the source code(BLC class).

2) We can write only one sorting logic.

To avoid the above said problem Comparator interface came into the picture :

2 files :
---------
Product.java(R)
---------------
package com.product.comparator;

public record Product(int pid, String pname)


{

ProductComparator.java(C)
------------------------
package com.product.comparator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class ProductComparator


{
public static void main(String[] args)
{
ArrayList<Product> al = new ArrayList<>();
al.add(new Product(4, "Keyboard"));
al.add(new Product(3, "Camera"));
al.add(new Product(1, "Laptop"));
al.add(new Product(2, "Mobile"));

//Anonymous inner class


Comparator<Product> cmpId = new Comparator<Product>()
{
@Override
public int compare(Product p1, Product p2)
{
return p1.pid() - p2.pid();
}
};
Collections.sort(al, cmpId);
System.out.println("Sorting based on the Id :");
al.forEach(System.out::println);

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

//By Using Lambda


Comparator<Product> cmpName = (p1,p2)-> p1.pname().compareTo(p2.pname());
Collections.sort(al, cmpName);
System.out.println("Sorting based on the Name :");
al.forEach(System.out::println);

}
-----------------------------------------------------------------
Program to print the Integer object in descending order by using Comparator

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Main {

public static void main(String[] args)


{
ArrayList<Integer> al = new ArrayList<>();
al.add(67);
al.add(43);
al.add(100);
al.add(21);
al.add(9);
al.add(102);

Comparator<Integer> descCmp = (i1, i2)-> -(i1 - i2);


Collections.sort(al, descCmp);
al.forEach(System.out::println);

}
}
----------------------------------------------------------------
04-03-2024
-----------
How many classes are not accepting null?

The following classes are not accepting null in the entire Collection Framework.
1) TreeSet 2) TreeMap 3) Hashtable 4) PriorityQueue
5) ConcurrentHashMap
---------------------------------------------------------------
TreeSet :
---------
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Clonable, Serializable

It is a predefined class available in java.util package under Set interface.

TreeSet, TreeMap and PriorityQueue are the three sorted collection in the entire Collection Framework
so these classes never accepting non comparable objects.

It will sort the elements in natural sorting order i.e ascending order in case of number , and alphabetical
order or Dictionary order in the case of String. In order to sort the elements according to user choice, It
uses Comparator interface.

It does not accept duplicate and null value(java.lang.NullPointerException).

It does not accept non comparable type of data if we try to insert it will throw a runtime exception i.e
java.lang.ClassCastException

TreeSet implements NavigableSet.

NavigableSet extends SortedSet.

It contains 4 types of constructors :


----------------------------------------
1) TreeSet t1 = new TreeSet();
create an empty TreeSet object, elements will be inserted in a natural sorting order.

2) TreeSet t2 = new TreeSet(Comparator c);


Customized sorting order

3) TreeSet t3 = new TreeSet(Collection c);

4) TreeSet t4 = new TreeSet(SortedSet s);


----------------------------------------------------------------
//program that describes TreeSet provides default natural sorting order
import java.util.*;
public class TreeSetDemo
{
public static void main(String[] args)
{
SortedSet<Integer> t1 = new TreeSet<>();
t1.add(4);
t1.add(7);
t1.add(2);
t1.add(1);
t1.add(9);

System.out.println(t1);

NavigableSet<String> t2 = new TreeSet<>();


t2.add("Orange");
t2.add("Mango");
t2.add("Banana");
t2.add("Grapes");
t2.add("Apple");
System.out.println(t2);
}
}

Note : Integer and String both classes are implementing java.lang.Comparable so internally compareTo()
is invoked the
compare the Integer and String Object.
----------------------------------------------------------------
import java.util.*;
public class TreeSetDemo1
{
public static void main(String[] args)
{
TreeSet<String> t1 = new TreeSet<>();
t1.add("Orange");
t1.add("Mango");
t1.add("Pear");
t1.add("Banana");
t1.add("Apple");
System.out.println("In Ascending order");
t1.forEach(i -> System.out.println(i));

TreeSet<String> t2 = new TreeSet<>();


t2.add("Orange");
t2.add("Mango");
t2.add("Pear");
t2.add("Banana");
t2.add("Apple");

System.out.println("In Descending order");


Iterator<String> itr2 = t2.descendingIterator(); //for descending order

itr2.forEachRemaining(x -> System.out.println(x));


}
}

Note :- descendingIterator() is a predefined method of TreeSet class which will traverse in the descending
order and return type of this method is Iterator interface.
---------------------------------------------------------------
import java.util.*;
public class TreeSetDemo2
{
public static void main(String[] args)
{
Set<String> t = new TreeSet<>();
t.add("6");
t.add("5");
t.add("4");
t.add("2");
t.add("9");
Iterator<String> iterator = t.iterator();
iterator.forEachRemaining(x -> System.out.println(x));

//From 1.8 to replace hasNext() and next() method


}
}
----------------------------------------------------------------
import java.util.*;

public class TreeSetDemo3


{
public static void main(String[] args)
{
Set<Character> t = new TreeSet<>();
t.add(’A’);
t.add(’C’);
t.add(’B’);
t.add(’E’);
t.add(’D’);
Iterator<Character> iterator = t.iterator();
iterator.forEachRemaining(x -> System.out.println(x));
}
}
--------------------------------------------------------------
WAP to show that TreeSet is having Comparator interface as a parameter which can sort the element in
user-defined sorting order.

import java.util.TreeSet;

record Student(int id, String name, int age)


{

public class TreeSetComparator


{
public static void main(String[] args)
{
TreeSet<Student> ts = new TreeSet<>();
ts.add(new Student(101, "Zaheer", 24));
ts.add(new Student(201, "Aryan", 27));
ts.add(new Student(301, "Pooja", 26));

ts.forEach(std -> System.out.println(std));

If we are inserting any object in the TreeSet then the TreeSet element must provide sorting logic by
Comparable or By Comparator at Object Construction time (By using Constructor)
otherwise ClassCastException will be generated as shown in the above program
---------------------------------------------------------------
import java.util.TreeSet;
record Student(int id, String name, int age) implements Comparable<Student>
{

@Override
public int compareTo(Student s2)
{
return this.id - s2.id;
}

public class TreeSetComparator


{
public static void main(String[] args)
{
TreeSet<Student> ts = new TreeSet<>();
ts.add(new Student(401, "Raj", 22));
ts.add(new Student(101, "Zaheer", 24));
ts.add(new Student(201, "Aryan", 27));
ts.add(new Student(301, "Pooja", 26));

ts.forEach(std -> System.out.println(std));

}
----------------------------------------------------------------

import java.util.TreeSet;

record Student(int id, String name, int age)


{

public class TreeSetComparator


{
public static void main(String[] args)
{
TreeSet<Student> ts = new TreeSet<>((s1,s2)-> s1.id() - s2.id());
ts.add(new Student(401, "Raj", 22));
ts.add(new Student(101, "Zaheer", 24));
ts.add(new Student(201, "Aryan", 27));
ts.add(new Student(301, "Pooja", 26));

System.out.println("Sorted Based on the ID in ascending Order");


ts.forEach(std -> System.out.println(std));

TreeSet<Student> ts1 = new TreeSet<>((s1,s2)-> s2.id() - s1.id());


ts1.add(new Student(401, "Raj", 22));
ts1.add(new Student(101, "Zaheer", 24));
ts1.add(new Student(201, "Aryan", 27));
ts1.add(new Student(301, "Pooja", 26));
System.out.println("Sorted Based on the ID in descending Order");
ts1.forEach(std -> System.out.println(std));

TreeSet<Student> ts2 = new TreeSet<>((s1,s2)-> s1.name().compareTo(s2.name()));


ts2.add(new Student(401, "Raj", 22));
ts2.add(new Student(101, "Zaheer", 24));
ts2.add(new Student(201, "Aryan", 27));
ts2.add(new Student(301, "Pooja", 26));

System.out.println("Sorted Based on the Name in descending Order");


ts2.forEach(std -> System.out.println(std));

TreeSet<Student> ts3 = new TreeSet<>((s1,s2)-> s2.name().compareTo(s1.name()));


ts3.add(new Student(401, "Raj", 22));
ts3.add(new Student(101, "Zaheer", 24));
ts3.add(new Student(201, "Aryan", 27));
ts3.add(new Student(301, "Pooja", 26));

System.out.println("Sorted Based on the Name in descending Order");


ts3.forEach(std -> System.out.println(std));

}
---------------------------------------------------------------
Methods of SortedSet interface :
--------------------------------------
public E first() :- Will fetch first element

public E last() :- Will fetch last element

public SortedSet headSet(int range) :- Will fetch the values which are less than specified range

public SortedSet tailSet(int range) :- Will fetch the values which are equal or greater than the specified
range.

public SortedSet subSet(int startRange, int endRange) :- Will fetch the range of values where startRange
is inclusive and endRange is exclusive.

Note :- headSet(), tailSet() and subSet(), return type is SortedSet


---------------------------------------------------------------
import java.util.*;
public class SortedSetMethodDemo
{
public static void main(String[] args)
{
TreeSet<Integer> times = new TreeSet<>();
times.add(1205);
times.add(1505);
times.add(1545);
times.add(1600);
times.add(1830);
times.add(2010);
times.add(2100);

SortedSet<Integer> sub = new TreeSet<>();

sub = times.subSet(1545,2100);
System.out.println("Using subSet() :-"+sub);//[1545, 1600,1830,2010]
System.out.println(sub.first());
System.out.println(sub.last());

sub = times.headSet(1545);
System.out.println("Using headSet() :-"+sub); //[1205, 1505]

sub = times.tailSet(1545);
System.out.println("Using tailSet() :-"+sub); //[1545 to 2100]
}
}
----------------------------------------------------------------
NavigableSet(I) :
-----------------
With the help of SortedSet interface method we can find out the range of values but we can’t navigate
among those elements.

Now to frequently navigate among those range of elements, Java software people introduced new
interface called NavigableSet from 1.6V

NavigableSet extends SortedSet


----------------------------------------------------------------
import java.util.*;

public class NavigableSetDemo


{
public static void main(String[] args)
{
NavigableSet<Integer> ns = new TreeSet<>();
ns.add(1);
ns.add(2);
ns.add(3);
ns.add(4);
ns.add(5);
ns.add(6);

System.out.println("lower(3): " + ns.lower(3));//Just below than the specified element or null

System.out.println("floor(3): " + ns.floor(7)); //Equal less or null

System.out.println("higher(3): " + ns.higher(3));//Just greater than specified element or null

System.out.println("ceiling(3): " + ns.ceiling(3));//Equal or greater or null

}
}
----------------------------------------------------------------
05-03-2024
----------
Map interface :
---------------
As we know Collection interface is used to hold single Or individual object but Map interface will hold
group of objects in the form key and value pair. {key = value}

Map interface is not the part the Collection.

Before Map interface We had Dictionary(abstract class) class and it is extended by Hashtable class in
JDK 1.0V

Map interface works with key and value pair introduced from 1.2V.

Here key and value both are objects.

Here key must be unique and value may be duplicate.

Each key and value pair is creating one Entry.(Entry is nothing but the combination of key and value pair)

interface Map
{
interface Entry
{
//key and value
}
}

How to represent this entry interface (Map.Entry in .java) [Map$Entry in .class]

In Map interface whenever we have a duplicate key then the old key value will be replaced by new
key(duplicate key) value.
------------------------------------------------------------------
Map interface Hierarchy :
-------------------------
Map interface Hierarchy [05-MAR-24]
-----------------------------------------------------------------
Methods of Map interface :
--------------------------
1) Object put(Object key, Object value) :- To insert one entry in the Map collection. It will return the old
object key’s value if the key is already available(Duplicate key), If key is not available then it will return
null.

2) putIfAbsent(Object key, Object value) :- It will insert an entry if and only if key is not present , if the key
is already available then it will not insert the Entry to the Map Collection

3) Object get(Object key) :- It will return corresponding value of key, if the key is not present then it will
return null.

4) Object getOrDefault(Object key, Object defaultValue) :- To avoid null value this method has been
introduced, here we can pass some defaultValue to avoid the null value.

5) boolean containsKey(Object key) :- To Search a particular key


6) boolean containsValue(Object value) :- To Search a particular value

7) int size() :- To count the number of Entries.

8) remove(Object key) :- One complete entry will be removed.

9) void clear() :- Used to clear the Map

10) boolean isEmpty() :- To verify Map is empty or not?

11) void putAll(Map m) :- Merging of two Map collection


------------------------------------------------------------------
Note :- Iterator interface will not work with Map interface because Map interface works with Group of
Object, If we want ti iterate the map data then we should use Collection view Method.

Collection views Methods :


------------------------------
public Set keySet() :- Will return only keys (Set of keys)

Collection values() :- Will return all values.

Set<Map.Entry> entrySet() :- It will return key and value pair in the form of Entry.

a) getKey() b) getValue() c) setValue()


-----------------------------------------------------------------
*** How HashMap Works internally ?
----------------------------------
a) While working with HashSet or HashMap every object must be compared because duplicate objects
are not allowed.

b) Whenever we add any new key to verify whether key is unique or duplicate, HashMap internally uses
hashCode(), == operator and equals method.

c) While adding the key object in the HashMap, first of all it will invoke the hashCode() method to retrieve
the corresponding key hashcode value.
Example :- hm.put(key,value);
then internally key.hashCode();

d) If the newly added key and existing key hashCode value both are same (Hash collision), then only ==
operator is used for comparing those keys by using reference or memory address, if both keys references
are same then existing key value will be replaced with new key value.

If the reference of both keys are different then equals(Object obj) method is invoked to compare
those keys by using state(data). [content comparison]

If the equals(Object obj) method returns true (content wise both keys are same), this new key is duplicate
then existing key value will be replaced.

If equals(Object obj) method returns false, this new key is unique, new entry (key-value) will be inserted.

Note :- equals(Object obj) method is invoked only when two keys are having same hashcode as well as
their references are different.

e) Actually by calling hashcode method we are not comparing the objects, we are just storing the objects
in a group so the currently adding key object will be compared with its HASHCODE GROUP objects, but
not with all the keys which are available in the Map.

f) The main purpose of storing objects into the corresponding group to decrease the number of
comparison so the efficiency of the program will increase.

g) To insert an entry in the HashMap, HashMap internally uses Hashtable data structure

h) Now, for storing same hashcode object into a single group, hash table data structure internally uses
one more data structure called Bucket.

i) The Hash table data structure internally uses Node class array object.

j) The bucket data structure internally uses LinkedList data structure, It is a single linked list again
implemented by Node class only.

*k) A bucket is group of entries of same hash code keys.

l) Performance wise LinkedList is not good to serach, so from java 8 onwards LinkedList is changed to
Binary tree to decrease the number of comparison within the same bucket hashcode if the number of
entries are greater than 8.

* equals() and hashCode() method contract :


-----------------------------------------
Both the methods are working together to find out the duplicate objects in the Map.

*If equals() method invoked on two objects and it returns true then hashcode of both the objects must be
same.
-----------------------------------------------------------------

package com.ravi.exception;

import java.util.HashMap;

public class HashMapDemo {

public static void main(String[] args)


{
HashMap<String, Integer> hm = new HashMap<>();
hm.put("A", 1);
hm.put("A", 2);
hm.put(new String("A"),3);

System.out.println(hm.size()); //1
System.out.println(hm); //{A = 3}

}
-----------------------------------------------------------------
package com.ravi.exception;

import java.util.HashMap;

public class ExceptionTermination {


public static void main(String[] args)
{
HashMap<Object, Object> hm = new HashMap<>();
hm.put("A", 1);
hm.put(65, 2);

System.out.println(hm.size());
System.out.println(hm);

}
------------------------------------------------------------------
import java.util.*;
class Employee
{
int eid;
String ename;

Employee(int eid, String ename)


{
this.eid = eid;
this.ename = ename;
}

@Override
public boolean equals(Object obj) //obj = e2
{
if(obj instanceof Employee)
{
Employee e2 = (Employee) obj; //downcasting

if(this.eid == e2.eid && this.ename.equals(e2.ename))


{
return true;
}
else
{
return false;
}
}
else
{
System.out.println("Comparison is not possible");
return false;
}
}

public String toString()


{
return " "+eid+" "+ename;
}
}
public class HashMapDemo8
{
public static void main(String[] args)
{
Employee e1 = new Employee(101,"Aryan");
Employee e2 = new Employee(102,"Pooja");
Employee e3 = new Employee(101,"Aryan");
Employee e4 = e2;

HashMap<Employee,String> hm = new HashMap<>();


hm.put(e1,"Ameerpet");
hm.put(e2,"S.R Nagar");
hm.put(e3,"Begumpet");
hm.put(e4,"Panjagutta");

hm.forEach((k,v)-> System.out.println(k+" : "+v));


}
}
------------------------------------------------------------------
Offline
--------
Map interface
Queue interface
Generics
Concurrent Collection (Collection + Multithreading)
Stream API
Sealed class
New Java Date and Time API
Optional class

Online
-------
Inner class in Java
enum
Array (Arrays class method)
String (SB and StringBuilder)
------------------------------------------------------------------
HashMap<K,V> :- [Unsorted, Unordered, No Duplicate keys]
------------
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Serializable, Clonable

It is a predefined class available in java.util package under Map interface available from JDK 1.2.

It gives us unsorted and Unordered map. when we need a map and we don’t care about the order while
iterating the elements through it then we should use HashMap.

It inserts the element based on the hashCode of the Object key using hashing technique [hasing
alogorithhm]

It does not accept duplicate keys but value may be duplicate.

It accepts only one null key(because duplicate keys are not allowed) but multiple null values are allowed.

HashMap is not synchronized.

Time complexcity of search, insert and delete will be O(1)


We should use HashMap to perform searching opeartion.

It contains 4 types of constructor

1) HashMap hm1 = new HashMap();


It will create the HashMap Object with default capacity is 16. The default load fator or Fill Ratio is 0.75
(75% of HashMap is filled up then new HashMap Object will be created having double capacity)

2) HashMap hm2 = new HashMap(int initialCapacity);


will create the HashMap object with specified capacity

3) HashMap hm3 = new HashMap(int initialCapacity, float loadFactor);


we can specify our own initialCapacity and loadFactor(by default load factor is 0.75%)

4)HashMap hm4 = new HashMap(Map m);


Interconversion of Map Collection
-----------------------------------------------------------------
//Program that shows HashMap is unordered
import java.util.*;
public class HashMapDemo
{
public static void main(String[] a)
{
Map<String,String> map = new HashMap<>();
map.put("Ravi", "12345");
map.put("Rahul", "12345");
map.put("Aswin", "5678");
map.put(null, "6390");
map.put("Ravi","1529");
map.put("Aamir","890");

System.out.println(map);

System.out.println(map.get(null));
System.out.println(map.get("Virat"));

map.forEach((k,v)-> System.out.println("Key is :"+k+" value is "+v));

}
}
-----------------------------------------------------------------
equals(Object obj) and hashCode() bot methods are overridden in the String class as well as all the
Warpper classes.

package com.product.comparator;

import java.util.HashMap;

public class HashMapDemo {

public static void main(String[] args)


{
HashMap<Object,Object> hm = new HashMap<>();
hm.put("A", 111);
hm.put(new String("A"), 222);

hm.put(new StringBuilder("B"),333);
hm.put(new StringBuilder("B"),444);

System.out.println(hm);

Note :- hashcode and equals methods are not overridden in StringBuilder class.
-----------------------------------------------------------------
//Program to search a particular key and value in the Map collection
import java.util.*;
public class HashMapDemo1
{
public static void main(String args[])
{
HashMap<Integer,String> hm = new HashMap<>();
hm.put(1, "JSE");
hm.put(2, "JEE");
hm.put(3, "JME");
hm.put(4,"JavaFX");
hm.put(5,null);
hm.put(6,null);

System.out.println("Initial map elements: " + hm);


System.out.println("key 2 is present or not :"+hm.containsKey(2));

System.out.println("JME is present or not :"+hm.containsValue("JME"));

System.out.println("Size of Map : " + hm.size());


hm.clear();
System.out.println("Map elements after clear: " + hm);
}
}
-----------------------------------------------------------------
//Collection view methods [keySet(), values(), entrySet()]
import java.util.*;
public class HashMapDemo2
{
public static void main(String args[])
{
Map<Integer,String> map = new HashMap<>();
map.put(1, "C");
map.put(2, "C++");
map.put(3, "Java");
map.put(4, ".net");

map.forEach((k,v)->System.out.println("Key :"+k+" Value :"+v) );

System.out.println("Return Old Object value :"+map.put(4,"Python"));


for(Map.Entry m : map.entrySet())
{
System.out.println(m.getKey()+" : "+m.getValue());
}
}
}
----------------------------------------------------------------
import java.util.*;
public class HashMapDemo3
{
public static void main(String args[])
{
HashMap<Integer,String> map = new HashMap<>(26,0.9f);
map.put(1, "Java");
map.put(2, "is");
map.put(3, "best");
map.remove(3); //will remove the complete Entry
String val=(String)map.get(3);
System.out.println("Value for key 3 is: " + val);
map.forEach((k,v)->System.out.println(k +" : "+v));
}
}
-----------------------------------------------------------------
//To merge two Map Collection (putAll)
import java.util.*;
public class HashMapDemo4
{
public static void main(String args[])
{
HashMap<Integer,String> newmap1 = new HashMap<>();

HashMap<Integer,String> newmap2 = new HashMap<>();

newmap1.put(1, "OCPJP");
newmap1.put(2, "is");
newmap1.put(3, "best");

System.out.println("Values in newmap1: "+ newmap1);

newmap2.put(4, "Exam");

newmap2.putAll(newmap1);

newmap2.forEach((k,v)->System.out.println(k+" : "+v));
}
}
----------------------------------------------------------------
import java.util.*;
public class HashMapDemo5
{
public static void main(String[] argv)
{
Map<String,String> map = new HashMap<>(9, 0.85f);
map.put("key", "value");
map.put("key2", "value2");
map.put("key3", "value3");
map.put("key7","value7");

Set keys = map.keySet();//keySet return type is Set


System.out.println(keys ); //[]

Collection val = map.values(); //values return type is collection


System.out.println(val);

map.forEach((k,v)-> System.out.println(k+" : "+v));

}
}
----------------------------------------------------------------
//getOrDefault() method
import java.util.*;
public class HashMapDemo6
{
public static void main(String[] args)
{
Map<String, String> map = new HashMap<>();
map.put("A", "1");
map.put("B", "2");
map.put("C", "3");
//if the key is not present, it will return default value .It is used to avoid null
String value = map.getOrDefault("C","Key is not available");
System.out.println(value);
System.out.println(map);
}
}
----------------------------------------------------------------
//interconversion of two HashMap
import java.util.*;
public class HashMapDemo7
{
public static void main(String args[])
{
HashMap<Integer, String> hm1 = new HashMap<>();

hm1.put(1, "Ravi");
hm1.put(2, "Rahul");
hm1.put(3, "Rajen");

HashMap<Integer, String> hm2 = new HashMap<>(hm1);

System.out.println("Mapping of HashMap hm1 are : " + hm1);

System.out.println("Mapping of HashMap hm2 are : " + hm2);


}
}
----------------------------------------------------------------
LinkedHashMap :
------------------
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

It is a predefined class available in java.util package under Map interface available from 1.4.

It is the sub class of HashMap class.

It maintains insertion order. It contains a doubly linked with the elements or nodes so It will iterate more
slowly in comparison to HashMap.

It uses Hashtable and LinkedList data structure.

If We want to fetch the elements in the same order as they were inserted then we should go with
LinkedHashMap.

It accepts one null key and multiple null values.

It is not synchronized.

It has also 4 constructors same as HashMap

1) LinkedHashMap hm1 = new LinkedHashMap();


will create a LinkedHashMap with default capacity 16 and load factor 0.75

2) LinkedHashMap hm1 = new LinkedHashMap(iny initialCapacity);

3) LinkedHashMap hm1 = new LinkedHashMap(iny initialCapacity, float loadFactor);

4) LinkedHashMap hm1 = new LinkedHashMap(Map m);


----------------------------------------------------------------
import java.util.*;
public class LinkedHashMapDemo
{
public static void main(String[] args)
{
LinkedHashMap<Integer,String> l = new LinkedHashMap<>();
l.put(1,"abc");
l.put(3,"xyz");
l.put(2,"pqr");
l.put(4,"def");
l.put(null,"ghi");
System.out.println(l);
}
}
----------------------------------------------------------------
import java.util.LinkedHashMap;
import java.util.Map;

public class LinkedHashMapDemo1


{
public static void main(String[] a)
{
Map<String,String> map = new LinkedHashMap<>();
map.put("Ravi", "1234");
map.put("Rahul", "1234");
map.put("Aswin", "1456");
map.put("Samir", "1239");

map.forEach((k,v)->System.out.println(k+" : "+v));
}
}
----------------------------------------------------------------
Hashtable<K,V>
--------------
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Clonable, Serializable

It is predefined class available in java.util package under Map interface.

Like Vector, Hashtable is also form the birth of java so called legacy class.

It is the sub class of Dictionary class which is an abstract class.

*The major difference between HashMap and Hashtable is, HashMap methods are not synchronized
where as Hastable methods are synchronized.

HashMap can accept one null key and multiple null values where as Hashtable does not contain anything
as a null(key and value both). if we try to add null then JVM will throw an exception i.e
NullPointerException.

The initial default capacity of Hashtable class is 11 where as loadFactor is 0.75.

It has also same constructor as we have in HashMap.(4 constructors)

1) Hashtable hs1 = new Hashtable();


It will create the Hashtable Object with default capacity as 11 as well as load factor is 0.75

2) Hashtable hs2 = new Hashtable(int initialCapacity);


will create the Hashtable object with specified capacity

3) Hashtable hs3 = new Hashtable(int initialCapacity, float loadFactor);


we can specify our own initialCapacity and loadFactor

4) Hashtable hs = new Hashtable(Map c);


Interconversion of Map Collection
----------------------------------------------------------------
import java.util.*;
public class HashtableDemo
{
public static void main(String args[])
{
Hashtable<Integer,String> map=new Hashtable<>();
map.put(1, "Java");
map.put(2, "is");
map.put(3, "best");
map.put(4,"language");

// map.put(5,null);
System.out.println(map);

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

for(Map.Entry m : map.entrySet())
{
System.out.println(m.getKey()+" = "+m.getValue());
}
}
}
----------------------------------------------------------------
import java.util.*;
public class HashtableDemo1
{
public static void main(String args[])
{
Hashtable<Integer,String> map=new Hashtable<>();
map.put(1,"Priyanka");
map.put(2,"Ruby");
map.put(3,"Vibha");
map.put(4,"Kanchan");

map.putIfAbsent(5,"Bina");
map.putIfAbsent(24,"Pooja");
map.putIfAbsent(26,"Ankita");

map.putIfAbsent(1,"Sneha");
System.out.println("Updated Map: "+map);
}
}
----------------------------------------------------------------
08-03-2024
----------
WeakHashMap :-
------------------
public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>

It is a predefined class in java.util package under Map interface.It was introduced from JDK 1.2v
onwards.

While working with HashMap, keys of HashMap are of strong reference type. This means the entry of
map will not be deleted by the garbage collector even though the key is set to be null and still it is not
eligible for Garbage Collector.

On the other hand while working with WeakHashMap, keys of WeakHashMap are of weak reference type.
This means the entry of a map is deleted by the garbage collector if the key value is set to be null
because it is of weak type.

So, HashMap dominates over Garbage Collector where as Garbage Collector dominates over
WeakHashMap.

It contains 4 types of Constructor :


---------------------------------------
1) WeakHashMap wm1 = new WeakHashMap();
Creates an empty WeakHashMap object with default capacity is 16 and load fator 0.75

2) WeakHashMap wm2 = new WeakHashMap(int initialCapacity);

3) WeakHashMap wm3 = new WeakHashMap(int initialCapacity, float loadFactor);

Eg:- WeakHashMap wm = new WeakHashMap(10,0.9);

capacity - The capacity of this map is 10. Meaning, it can store 10 entries.

loadFactor - The load factor of this map is 0.9. This means whenever our hashtable is filled up by 90%,
the entries are moved to a new hashtable of double the size of the original hashtable.

4) WeakHashMap wm4 = new WeakHashMap(Map m);


--------------------------------------------------------------
import java.util.*;
public class WeakHashMapDemo
{
public static void main(String args[]) throws Exception
{
WeakHashMap<Test,String> map = new WeakHashMap<>();

Test t = new Test();


map.put(t," Rahul ");

System.out.println(map); //{Test Nit = Rahul}

t = null;

System.gc(); //Explicitly calling garbage collector

Thread.sleep(3000);

System.out.println(map); //{}
}
}

class Test
{
@Override
public String toString()
{
return "Test Nit";
}

@Override
public void finalize() //called automaticaly if an object is eligible 4 GC
{
System.out.println("finalize method is called");
}
}
--------------------------------------------------------------
How to calculate Custom HashCode of any String value
public class CustomStringHashCode
{
public static int customHashCode(String str)
{
if (str == null)
{
return 0; // Return a default value for null strings
}

int hashCode = 0;

for (int i = 0; i < str.length(); i++)


{
char charValue = str.charAt(i);
hashCode = 31 * hashCode + charValue;
}

return hashCode;
}

public static void main(String[] args) {


String exampleString = "Suraj";

// Using the built-in hashCode method


int hashCodeBuiltIn = exampleString.hashCode();
System.out.println("Built-in hashCode: " + hashCodeBuiltIn);

// Using the customHashCode method


int customHashCode = customHashCode(exampleString);
System.out.println("Custom hashCode: " + customHashCode);
}
}
--------------------------------------------------------------
IdentityHashMap :
-----------------
public class IdentityHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Clonable,
Serializable.

It was introduced from JDK 1.4 onwards.

The IdentityHashMap uses == operator to compare keys.

As we know HashMap uses equals() and hashCode() method for comparing the keys based on the
hashcode of the object it will serach the bucket location and insert the entry their only.

So We should use IdentityHashMap where we need to check the reference or memory address instead of
logical equality.

HashMap uses hashCode of the "Object key" to find out the bucket loaction in Hashtable, on the other
hand IdentityHashMap does not use hashCode() method actually It uses
System.identityHashCode(Object o)

IdentityHashMap is more faster than HashMap in case of Comparison.

It has three constrcutors, It does not contain loadFactor specific constructor.


-------------------------------------------------------------
import java.util.*;
public class IdentityHashMapDemo
{
public static void main(String[] args)
{
HashMap<String,Integer> hm = new HashMap<>();

IdentityHashMap<String,Integer> ihm = new IdentityHashMap<>();

hm.put("Ravi",23);
hm.put(new String("Ravi"), 24);

ihm.put("Ravi",23);
ihm.put(new String("Ravi"), 27); //compares based on == operator

System.out.println("HashMap size :"+hm.size());


System.out.println(hm);
System.out.println("........................");
System.out.println("IdentityHashMap size :"+ihm.size());
System.out.println(ihm);

}
--------------------------------------------------------------
SortedMap<K,V>
--------------
It is a predefined interface available in java.util package under Map interface.

We should use SortedMap interface when we want to insert the key element based on some sorting order
i.e the default natural sorting order.
--------------------------------------------------------------
TreeMap<K,V>
------------
public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V> , Clonable,
Serializable

It is a predefined class avaialble in java.util package under Map interface.

It is a sorted map that means it will sort the elements by natural sorting order based on the key or by
using Comparator interface as a constructor parameter.

It does not allow non comparable keys.

It does not accept null key but null value allowed.

TreeMap implements NavigableMap and NavigableMap extends SortedMap. SortedMap extends Map
interface.

TreeMap contains 4 types of Constructors :

1) TreeMap tm1 = new TreeMap(); //creates an empty TreeMap

2) TreeMap tm2 = new TreeMap(Comparator cmp); //user defined soting logic


3) TreeMap tm3 = new TreeMap(Map m);

4) TreeMap tm4 = new TreeMap(SortedMap m);


--------------------------------------------------------------
import java.util.*;
public class TreeMapDemo
{
public static void main(String[] args)
{
TreeMap t = new TreeMap();
t.put(4,"Ravi");
t.put(7,"Aswin");
t.put(2,"Ananya");
t.put(1,"Dinesh");
t.put(9,"Ravi");
t.put(3,"Ankita");
t.put(5,null);

System.out.println(t);
}
}
--------------------------------------------------------------
import java.util.*;
public class TreeMapDemo1
{
public static void main(String args[])
{
TreeMap map = new TreeMap();
map.put("one","1");
map.put("two",null);
map.put("three","3");
map.put("four",4);

displayMap(map);

map.forEach((k, v) -> System.out.println("Key = " + k + ", Value = " + v));

}
static void displayMap(TreeMap map)
{
Collection c = map.entrySet(); //Set<Map.Entry>

Iterator i = c.iterator();
i.forEachRemaining(x -> System.out.println(x));
}
}
--------------------------------------------------------------
//firstKey() lastKey() headMap() tailMap() subMap() Map
// first() last() headSet() tailSet() subSet() Set

import java.util.*;
public class TreeMapDemo2
{
public static void main(String[] argv)
{
Map map = new TreeMap();
map.put("key2", "value2");
map.put("key3", "value3");
map.put("key1", "value1");

System.out.println(map); //{}

SortedMap x = (SortedMap) map;


System.out.println("First key is :"+x.firstKey());
System.out.println("Last Key is :"+x.lastKey());
}
}
---------------------------------------------------------------
package com.product.comparator;

import java.util.TreeMap;

record Player(int pid, String name)


{

public class TreeMapComparator


{
public static void main(String[] args)
{
TreeMap<Player,Integer> tm1 = new TreeMap<>((p1,p2)-> p1.name().compareTo(p2.name()));

tm1.put(new Player(333,"Rahul"), 24);


tm1.put(new Player(111,"Zuber"), 25);
tm1.put(new Player(222,"Aryan"), 26);

tm1.forEach((k , v)-> System.out.println("Key ="+k+" Value = "+v));


}

}
----------------------------------------------------------------
Methods of SortedMap interface :
--------------------------------
1) firstKey() //first key

2) lastKey() //last key

3) headMap(int keyRange) //less than the specified range

4) tailMap(int keyRange) //equal or greater than the specified range

5) subMap(int startKeyRange, int endKeyRange) //the range of key where startKey will be inclusive and
endKey will be exclusive.

return type of headMap(), tailMap() and subMap() would be SortedMap(I)

import java.util.*;
public class SortedMapMethodDemo
{
public static void main(String args[])
{
SortedMap<Integer,String> map=new TreeMap<>();
map.put(100,"Amit");
map.put(101,"Ravi");

map.put(102,"Vijay");
map.put(103,"Rahul");

System.out.println("First Key: "+map.firstKey()); //100


System.out.println("Last Key "+map.lastKey()); //103
System.out.println("headMap: "+map.headMap(102)); //100 101
System.out.println("tailMap: "+map.tailMap(102)); //102 103
System.out.println("subMap: "+map.subMap(100, 102)); //100 101

}
}
----------------------------------------------------------------
Assignment
NavigableMap Method
----------------------------------------------------------------
09-03-2024
----------
Properties class:
-----------------
Properties class is used to maintain the data in the key-value form. It takes both key and value as a string.

Properties class is a subclass of Hashtable. It provides the methods to store properties in a properties file
and to get the properties from the properties file, we should load method of Properties class.

System.getProperties() returns the all system properties.

Here we need to create a file with with extension .properties

Example :
---------
driver = oracle.jdbc.driver.OracleDriver
user = system
password = tiger

FileReader fr = new FileReader("db.properties");

Properties p = new Properties();


p.load(fr);
--------------------------------------------------------------
import java.util.*;
import java.io.*;
public class PropertiesExample1
{
public static void main(String[] args)throws Exception
{
FileReader reader=new FileReader("db.properties");
Properties p=new Properties();
p.load(reader);

System.out.println(p.getProperty("user"));
System.out.println(p.getProperty("password"));
System.out.println(p.getProperty("driver"));
}
}

By using Properties class we can dynamically change the property which we are taking from properties
file without re-compilation of .java file.
----------------------------------------------------------------
import java.util.*;
import java.io.*;
public class PropertiesExample2
{
public static void main(String[] args)throws Exception
{
Properties p=System.getProperties();
Set set=p.entrySet();

Iterator itr=set.iterator();
while(itr.hasNext())
{
Map.Entry entry=(Map.Entry)itr.next();
System.out.println(entry.getKey()+" = "+entry.getValue());
}

} }

In order to get the complete properties of a System, we should


getProperties() static method of System class. The signature of this method is :

public static Properties getProperties()


----------------------------------------------------------------
Queue interface :-
-------------------
1) It is sub interface of Collection(I)

2) It works in FIFO(First In first out)

3) It is an ordered collection.

4) In a queue, insertion is possible from last is called REAR where as deletion is possible from the starting
is called FRONT of the queue.

5) From jdk 1.5 onwards LinkedList class implments Queue interface to handle the basic queue
operations.
---------------------------------------------------------------
Queue interface :-
-------------------
1) It is sub interface of Collection(I)
2) It works in FIFO(First In first out)

3) It is an ordered collection.

4) In a queue, insertion is possible from last is called REAR where as deletion is possible from the starting
is called FRONT of the queue.

5) From jdk 1.5 onwards LinkedList class implments Queue interface to handle the basic queue
operations.

PriorityQueue :
----------------
public class PriorityQueue extends AbstractQueue implements Serializable

It is a predefined class in java.util package, available from Jdk 1.5 onwards.

It inserts the elements based on the priority HEAP (Using Binary tree).

The elements of the priority queue are ordered according to their natural ordering, or by a Comparator
provided at queue construction time, depending on which constructor is used.

A priority queue does not permit null elements as well as It uses Binary tree to insert the elements.

It provides natural sorting order so we can’t take non-comparable objects(hetrogeneous types of Object)

The initial capacity of PriorityQueue is 11.

Constructor :
--------------
1) PriorityQueue pq1 = new PriorityQueue();

2) PriorityQueue pq2 = new PriorityQueue(int initialCapacity);

3) PriorityQueue pq3 = new PriorityQueue(int initialCapacity, Comparator cmp);

4-) PriorityQueue pq3 = new PriorityQueue(Comparator cmp);

5) PriorityQueue pq4 = new PriorityQueue(Collection c);

Methods :-
----------
add() / offer() :- Used to add an element in the Queue

poll() :- It is used to fetch the elements from top of the queue, after fetching it will delete the element.

peek() :- It is also used to fetch the elements from top of the queue, Unlike poll it will only fetch but not
delete the element.

boolean remove(Object element) :- It is used to remove an element. The return type is boolean.
---------------------------------------------------------------
import java.util.PriorityQueue;

public class PriorityQueueDemo


{
public static void main(String[] argv)
{
PriorityQueue<String> pq = new PriorityQueue<>();
pq.add("Orange");
pq.add("Apple");
pq.add("Mango");
pq.add("Guava");
pq.add("Grapes");

System.out.println(pq);

}
}
---------------------------------------------------------------
import java.util.PriorityQueue;
public class PriorityQueueDemo3
{
public static void main(String[] argv)
{
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(11);
pq.add(2);
pq.add(4);
pq.add(6);
System.out.println(pq);
}
}
----------------------------------------------------------------

import java.util.PriorityQueue;
public class PriorityQueueDemo1
{
public static void main(String[] argv)
{
PriorityQueue<String> pq = new PriorityQueue<>();
pq.add("9");
pq.add("8");
pq.add("7");
System.out.print(pq.peek() + " "); //7 3 5 6
pq.offer("6");
pq.offer("5");
pq.add("3");

pq.remove("1");
System.out.print(pq.poll() + " ");
if (pq.remove("2"))
System.out.print(pq.poll() + " ");
System.out.println(pq.poll() + " " + pq.peek());
System.out.println(pq);
}
}
---------------------------------------------------------------
import java.util.PriorityQueue;
public class PriorityQueueDemo2
{
public static void main(String[] argv)
{
PriorityQueue<String> pq = new PriorityQueue<>();
pq.add("2");
pq.add("4");
pq.add("6"); // 6 9
System.out.print(pq.peek() + " "); //2 2 3 4 4
pq.offer("1");
pq.offer("9");
pq.add("3");

pq.remove("1");
System.out.print(pq.poll() + " ");
if (pq.remove("2"))
System.out.print(pq.poll() + " ");
System.out.println(pq.poll() + " " + pq.peek()+" "+pq.poll());
}
}

---------------------------------------------------------------
Assignment :
------------
WAP to sort the element of PriorityQueue based on Comparator (through Constructor)
---------------------------------------------------------------
Generics :
----------
Why generic came into picture :
------------------------------------
As we know our compiler is known for Strict type checking because java is a statically typed checked
language.

The basic problem with collection is It can hold any kind of Object.

ArrayList al = new ArrayList();


al.add("Ravi");
al.add("Aswin");
al.add("Rahul");
al.add("Raj");
al.add("Samir");

for(int i =0; i<al.size(); i++)


{
String s = (String) al.get(i);
System.out.println(s);
}

By looking the above code it is clear that Collection stores everything in the form of Object so here even
after adding String type only we need type casting as shown below.

import java.util.*;
class Test1
{
public static void main(String[] args)
{
ArrayList al = new ArrayList(); //raw type
al.add("Ravi");
al.add("Ajay");
al.add("Vijay");

for(int i=0; i<al.size(); i++)


{
String name = (String) al.get(i); //type casting is required
System.out.println(name.toUpperCase());
}

}
}

Even after type casting there is no guarantee that the things which are coming from ArrayList Object is
Integer only because we can add anything in the Collection as a result java.lang.ClassCastException as
shown in the program below.

import java.util.*;
class Test2
{
public static void main(String[] args)
{
ArrayList t = new ArrayList(); //raw type
t.add("alpha");
t.add("beta");
for (int i = 0; i < t.size(); i++)
{
String str =(String) t.get(i);
System.out.println(str);
}

t.add(1234);
t.add(1256);
for (int i = 0; i < t.size(); ++i)
{
String obj= (String)t.get(i); //we can’t perform type casting here
System.out.println(obj);
}
}
}
---------------------------------------------------------------
To avoid all the above said problem Generics came into picture from JDK 1.5 onwards

-> It deals with type safe Object so there is a guarantee of both the end i.e putting inside and getting out.

Example:-
ArrayList<String > al = new ArrayList<>();

Now here we have a guarantee that only String can be inserted as well as only String will come out from
the Collection so we can perform String related operation.
Advantages :-
---------------
a) Type safe Object (No compilation warning)

b) Strict compile time checking (Type erasure)

c) No need of type casting


--------------------------------------------------------------
11-03-2024
-----------
import java.util.*;
public class Test3
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<>(); //Generic type
al.add("Ravi");
al.add("Ajay");
al.add("Vijay");

for(int i=0; i<al.size(); i++)


{
String name = al.get(i); //no type casting is required
System.out.println(name.toUpperCase());
}
}
}
-----------------------------------------------------------------
//Program that describes the return type of any method can be type safe
//[We can apply generics on method return type]

import java.util.*;
public class Test4
{
public static void main(String [] args)
{
Dog d1 = new Dog();
Dog d2 = d1.getDogList().get(0);
System.out.println(d2);
}
}
class Dog
{
public List<Dog> getDogList()
{
ArrayList<Dog> d = new ArrayList<>();
d.add(new Dog());
d.add(new Dog());
d.add(new Dog());
return d;
}
}

Note :- In the above program the compiler will stop us from returning anything which is not compaitable
List<Dog> and there is a guarantee that only "type safe list of Dog object" will be returned so we need not
to provide type casting as shown below
Dog d2 = (Dog) d1.getDogList().get(0); //before generic.
----------------------------------------------------------------
//Mixing generic with non-generic
import java.util.*;

class Car
{
}
public class Test5
{
public static void main(String [] args)
{
ArrayList<Car> a = new ArrayList<>();
a.add(new Car());
a.add(new Car());
a.add(new Car());

ArrayList b = a; //assigning Generic to raw type

System.out.println(b);
}
}
----------------------------------------------------------------
//Mixing generic to non-generic
import java.util.*;
public class Test6
{
public static void main(String[] args)
{
List<Integer> myList = new ArrayList<>();
myList.add(4);
myList.add(6);
myList.add(5);

UnknownClass u = new UnknownClass();


int total = u.addValues(myList);
System.out.println("The sum of Integer Object is :"+total);
}
}
class UnknownClass
{
public int addValues(List list) //generic to raw type OR
{
Iterator it = list.iterator();
int total = 0;
while (it.hasNext())
{
int i = ((Integer)it.next());
total += i; //total = 15
}
return total;
}
}
Note :-
In the above program the compiler will not generate any warning message because even though we are
assigning type safe Integer Object to unsafe or raw type List Object but this List Object is not inserting
anything new in the collection so there is no risk to the caller.
----------------------------------------------------------------
//Mixing generic to non-generic
import java.util.*;
public class Test7
{
public static void main(String[] args)
{
List<Integer> myList = new ArrayList<>();

myList.add(4);
myList.add(6);
UnknownClass u = new UnknownClass();
int total = u.addValues(myList);
System.out.println(total);
}
}
class UnknownClass
{
public int addValues(List list)
{
list.add(5); //adding object to raw type
Iterator it = list.iterator();
int total = 0;
while (it.hasNext())
{
int i = ((Integer)it.next());
total += i;
}
return total;
}
}
Here Compiler will generate warning message because the unsafe object is inserting the value 5 to safe
object.
----------------------------------------------------------------
*Type Erasure
------------
In the above program the compiler will generate warning message because the unsafe List Object is
inserting the Integer object 5 so the type safe Integer object is getting value 5 from unsafe type so there is
a problem to the caller method.

By writing ArrayList<Integer> actually JVM does not have any idea that our ArrayList was suppose to hold
only Integers.

All the type safe generics information does not exist at runtime. All our generic code is Strictly for
compiler.

There is a process done by java compiler called "Type erasure" in which the java compiler converts
generic version to non-generic type.

List<Integer> myList = new ArrayList<Integer>();


At the compilation time it is fine but at runtime for JVM the code becomes

List myList = new ArrayList();

Note :- GENERIC IS STRICTLY A COMPILE TIME PROTECTION.


-----------------------------------------------------------------
Behavior of Polymorphism with Array and Generics :
--------------------------------------------------

//Polymorphism with array

import java.util.*;
abstract class Animal
{
public abstract void checkup();
}

class Dog extends Animal


{
@Override
public void checkup()
{
System.out.println("Dog checkup");
}
}

class Cat extends Animal


{
@Override
public void checkup()
{
System.out.println("Cat checkup");
}
}

class Bird extends Animal


{
@Override
public void checkup()
{
System.out.println("Bird checkup");
}
}

public class Test8


{
public void checkAnimals(Animal animals[])
{
for(Animal animal : animals)
{
animal.checkup();
}
}

public static void main(String[] args)


{
Dog []dogs={new Dog(), new Dog()};

Cat []cats={new Cat(), new Cat(), new Cat()};

Bird []birds = {new Bird(), new Bird()};

Test8 t = new Test8();

t.checkAnimals(dogs);
t.checkAnimals(cats);
t.checkAnimals(birds);
}
}
Note :-From the above program it is clear that polymorphism(Upcasting) concept works with array.
----------------------------------------------------------------
import java.util.*;
abstract class Animal
{
public abstract void checkup();
}

class Dog extends Animal


{
@Override
public void checkup()
{
System.out.println("Dog checkup");
}
}

class Cat extends Animal


{
@Override
public void checkup()
{
System.out.println("Cat checkup");
}
}
class Bird extends Animal
{
@Override
public void checkup()
{
System.out.println("Bird checkup");
}
}
public class Test9
{
public void checkAnimals(List<Animal> animals)
{
for(Animal animal : animals)
{
animal.checkup();
}
}
public static void main(String[] args)
{
List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog());
dogs.add(new Dog());

List<Cat> cats = new ArrayList<>();


cats.add(new Cat());
cats.add(new Cat());

List<Bird> birds = new ArrayList<>();


birds.add(new Bird());

Test9 t = new Test9();


t.checkAnimals(dogs);
t.checkAnimals(cats);
t.checkAnimals(birds);

}
}

Note :- The above program will generate the compilation error.

So from the above program it is clear that polymorphism does not work in the same way for generics as it
does with arrays.

Eg:-

Parent [] arr = new Child[5]; //valid


Object [] arr = new String[5]; //valid

But in generics the same type is not valid

List<Object> list = new ArrayList<Integer>(); //Invalid


List<Parent> mylist = new ArrayList<Child>(); //Invalid
----------------------------------------------------------------
import java.util.*;
public class Test10
{
public static void main(String [] args)
{
//ArrayList<Number> al = new ArrayList<Integer>(); [Compile time]
//ArrayList al = new ArrayList(); [Runtime]
//al.add("Ravi");

Object []obj = new String[3]; //valid with Array


obj[0] = "Ravi";
obj[1] = "hyd";
obj[2] = 12; //java.lang.ArrayStoreException
}
}
Note :- It will generate java.lang.ArrayStoreException because we are trying to insert 12 (integer value)
into String array.

In Array we have an Exception called ArrayStoreException but the same Exception or such type of
exception, is not available with Generics that is the reason in generics compiler does not allow upcasting
concept.
(It is a strict compile time checking)
----------------------------------------------------------------
import java.util.*;
class Parent
{
}
class Child extends Parent
{
}

public class Test11


{
public static void main(String [] args)
{
ArrayList<Parent> lp = new ArrayList<Child>();

ArrayList<Parent> lp1 = new ArrayList<Parent>();

ArrayList<Child> lp2 = new ArrayList<>();

System.out.println("Success");
}
}
-----------------------------------------------------------------
Wild card character(?) :
------------------------
<?> -: Many possibilities

<Animal> -: Only <Animal> can assign, but not Dog or sub type of animal

<? super Dog> -: Dog, Animal, Object can assign (Compiler has surity)

<? extends Animal> -: Below of Animal(Child of Animal) means, sub classes of Animal (But the compiler
does not have surity because you can have many sub classes of Animal in the future, so chances of
wrong collections)
-----------------------------------------------------------------
//program on wild-card chracter
import java.util.*;
class Parent
{

}
class Child extends Parent
{
}
public class Test12
{
public static void main(String [] args)
{
List<?> lp = new ArrayList<Parent>();
System.out.println("Wild card....");
}
}
---------------------------------------------------------------
import java.util.*;
public class Test13
{
public static void main(String[] args)
{
List<? extends Number> list1 = new ArrayList<Byte>();

List<? super String> list2 = new ArrayList<Object>();

List<? super Gamma> list3 = new ArrayList<Alpha>();

List list4 = new ArrayList();

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

class Alpha
{
}
class Beta extends Alpha
{
}
class Gamma extends Alpha
{
}
-----------------------------------------------------------------
class Test<R,A>
{
private R r;
public void set(A a)
{
r = a; //error
}

public R get()
{
return r;
}
}
public class Test14
{
public static void main(String[] args)
{
Test<String,String> test = new Test();
test.set("Info");
System.out.println(test.get());
}
}
----------------------------------------------------------------
class MyClass<T>
{
T obj;
public MyClass(T obj) //obj = new Student(
{
this.obj=obj;
}

T getObj()
{
return obj;
}
}
public class Test15
{
public static void main(String[] args)
{
Integer i=12;
MyClass<Integer> mi = new MyClass<>(i);
System.out.println("Integer object stored :"+mi.getObj());

Float f=12.34f;
MyClass<Float> mf = new MyClass<>(f);
System.out.println("Float object stored :"+mf.getObj());

MyClass<String> ms = new MyClass<>("Rahul");


System.out.println("String object stored :"+ms.getObj());

MyClass<Boolean> mb = new MyClass<>(false);


System.out.println("Boolean object stored :"+mb.getObj());

Double d=99.34;
MyClass<Double> md = new MyClass<>(d);
System.out.println("Double object stored :"+md.getObj());

MyClass<Student> std = new MyClass<>(new Student(1,"A"));


System.out.println("Student object stored :"+std.getObj());
}
}

record Student(int id, String name)


{

}
-----------------------------------------------------------------
//E stands for Element type
class Fruit
{
}
class Apple extends Fruit //Fruit is super, Apple is sub class
{
@Override
public String toString()
{
return "Apple";
}
}

class Basket<E> // E is Fruit Types


{
private E element;
public void setElement(E element) //Fruit element = new Apple();
{
this.element = element;
}

public E getElement() // public Fruit getElement{}


{
return this.element;
}
}

public class Test16


{
public static void main(String[] args)
{
Basket<Fruit> b = new Basket<>();
b.setElement(new Apple());

Apple x = (Apple) b.getElement();


System.out.println(x);

Basket<Fruit> b1 = new Basket<>();


b1.setElement(new Mango());
Mango y = (Mango)b1.getElement();
System.out.println(y);

}
}
class Mango extends Fruit
{
@Override
public String toString()
{
return "Mango";
}
}
----------------------------------------------------------------
12-03-2024
-----------
Concurrent collections in java
-------------------------------
Concurrent Collections are introduced from JDK 1.5 onwards to enhance the performance of
multithreaded application.

These are threadsafe collection and available in java.util.concurrent sub package.

Limitation of Traditional Collection :


---------------------------------------
1) In the Collection framework most of the Collection classes are not thread-safe because those are
non-synchronized like ArrayList, LinkedList, HashSet, HashMap is non-synchronized in nature, So If
multiple threads will perform any operation on the collection object simultaneously then we will get some
wrong data this is known as Data race or Race condition.

2) Some Collection classes are synchronized like Vector, Hashtable but performance wise these classes
are slow in nature.

Collections class has provided static methods to make our List, Set and Map interface classes as a
synchronized.

a) public static List synchronizedList(List list)


b) public static Set synchronizedSet(Set set)
c) public static Map synchronizedMap(Map map)

3) Traditional Collection works with fail fast iterator that means while iterating the element,
if there is a change in structure then we will get ConcurrentModificationException.
On the other hand concurrent collection works with fail safe iterator where even though there is a
change in structure but we will not get ConcurrentModificationException.
----------------------------------------------------------------
//Collections.synchronizedList(List list);
import java.util.*;
public class Collection2
{
public static void main(String[] args)
{
ArrayList<String> arl = new ArrayList<>();
arl.add("Apple");
arl.add("Orange");
arl.add("Grapes");
arl.add("Mango");
arl.add("Guava");
arl.add("Mango");

List<String> syncCollection = Collections.synchronizedList(arl);

List<String> upperList = new ArrayList<>(); //New List

Runnable listOperations = () ->


{
synchronized (syncCollection)
{
syncCollection.forEach(str -> upperList.add(str.toUpperCase()));
}
};

Thread t1 = new Thread(listOperations);


t1.start();

upperList.forEach(x -> System.out.println(x));


}
}
----------------------------------------------------------------
//Collections.synchronizedSet(Set set);
import java.util.*;
public class Collection3
{
public static void main(String[] args)
{
Set<String> set = Collections.synchronizedSet(new HashSet<>());
set.add("Apple");
set.add("Orange");
set.add("Grapes");
set.add("Mango");
set.add("Guava");
set.add("Mango");
System.out.println("Set after Synchronization :");
synchronized (set)
{
Spliterator<String> itr = set.spliterator();
itr.forEachRemaining(str -> System.out.println(str));
}
}
}
---------------------------------------------------------------
//Collections.synchronizedMap(Map map);
import java.util.*;
public class Collection4
{
public static void main(String[] args)
{
Map<String, String> map = new HashMap<String, String>();
map.put("1", "Ravi");
map.put("4", "Elina");
map.put("3", "Aryan");
Map<String, String> synmap = Collections.synchronizedMap(map);
System.out.println("Synchronized map is :" + synmap);
}
}
----------------------------------------------------------------
package com.ravi.concurrent;

import java.util.ArrayList;
import java.util.Iterator;

class Concurrent extends Thread {


ArrayList<String> al = null;

public Concurrent(ArrayList<String> al) {


super();
this.al = al;
}

@Override
public void run()
{
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
}
al.add("Ameerpet");
}

public class ConcurrentModificationDemo {

public static void main(String[] args) throws InterruptedException


{
ArrayList<String> arl = new ArrayList<>();
arl.add("Hyderabad");
arl.add("Pune");
arl.add("Delhi");
arl.add("Indore");

Concurrent c = new Concurrent(arl);


c.start();

Iterator<String> itr = arl.iterator();


while(itr.hasNext())
{
System.out.println(itr.next());
Thread.sleep(1500);
}

Note :- In the above program we will get java.util.ConcurrentModificationException because Iterator is fail
fast iterator.
----------------------------------------------------------------
CopyOnWriteArrayList in java :
---------------------------------
public class CopyOnWriteArrayList implements List, Cloneable, Serializable, RanomAccess

A CopyOnWriteArrayList is similar to an ArrayList but it has some additional features like thread-safe.
This class is existing in java.util.concurrent sub package.

ArrayList is not thread-safe. We cant use ArrayList in the multi-threaded environment because it creates a
problem in ArrayList values (Data inconsistency).

*The CopyOnWriteArrayList is an enhanced version of ArrayList. If we are making any modifications(add,


remove, etc.) in CopyOnWriteArrayList then JVM creates a new copy by use of Cloning.

The CopyOnWriteArrayList is costly, if we want to perform update operations, because whenever we


make any changes the JVM creates a cloned copy of the array and add/update element to it.

It is a thread-safe version of ArrayList as well as here Iterator is fail safe iterator. Multiple threads can
read the data but only one thread can write the data at one time.
*CopyOnWriteArrayList is the best choice if we want to perform read operation frequently in multithreaded
environment.

The CopyOnWriteArrayList is a replacement of a synchronized List, because it offers better concurrency.

Constructors of CopyOnWriteArrayList in java :


----------------------------------------------------
We have 3 constructors :

1) CopyOnWriteArrayList c = new CopyOnWriteArrayList();


It creates an empty list in memory. This constructor is useful when we want to create a list without any
value.

2) CopyOnWriteArrayList c = new CopyOnWriteArrayList(Collection c);


Interconversion of collections.

3) CopyOnWriteArrayList c = new CopyOnWriteArrayList(Object[] obj) ;


It Creates a list that containing all the elements that is specified Array. This constructor is useful when we
want to create a CopyOnWriteArrayList from Array.

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListExample1


{
public static void main(String[] args)
{
List<String> list = Arrays.asList("Apple", "Orange", "Mango","Kiwi", "Grapes");

CopyOnWriteArrayList<String> copyOnWriteList = new CopyOnWriteArrayList<String>(list);

System.out.println("Without modification = "+copyOnWriteList);

//Iterator1
Iterator<String> iterator1 = copyOnWriteList.iterator();

//Add one element and verify list is updated


copyOnWriteList.add("Guava");

System.out.println("After modification = "+copyOnWriteList);

//Iterator2
Iterator<String> iterator2 = copyOnWriteList.iterator();

System.out.println("Element from first Iterator:");


iterator1.forEachRemaining(System.out :: println);

System.out.println("Element from Second Iterator:");


iterator2.forEachRemaining(System.out :: println);
}
}
----------------------------------------------------------------
import java.util.*;
import java.util.concurrent.*;
class ConcurrentModification extends Thread
{
CopyOnWriteArrayList<String> al = null;
public ConcurrentModification(CopyOnWriteArrayList<String> al)
{
this.al = al;
}
@Override
public void run()
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
al.add("KIWI");
}
}
public class CopyOnWriteArrayListExample2
{
public static void main(String[] args) throws InterruptedException
{
CopyOnWriteArrayList<String> arl = new CopyOnWriteArrayList<>();
arl.add("Apple");
arl.add("Orange");
arl.add("Grapes");
arl.add("Mango");
arl.add("Guava");
ConcurrentModification cm = new ConcurrentModification(arl);
cm.start();

Iterator<String> itr = arl.iterator();


while(itr.hasNext())
{
String str = itr.next();
System.out.println(str);
Thread.sleep(1500);
}

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

Spliterator<String> spl = arl.spliterator();


spl.forEachRemaining(x -> System.out.println(x));
}
}

Here We will not get java.util.ConcurrentModificationException because Here the Iterator is Fail safe
Iterator.
----------------------------------------------------------------
13-03-2024
-----------
CopyOnWriteArraySet :
--------------------------
public class CopyOnWriteArraySet extends AbstractSet implements Serializable

A CopyOnWriteArraySet is a thread-safe version of HashSet in Java and it works like


CopyOnWriteArrayList in java.

The CopyOnWriteArraySet internally used CopyOnWriteArrayList to perform all type of operation.It means
the CopyOnWriteArraySet internally creates an object of CopyOnWriteArrayList and perform operation on
it.

Whenever we perform add, set, and remove operation on CopyOnWriteArraySet, it internally creates a
new object of CopyOnWriteArrayList and copies all the data to the new object. So, when it is used in by
multiple threads, it doesnt create a problem, but it is well suited if we have small size collection and want
to perform only read operation by multiple threads.

The CopyOnWriteArraySet is the replacement of synchronizedSet and offers better concurrency.

It creates a new copy of the array every time iterator is created, so performance is slower than HashSet.

Constructors :
----------------
It has two constructors

1) CopyOnWriteArraySet set1 = new CopyOnWriteArraySet();


It will create an empty Set

2) CopyOnWriteArraySet set1 = new CopyOnWriteArraySet(Collection c); Interconversion of collection


----------------------------------------------------------------
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CopyOnWriteArraySet;

public class CopyOnWriteArraySetExample1


{
public static void main(String[] args)
{
CopyOnWriteArraySet<String> set = new CopyOnWriteArraySet<>();

set.add("Java");
set.add("Python");
set.add("C++");
set.add("Java");

Iterator itr = set.iterator();


while(itr.hasNext())
{
System.out.println(itr.next());
}

// Adding a new element


set.add("JavaScript");
System.out.println("............");
for (String language : set)
{
System.out.println(language);
}
}
}
-----------------------------------------------------------------
import java.util.concurrent.CopyOnWriteArraySet;

public class CopyOnWriteArraySetExample2


{
public static void main(String[] args)
{
CopyOnWriteArraySet<Integer> set = new CopyOnWriteArraySet<Integer>();
set.add(1);
set.add(2);
set.add(3);
set.add(4);
set.add(5);

System.out.println("Is element contains: "+set.contains(1));

System.out.println("Is set empty: "+set.isEmpty());

System.out.println("remove element from set: "+set.remove(3));

System.out.println("Element from Set: "+ set);


}
}
---------------------------------------------------------------
*** ConcurrentHashMap :
-----------------------
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>,
Serializable

Like HashMap, ConcurrentHashMap provides similar functionality except that it has internally maintained
concurrency.

It is the concurrent version of the HashMap. It internally maintains a Hashtable that is divided into
segments(Buckets).

The number of segments depends upon the level of concurrency required the Concurrent HashMap. By
default, it divides into 16 segments and each Segment behaves independently. It doesnt lock the whole
HashMap as done in Hashtables/synchronizedMap, it only locks the particular segment(Bucket) of
HashMap. [Bucket level locking]

ConcurrentHashMap allows multiple threads can perform read operation without locking the
ConcurrentHashMap object.

It does not allow null as a key or evan null as a value.

[Note :- TreeSet, TreeMap, Hashtable, PriroityQueue, ConcurrentHashMap]

It contains 5 types of constructor :


----------------------------------------
1) ConcurrentHashMap chm1 = new ConcurrentHashMap();
2) ConcurrentHashMap chm2 = new ConcurrentHashMap(int initialCapacity);

3) ConcurrentHashMap chm3 = new ConcurrentHashMap(int initialCapacity, float loadFactor);

4) ConcurrentHashMap chm4 = new ConcurrentHashMap(int initialCapacity, float loadFactor, int


concurrencyLevel);

5) ConcurrentHashMap chm5 = new ConcurrentHashMap(ConcurrentMap m);

Internal Working of ConcurrentHashMap :


-----------------------------------------------
Like HashMap and Hashtable, the ConcurrentHashMap is also used Hashtable data structure. But it is
using the segment locking strategy to handle the multiple threads.

A segment(bucket) is a portion of ConcurrentHashMap and ConcurrentHashMap uses a separate lock for


each thread. Unlike Hashtable or synchronized HashMap, it doesnt synchronize the whole HashMap or
Hashtable for one thread.

As we have seen in the internal implementation of the HashMap, the default size of HashMap is 16 and it
means there are 16 buckets. The ConcurrentHashMap uses the same concept is used in
ConcurrentHashMap. It uses the 16 separate locks for 16 buckets by default because the default
concurrency level is 16. It means a ConcurrentHashMap can be used by 16 threads at same time. If one
thread is reading from one bucket(Segment), then the second bucket doesnt affect it.

Why we need ConcurrentHashMap in java?


-------------------------------------------------
As we know Hashtable and HashMap works based on key-value pairs. But why we are introducing
another Map? As we know HashMap is not thread safe, but we can make it thread-safe by using
Collections.synchronizedMap() method and Hashtable is thread-safe by default.

But a synchronized HashMap or Hashtable is accessible only by one thread at a time because the object
get the lock for the whole HashMap or Hashtable. Even multiple threads cant perform read operations at
the same time. It is the main disadvantage of Synchronized HashMap or Hashtable, which creates
performance issues. So ConcurrentHashMap provides better performance than Synchronized HashMap
or Hashtable.
----------------------------------------------------------------
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample1


{
public static void main(String args[])
{

HashMap<Integer, String> hashMap = new HashMap<Integer, String>();


hashMap.put(1, "Ravi");
hashMap.put(2, "Ankit");
hashMap.put(3, "Prashant");
hashMap.put(4, "Pallavi");

ConcurrentHashMap<Integer, String> concurrentHashMap = new


ConcurrentHashMap<>(hashMap);
System.out.println("Object from ConcurrentHashMap: "+ concurrentHashMap);
}

}
----------------------------------------------------------------
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample2


{
public static void main(String args[])
{
// Creating ConcurrentHashMap
Map<String, String> cityTemperatureMap = new ConcurrentHashMap<>();

cityTemperatureMap.put("Delhi", "30");
cityTemperatureMap.put("Mumbai", "32");
cityTemperatureMap.put("Chennai", "35");
cityTemperatureMap.put("Bangalore", "22" );

Iterator<String> iterator = cityTemperatureMap.keySet().iterator();

while (iterator.hasNext())
{
System.out.println(cityTemperatureMap.get(iterator.next()));
// adding new value, it won’t throw error
cityTemperatureMap.put("Hyderabad", "28");
}
}
}
-----------------------------------------------------------------
enum in java :
--------------
An enum is class in java that is used to represent group of universal constants. It is introduced from JDK
1.5 onwards.

In order to craete an enum, we can use enum keyword and all the univarsal constants of the enum must
be separeted by comma. Semicolon is optional at the end.

Example:-

enum Color
{
RED, BLUE, BLACK, PINK //public + static + final

The enum constants are by default public, static and final.

An enum we can define inside the class, outside of the class and even inside of the method.

If we define an enum inside the class then we can apply public, private, protected and static.

Every enum in java extends java.lang.Enum class so an enum can implement many interfaces but can’t
extends a class.
By deafult every enum is implicitly final so we can’t inherit an enum.

In order to get the constant value of an enum we can use values() method which returns enum array, but
this method is provided as part of enum keyword that means this method is not available inside the Enum
class(java.lang.Enum).

In order to get the order position of enum constants we can use ordinal() method which is given inside the
enum class and the return type of this method is int. The order position of enum constant will start from 0.

As we know an enum is just like a class so we can define any method, constructor inside an enum.
Constructor must be either private or default.

*All the enum constants are by default object of type enum.

Enum constants must be decalred at the first line of enum otherwise we will get compilation error.
---------------------------------------------------------------
public class Test1
{
public static void main(String[] args)
{
enum Month
{
JANUARY, FEBRUARY,MARCH //public + static + final
}

System.out.println(Month.MARCH);
}
}
---------------------------------------------------------------
public class Test1
{
public static void main(String[] args)
{
enum Month
{
JANUARY, FEBRUARY,MARCH //public + static + final
}

System.out.println(Month.MARCH);
}
}
--------------------------------------------------------------
enum Month
{
JANUARY,FEBRUARY,MARCH
}
public class Test2
{
enum Color { RED,BLUE,BLACK }

public static void main(String[] args)


{
enum Week {SUNDAY, MONDAY, TUESDAY }
System.out.println(Month.FEBRUARY);
System.out.println(Color.RED);
System.out.println(Week.SUNDAY);
}
}

Note :- From the above Program it is clear that we can define an enum inside a class, outside of a class
and inside a method as well.
---------------------------------------------------------------
//Comapring the constant of an enum
public class Test3
{
enum Color { RED,BLUE }

public static void main(String args[])


{
Color c1 = Color.RED;
Color c2 = Color.RED;

if(c1 == c2)
{
System.out.println("==");
}
if(c1.equals(c2))
{
System.out.println("equals");
}
}
}

Here we will get true in both the cases because == operator always compares the memory address and
Object class equals() method also uses == oprator.
--------------------------------------------------------------
public class Test4
{
private enum Season //private, public, protected, static
{
SPRING, SUMMER, WINTER, RAINY;
}

public static void main(String[] args)


{
System.out.println(Season.RAINY);
}
}
---------------------------------------------------------------
//Interview Question
class Hello
{
int x = 100;
}

enum Direction extends Hello


{
EAST, WEST, NORTH, SOUTH
}

class Test5
{
public static void main(String[] args)
{
System.out.println(Direction.SOUTH);
}
}

Every enum extends from java.lang.Enum class so enum cannot


extend any other class
---------------------------------------------------------------
//All enums are by default final so can’t inherit

enum Color
{
RED, BLUE, PINK;
}
class Test6 extends Color
{
public static void main(String[] args)
{
System.out.println(Color.RED);
}
}

Every enum is by default final so we cannot inherit an enum.


---------------------------------------------------------------
//values() to get all the values of enum

class Test7
{
enum Season
{
SPRING, SUMMER, WINTER, FALL, RAINY
}

public static void main(String[] args)


{
Season x []= Season.values();

for(Season y : x)
System.out.println(y);
}
}
--------------------------------------------------------------
//ordinal() to find out the order position
class Test8
{
static enum Season
{
SPRING, SUMMER, WINTER, FALL, RAINY
}
public static void main(String[] args)
{
Season s1[] = Season.values();

for(Season x : s1)
System.out.println(x+" order is :"+x.ordinal());
}
}
---------------------------------------------------------------
//We can take main () inside an enum

enum Test9
{
TEST1, TEST2, TEST3; //Semicolon is compulsory

public static void main(String[] args)


{
System.out.println("Enum main method");
}
}
---------------------------------------------------------------
14-03-2024
-----------
//constant must be in first line of an enum

enum Test10
{

public static void main(String[] args)


{
System.out.println("Enum main method");
}

HR, SALESMAN, MANAGER;

}
-----------------------------------------------------------------
//Writing constructor in enum
enum Season
{
WINTER, SUMMER, SPRING, RAINY; //All are object of type enum

Season()
{
System.out.println("Constructor is executed....");
}

}
class Test11
{
public static void main(String[] args)
{
System.out.println(Season.WINTER);
System.out.println(Season.SUMMER);

}
}

Note :- By default every enum constant is an object of type enum so it will automatically call no argument
constructor at the time of loading the enum.class file but enum constant should not contain any
constructor.
-----------------------------------------------------------------
//Writing constructor with message
enum Season
{
SPRING("Pleasant"), SUMMER("UnPleasent"), RAINY("Rain"), WINTER;

String msg;

Season(String msg)
{
this.msg = msg;
}

Season()
{
this.msg = "Cold";
}

public String getMessage()


{
return msg;
}
}
class Test12
{
public static void main(String[] args)
{
Season s1[] = Season.values();

for(Season x : s1)
System.out.println(x+" is :"+x.getMessage());
}
}

Note :- enum constructor we cann’t declare with public or protected because outside accessibility is not
allowed, it is meant for internal enum object only.
-----------------------------------------------------------------
enum MyType
{
ONE
{
@Override
public String toString()
{
return "this is one";
}
},
TWO
{
@Override
public String toString()
{
return "this is two";
}
}
}
public class Test13
{
public static void main(String[] args)
{
System.out.println(MyType.ONE);
System.out.println(MyType.TWO);

}
}
-----------------------------------------------------------------
package com.nit.oop;

enum Designation
{
HR
{
@Override
public String toString()
{
return "HR Post";
}

},

SALES
{
@Override
public String toString()
{
return "SALES Post";
}
}

public class TestEnum


{
public static void main(String[] args)
{
System.out.println(Designation.HR);
System.out.println(Designation.SALES);

}
-----------------------------------------------------------------
public class Test14
{
enum Day
{
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

public static void main(String args[])


{
Day day=Day.MONDAY;

switch(day)
{
case SUNDAY:
System.out.println("Sunday");
break;
case MONDAY:
System.out.println("Monday");
break;
default:
System.out.println("other day");
}

}
}
-----------------------------------------------------------------
Optional<T> class in Java :
------------------------
It is a predefined final and immutable class available in java.util package from java 1.8v.

It is a container object which is used to represent an object (Optional object) that may or may not contain
a non-null value.

If the value is available in the container, isPresent() method will return true and get() method will return
the actual value.

It is very useful in industry to avoid NullPointerException.

Methods of Optional<T> class :


-------------------------------
1) public static Optional<T> ofNullable(T x) :
-------------------------------------------
It will return the object of Optional class with specified value. If the specified value is null then this method
will return an empty object of the optional class.

2) public boolean isPresent() :


--------------------------------
It will return true, if the value is available in the container otherwise it will return false.

3) public T get() :
--------------------
It will get/fetch the value from the container, if the value is not available then it will throw
java.util.NoSuchElementException.
4) public T orElse(T defaultValue) :
-------------------------------------
It will return the value, if available otherwise it will return the specified default value.

5) public static Optional<T> of (T value) :


--------------------------------------------
It will return the optional object with the specified value that is non- null value.

6) public static Optional<T> empty() :


---------------------------------------
It will return an empty Optional Object.
-----------------------------------------------------------------
//Program to verify whether the container has value or not
package com.ravi.optional_class_demo;

import java.util.Optional;

public class OptionalDemo1


{
public static void main(String[] args)
{
String str = null;

Optional<String> optional = Optional.ofNullable(str);

String orElse = optional.orElse("No value in container");


System.out.println("Value by orElse :"+orElse);

//Optional is containing value or not?


if(optional.isPresent())
{
System.out.println("Value by get :"+optional.get());
}
else
{
System.err.println("No value is available in the container");
}

}
----------------------------------------------------------------
//Writing different style of getter
package com.ravi.optional_class_demo;
import java.util.Optional;
class Employee
{
private Integer empId;
private String empName;

public Employee() {}

public Employee(Integer empId, String empName)


{
super();
this.empId = empId;
this.empName = empName;
}

//Changing the style of writing getter method


public Optional<Integer> getEmpId()
{
return Optional.ofNullable(empId);
}

public Optional<String> getEmpName()


{
return Optional.ofNullable(empName);
}
}

public class OptionalDemo2


{
public static void main(String[] args)
{
//Employee emp = new Employee(111,"Ravi");
Employee emp = new Employee();

Optional<Integer> empId = emp.getEmpId();


if(empId.isPresent())
{
System.out.println(empId.get());
}
else
{
System.err.println("No id value ");
}

Optional<String> empName = emp.getEmpName();


if(empName.isPresent())
{
System.out.println(empName.get());
}
else
{
System.err.println("No name value ");
}

}
}
-----------------------------------------------------------------
//Program to verify value is available or not
package com.ravi.optional_class_demo;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class OptionalDemo3
{
public static void main(String[] args)
{
List<Optional<String>> optionalList = new ArrayList<>();

optionalList.add(Optional.of("Ameerpet"));
optionalList.add(Optional.of("S.R Nager"));
optionalList.add(Optional.of("Begumpet"));
optionalList.add(Optional.of("Koti"));
optionalList.add(Optional.empty());

for (Optional<String> optional : optionalList)


{
if (optional.isPresent())
{
System.out.println(optional.get());
}
else
{
System.out.println("No data is available");
}
}
}
}
-----------------------------------------------------------------

//Immutability of Optional class

package com.ravi.optional_class_demo;
import java.util.Optional;
public class OptionalDemo4
{
public static void main(String[] args)
{
Optional<String> optl = Optional.of("India");
System.out.println(optl.hashCode());

Optional<String> newOptnl = modifyOptional(optl);


System.out.println(newOptnl.hashCode());

// Check if the original Optional is still the same


System.out.println("Address is :" + (optl == newOptnl));

public static Optional<String> modifyOptional(Optional<String> optional)


{

if (optional.isPresent())
{
return Optional.of("Modified: " + optional.get());
}
else
{
return Optional.empty();
}
}
}

From the above program it is clear that Optional is immutable class.

----------------------------------------------------------------
15-03-2024
-----------
Sealed class in Java :
-----------------------
It is a new feature introduced from java 15.

It is an improvement over final keyword.

By using sealed keyword we can declare classes and interfaces as sealed.

It is one kind of restriction that describes which classes and interfaces can extends or implement from
Sealed class Or interface

It is similar to final keyword with less restriction because here we can permit the classes to extend from
the original Sealed class.

The class which is inheriting from the sealed class must be final, sealed or non-sealed modifiers.

The sealed class must have at-least one sub class.

We can also create object for Sealed class.

It provides the following modifier :

1) sealed : Can be extended only through permitted class.

2) non-sealed : Can be extended by any sub class, if a user wants to give permission to its sub classes

3) permits : We can provide permission to the sub classes, which are inheriting through Sealed class.

4) final : we can declare permitted sub class as final so, it cannot be extended further.
-----------------------------------------------------------------
package com.nit.oop;

sealed class Bird permits Parrot, Peacock


{
public void fly()
{
System.out.println("Generic Bird can fly");
}
}
non-sealed class Parrot extends Bird
{
@Override
public void fly()
{
System.out.println("Parrot Bird can fly");
}
}

final class Peacock extends Bird


{
@Override
public void fly()
{
System.out.println("Peacock Bird can fly");
}
}

public class SealedDemo {

public static void main(String[] args)


{
Bird b = null;
b = new Parrot(); b.fly();
b = new Peacock(); b.fly();

}
----------------------------------------------------------------
package com.nit.oop;

sealed class OnlineJavaClass permits Mobile,Laptop


{
public void attendClass()
{
System.out.println("Attend online class");
}
}

non-sealed class Mobile extends OnlineJavaClass


{
public void attendClass()
{
System.out.println("Attending Java class through Mobile");
}
}

final class Laptop extends OnlineJavaClass


{
public void attendClass()
{
System.out.println("Attending Java class through Laptop");
}
}

public class OnlineClass {

public static void main(String[] args)


{
OnlineJavaClass cls = null;
cls = new Mobile(); cls.attendClass();
cls = new Laptop(); cls.attendClass();

}
-----------------------------------------------------------------
Streams in java :
------------------
It is introduced from Java 8 onwards, the Stream API is used to process the collection objects.

It contains classes for processing sequence of elements over Collection object and array.

Stream is a predefined interface available in java.util.stream sub package.

Package Information :
---------------------
java.util -> Base package
java.util.function -> Functional interfaces
java.util.concurrent -> Multithreaded support
java.util.stream -> Processing of Collection Object

forEach() method in java :


-----------------------------
The Java forEach() method is a technique to iterate over a collection such as (list, set or map) and
stream. It is used to perform a given action on each of the element of the collection.

The forEach() method has been added in following places:

Iterable interface This makes Iterable.forEach() method available to all collection classes. Iterable
interface is the super interface of Collection interface

Map interface This makes forEach() operation available to all map classes.

Stream interface This makes forEach() operations available to all types of stream.
----------------------------------------------------------------------
Creation of Streams to process the data :
-----------------------------------------------
We can create Stream from collection or array with the help of stream() and of() methods:

A stream() method is added to the Collection interface and allows creating a Stream<T> using any
collection object as a source

public java.util.Stream<E> stream();

The return type of this method is Stream interafce available in java.util.stream sub package.

Eg:-
List<String> items = new ArrayList<String>();
items.add("Apple");
items.add("Orange");
items.add("Mango");
Stream<String> stream = items.stream();
-----------------------------------------------------------------
package com.ravi.basic;
import java.util.*; //Base package
import java.util.stream.*; //Sub package
public class StreamDemo1
{
public static void main(String[] args)
{
List<String> items = new ArrayList<>();

items.add("Apple");
items.add("Orange");
items.add("Mango");

//Collections Object to Stream


Stream<String> strm = items.stream();
strm.forEach(p -> System.out.println(p));
}
}
----------------------------------------------------------------
Stream.of()
--------------
public static java.util.stream.Stream of(<T>)
-----------------------------------------------------
It is a static method of Stream interface through which we can create Stream of arrays and Collection.
The return type of this method is Stream interface
--------------------------------------------------------------
//Stream.of()
package com.ravi.basic;
import java.util.stream.*;
public class StreamDemo2
{
public static void main(String[] args)
{
Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9);
stream.forEach(p -> System.out.println(p));

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

//Anonymous Array Object


Stream<Integer> strm = Stream.of( new Integer[]{15,29,45,8,16} );
strm.forEach(p -> System.out.println(p));
}
}
-----------------------------------------------------------------
Intermediate Operations:
------------------------
filter(Predicate<T> predicate): Returns a new stream which contains filtered elements based on the
boolean expression using Predicate.

map(Function<T, R> mapper): Transforms elements in the stream using the provided mapping function.

flatMap(Function<T, Stream<R>> mapper): Flattens a stream of streams into a single stream.


distinct(): Returns a stream with distinct elements (based on their equals method).

sorted(): Returns a stream with elements sorted in their natural order.

sorted(Comparator<T> comparator): Returns a stream with elements sorted using the specified
comparator.

peek(Consumer<T> action): Allows us to perform an action on each element in the stream without
modifying the stream.

limit(long maxSize): Limits the number of elements in the stream to a specified maximum size.

skip(long n): Skips the first n elements in the stream.

takeWhile(Predicate<T> predicate): Returns a stream of elements from the beginning until the first
element that does not satisfy the predicate.

dropWhile(Predicate<T> predicate): Returns a stream of elements after skipping elements at the


beginning that satisfy the predicate.
-----------------------------------------------------------------
public abstract Stream<T> filter(Predicate<T> p) :
----------------------------------------------------
It is a predfined method of Stream interface. It is used to select/filter elements as per the Predicate
passed as an argument. It is basically used to filter the elements based on boolean condition.

public abstract <T> collect(java.util.stream.Collectors c)


----------------------------------------------------------------
It is a predfined method of Stream interface. It is used to return the result of the intermediate operations
performed on the stream. It is used to collect the data after filteration and convert the data to the
Collection.

Collectors is a predfined final class available in java.util.stream sub package which conatins a static
method toList() and toSet() to convert the data as a List/Set i.e Collection object. The return type of this
method is List/Set interface.
----------------------------------------------------------------
//Filter all the even numbers from Collection
package com.ravi.basic;
import java.util.*;
import java.util.stream.*;
public class StreamDemo3
{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10,3, 10);

//Without Stream
List<Integer> listEven = new ArrayList<Integer>();

for(Integer i : list)
{
if(i%2==0)
listEven.add(i);
}
System.out.println(listEven);
System.out.println(".........................................");
//With Stream which prints only even numbers
List<Integer> even = list.stream().filter(i -> i%2 == 0).collect(Collectors.toList());
System.out.println(even);

//With Stream which prints only odd numbers


Set<Integer> odd = list.stream().filter(i -> i%2==1).collect(Collectors.toSet());
System.out.println(odd);
}
}
-----------------------------------------------------------------
//Filtering the name
package com.ravi.basic;
import java.util.*;
import java.util.stream.*;
public class StreamDemo4
{
public static void main(String[] args)
{
List<String> list = Arrays.asList("Ravi", "Rahul", "Akshar", "Roshan","Raj","Ankit","Ravi");

list.stream().filter(str -> str.startsWith("R")).sorted().distinct().forEach(System.out::println);

}
}
-----------------------------------------------------------------
//Sorting the data
package com.ravi.basic;
import java.util.*;
import java.util.stream.*;
public class StreamDemo5
{
public static void main(String[] args)
{
List<String> names = Arrays.asList("Zaheer","Rahul","Aryan","Sailesh");

List<String> sortedName =
names.stream().sorted().collect(Collectors.toList());

System.out.println(sortedName);
}
}
-----------------------------------------------------------------
package com.ravi.basic;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

record Customer(int cid, String cname, double custBill)


{

}
public class StreamDemo6
{
public static void main(String[] args)
{
ArrayList<Customer> al = new ArrayList<>();
al.add(new Customer(1, "A", 27000));
al.add(new Customer(2, "B", 37000));
al.add(new Customer(3, "C", 47000));
al.add(new Customer(4, "D", 57000));

List<Customer> collect = al.stream().filter(cust -> cust.custBill() > 30000).collect(Collectors.toList());


collect.forEach(System.out::println);

}
}
-----------------------------------------------------------------
public Stream map(Function<T,R> mapper) :
-------------------------------------------------
It is a predefined method of Stream interface.

It takes Function (Predefined functional interafce ) as a parameter.

It performs intermediate operation and consumes single element from input Stream and produces single
element to output Stream.

Here mapper function is functional interface which takes one input and provides one output.
-----------------------------------------------------------------
package com.ravi.basic;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Test {

public static void main(String[] args)


{
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

numbers.stream().map(n -> n*n*n).forEach(System.out::println);

}
}
----------------------------------------------------------------
//Find even numbers in stream and collect the cubes
package com.ravi.basic;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamDemo7


{
public static void main(String[] args)
{
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
listOfNumbers.stream().map(num -> num + 10).forEach(System.out::println);

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

List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

List<Integer> cubeOfNum = numbers.stream().filter(n -> n%2==0).map(x ->


x*x*x).collect(Collectors.toList());
System.out.println(cubeOfNum);

System.out.println("................");
List<String> listOfString = Arrays.asList("Raj","Rahul","Chandrashekhar",
"ArrayIndexOutOfBoundsException");

listOfString.stream().map(str -> str.length()).forEach(System.out::println);

}
}
----------------------------------------------------------------
//Program on map(Function<T,R> mapped)
package com.ravi.basic;
import java.util.*;
import java.util.stream.*;
public class StreamDemo8
{
public static void main(String args[])
{
List<Player> listOfPlayers = createMyPlayerList();

//List<Player> to Set<String>
Set<String> setOfNames = listOfPlayers.stream().map(p -> p.name()).collect(Collectors.toSet());
System.out.println(setOfNames);
}

public static List<Player> createMyPlayerList()


{
List<Player> listOfPlayers = new ArrayList<>();
listOfPlayers.add(new Player("Virat",32));
listOfPlayers.add(new Player("Rohit",33));
listOfPlayers.add(new Player("Shami",34));
listOfPlayers.add(new Player("Siraj",28));
listOfPlayers.add(new Player("Sarfaraj",26));
listOfPlayers.add(new Player("Virat",32));

return listOfPlayers;
}
}

record Player(String name, int age)


{

}
----------------------------------------------------------------
16-03-2024
-----------
public Stream flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
---------------------------------------------------------
It is a predefined method of Stream interface.

The map() method produces one output value for each input value in the stream. So if there are n
elements in the stream, map() operation will produce a stream of n output elements.

flatMap() is two step process i.e. map() + Flattening. It helps in converting Collection<Collection<T>> to
Collection<T> [to make flat i.e converting Collections of collection into single collection or merging of all
the collection]
----------------------------------------------------------------
//flatMap()
//map + Flattening [Converting Collections of collection into single collection]
package com.ravi.basic;
import java.util.*;
import java.util.stream.*;
public class StreamDemo9
{
public static void main(String[] args)
{
List<String> list1 = Arrays.asList("A","B","C");
List<String> list2 = Arrays.asList("D","E","F");
List<String> list3 = Arrays.asList("G","H","I");

List<List<String>> listOfLists = Arrays.asList(list1, list2, list3);

List<String> collect = listOfLists.stream().flatMap(list -> list.stream()).collect(Collectors.toList());


System.out.println(collect);
}
}
---------------------------------------------------------------
//Flattening of prime, even and odd number
package com.ravi.basic.flat_map;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FlatMapDemo1


{
public static void main(String[] args)
{
List<Integer> primeNumbers = Arrays.asList(5,7,11);
List<Integer> evenNumbers = Arrays.asList(2,4,6);
List<Integer> oddNumbers = Arrays.asList(1,3,5);

List<List<Integer>> listOfCollection = Arrays.asList(primeNumbers, evenNumbers, oddNumbers);

List<Integer> collect = listOfCollection.stream().flatMap(num ->


num.stream()).collect(Collectors.toList());
System.out.println(collect);

}
----------------------------------------------------------------
//Fetching first character using flatMap()
package com.ravi.basic.flat_map;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FlatMapDemo2


{
public static void main(String[] args)
{
List<String> asList = Arrays.asList("Jyoti","Ankit","Vaibhab","Aman");

List<Character> collect = asList.stream().flatMap(str ->


Stream.of(str.charAt(0))).collect(Collectors.toList());

System.out.println(collect);

}
----------------------------------------------------------------
package com.ravi.basic.flat_map;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Product
{
private Integer productId;
private List<String> listOfProducts;

public Product(Integer productId, List<String> listOfProducts) {


super();
this.productId = productId;
this.listOfProducts = listOfProducts;
}

public Integer getProductId() {


return productId;
}

public List<String> getListOfProducts() {


return listOfProducts;
}
}

public class FlatMapDemo3


{
public static void main(String[] args)
{

List<Product> listOfProduct = Arrays.asList(


new Product(1, Arrays.asList("Camera", "Mobile","Laptop")),
new Product(2, Arrays.asList("Bat", "Ball","Wicket")),
new Product(3, Arrays.asList("Chair", "Table","Lamp")),
new Product(4, Arrays.asList("Cycle", "Bike","Car"))

);

List<String> collect = listOfProduct.stream().flatMap(p ->


p.getListOfProducts().stream()).collect(Collectors.toList());
System.out.println(collect);

}
-----------------------------------------------------------------

Difference between map() and flatMap()


--------------------------------------
map() method transforms each element into another single element.

flatMap() transforms each element into a stream of elements and then flattens those streams into a single
stream.

We should use map() when you want a one-to-one transformation, and we should use flatMap() when
dealing with nested structures or when you need to produce multiple output elements for each input
element.
---------------------------------------------------------------
public Stream sorted() :
------------------------
It is a predefined method of Stream interface.
It provides default natural sorting order.
The return type of this methof is Stream.

//Sorting the data


package com.ravi.basic;
import java.util.*;
import java.util.stream.*;
public class StreamSortedDemo
{
public static void main(String[] args)
{
List<String> names = Arrays.asList("Zaheer","Rahul","Aryan","Sailesh");

List<String> sortedName =
names.stream().sorted().collect(Collectors.toList());
System.out.println(sortedName);
}
}
----------------------------------------------------------------

public Stream distinct() :


--------------------------
It is a predefined method of Stream interface.

If we want to return stream from another stream by removing all the duplicates then we should use
distinct() method.

package com.ravi.basic;
import java.util.stream.Stream;
public class StreamDemo10
{
public static void main(String[] args)
{
Stream<String> s = Stream.of("Virat", "Rohit", "Dhoni", "Virat", "Rohit","Aswin","Bumrah");
s.distinct().sorted().forEach(System.out::println);

}
----------------------------------------------------------------

public Stream<T> limit(long maxSize) :


----------------------------------------
It is a predefined method of Stream interface to work with sequence of elements.

The limit() method is used to limit the number of elements in a stream by providing maximum size.

It creates a new Stream by taking the data from original Stream.

Elements which are not in the range or beyond the range of specified limit will be ignored.
----------------------------------------------------------------
package com.ravi.basic;
import java.util.stream.Stream;
public class StreamDemo12
{
public static void main(String[] args)
{
Stream<String> s = Stream.of("Virat", "Rohit", "Dhoni", "Zaheer", "Raina");
s.limit(4).forEach(System.out::println);
}
}
----------------------------------------------------------------
public Stream<T> skip(long n) :
-------------------------------
It is a predefined method of Stream interface which is used to skip the elements from begning of the
Stream.

It returns a new stream that contains the remaining elements after skipping the specified number of
elements which is passed as a parameter.
package com.ravi.basic;
import java.util.stream.Stream;
public class StreamDemo12
{
public static void main(String[] args)
{
Stream<String> s = Stream.of("Virat", "Rohit", "Dhoni", "Zaheer", "Raina","Sahwag","Sachin","Bumrah");
s.skip(3).limit(4).forEach(System.out::println);
}
}
----------------------------------------------------------------
public Stream<T> peek(Consumer<? super T> action) :
--------------------------------------------
It is a predefined method of Stream interface which is used to perform a side-effect operation on each
element in the stream while the stream remains unchanged.

It is an intermediate operation that allows us to perform operation on each element of Stream without
modifying original.

The peek() method takes a Consumer as an argument, and this function is applied to each element in the
stream. The method returns a new stream with the same elements as the original stream.

package com.ravi.basic;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamDemo13


{
public static void main(String[] args)
{
Stream<String> numbers = Stream.of("Apple","Mango","Grapes","Kiwi","pomogranate");

List<Integer> doubledNumbers = numbers


.peek(str -> System.out.println("Peeking from Original: " + str.toUpperCase()))
.map(num -> num.length())
.collect(Collectors.toList());
System.out.println("-----------------");
System.out.println(doubledNumbers);

Note :- peek(Consumer<T> cons) will not modify the Original Source.


----------------------------------------------------------------
public Stream<T> takeWhile(Predicate<T> predicate) :
-----------------------------------------------------
It is a predefined method of Stream interface introduced from java 9 which is used to perform a side-effect
operation on each element in the stream while the stream remains unchanged.

*It is used to create a new stream that includes elements from the original stream only as long as they
satisfy a given predicate.
package com.ravi.basic;

import java.util.stream.Stream;

public class StreamDemo14


{
public static void main(String[] args)
{
Stream<Integer> numbers = Stream.of(10,11,9,13,2,1,100);

numbers.takeWhile(n -> n > 9).forEach(System.out::println);

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

numbers = Stream.of(12,2,3,4,5,6,7,8,9);

numbers.takeWhile(n -> n%2==0).forEach(System.out::println);

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

numbers = Stream.of(1,2,3,4,5,6,7,8,9);

numbers.takeWhile(n -> n < 9).forEach(System.out::println);

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

numbers = Stream.of(11,2,3,4,5,6,7,8,9);

numbers.takeWhile(n -> n > 9).forEach(System.out::println);

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

Stream<String> stream = Stream.of("Ravi", "Ankit", "Rohan", "Aman", "Ravish");

stream.takeWhile(str -> str.charAt(0)==’R’).forEach(System.out::println);

}
}
----------------------------------------------------------------
public Stream<T> dropWhile(Predicate<T> predicate) :
----------------------------------------------------
It is a predefined method of Stream interface introduced from java 9 which is used to create a new stream
by excluding elements from the original stream as long as they satisfy a given predicate.

package com.ravi.basic;

import java.util.stream.Stream;

public class StreamDemo15 {


public static void main(String[] args)
{
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

numbers.dropWhile(num -> num < 5).forEach(System.out::println);

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

numbers = Stream.of(15, 8, 7, 9, 5, 6, 7, 8, 9, 10);

numbers.dropWhile(num -> num > 5).forEach(System.out::println);

}
----------------------------------------------------------------
New Date and Time API :
-----------------------
LocalDate :
-----------
It is a predefined final class which represents only Date. The java.util.Date class is providing Date and
Time both so, only to get the Date we need to use LocalDate class available in java.time package.

LocalDate d = LocalDate.now();

Here now is a static method of LocalDate class and its return type is LocalDate class. (Factory Method)

LocalTime :
-----------
It is also a final class which will provide only time.
LocalTime d = LocalTime.now();

Here now is a static method of LocalTime class and its return type is LocalTime (Factory Method).

LocalDateTime :
----------------
It is also a final class which will provide Date and Time both without a time zone. It is a combination of
LocalDate and LocalTime class.
LocalDateTime d = LocalDateTime.now();

package com.ravi.new_date_time;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Demo1


{
public static void main(String[] args)
{
LocalDate d = LocalDate.now();
System.out.println(d);
LocalTime t = LocalTime.now();
System.out.println(t);

LocalDateTime dt = LocalDateTime.now();
System.out.println(dt);
}
}
----------------------------------------------------------------
ZonedDateTime :
---------------
It is a final class available in java.time package.

It is also provides date and time along with time zone so, by using this class we can work with different
time zone in a global way.

ZonedDateTime x = ZonedDateTime.now();
ZoneId zone = x.getZone();

getZone() is a predefined non static method of ZonedDateTime class which returns ZoneId class, this
ZoneId class provides the different zones, by using getAvailableZoneIds() static method we can find out
the total zone available using this ZoneId class.

package com.ravi.new_date_time;

import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Demo2


{

public static void main(String[] args)


{
ZonedDateTime z = ZonedDateTime.now();
System.out.println(z);

ZoneId zone = z.getZone();


System.out.println(zone);

System.out.println(ZoneId.getAvailableZoneIds());

}
----------------------------------------------------------------
Differenr of() static method :
------------------------------
List.of();
Stream.of();
Optional.of();
ZoneId.of();
---------------------------------------------------------------
package com.ravi.new_date_time;

import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Demo3


{
public static void main(String[] args)
{
ZoneId AusTimeZone = ZoneId.of("Australia/Hobart");
ZonedDateTime aus = ZonedDateTime.now(AusTimeZone);
System.out.println("Current Date and Time in Australia Time Zone: " + aus);
}
}
----------------------------------------------------------------
DateTimeFormatter :
-------------------
It is a predefined final class available in java.time.format sub package.

It is mainly used to formatting and parsing date and time objects according to Java Date and Time API.

Method :
--------
public static DateTimeFormatter ofPattern(String pattern) :

It is a static method of DateTimeFormatter class, It creates a


formatter using user specified String pattern ("dd-MM-yyyy HH:mm:ss")
and LocalDateTime class contains format method which takes
DateTimeFormatter as a parameter and returns the String value.

package com.ravi.new_date_time;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Demo4


{
public static void main(String[] args)
{
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-YYYY");

String formattedDateTime = now.format(formatter);


System.out.println("Formatted DateTime: " + formattedDateTime);
}
}
-----------------------------------------------------------------
Inner classes in java :
------------------------
In java it is possible to define a class (inner class) inside another class (outer class) called nested class.

In the same way it is also possible to define an interface OR enum OR Annotation inside another interface
OR enum OR Annotation is called inner class or nested class.

Inner classes in Java create a strong encapsulation and HAS-A relationship between the inner class and
its outer class.
An inner class, .class file will be represented by $ symbol.

Advantages of inner class :


--------------------------------
1) It helps us to logically divide the class and it’s respective code.

2) It is used to achieve encapsulation.

3) It enhance the readability and maintainability of the code.

-----------------------------------------------------------------
1) Member Inner class OR Nested Inner class OR Regular class :
-----------------------------------------------------------------
A non-static class that is created inside a class but outside of a method is called Member Inner class OR
Nested Inner class OR Regular class.

It can be declared with access modifiers like private, default, protected, public, abstract and final.

It is also called as Regular Inner class.

An inner class can also access the private member of outer class.

Note :- The .class file of an inner class will be represented by $ symbol at the time of compilation.

An outer class can be declared as public, abstract and final only.


----------------------------------------------------------------
package com.ravi.inner_class;

class Outer
{
private int x = 100;

public class Inner


{
private int y = 200;

public void show()


{
System.out.println(x);
System.out.println(y);
}

}
}
public class NestedDemo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();

//OR

Outer.Inner in = new Outer().new Inner();


in.show();
}

}
----------------------------------------------------------------
class MyOuter
{
private int x = 7;
public void makeInner()
{
MyInner in = new MyInner();
System.out.println("Inner y is "+in.y);
in.seeOuter();
}

class MyInner
{
private int y = 15;
public void seeOuter()
{
System.out.println("Outer x is "+x);
}
}
}
public class Test2
{
public static void main(String args[])
{
MyOuter m = new MyOuter();
m.makeInner();
}
}

Note : From the above program it is clear that an inner can access the private data of outer class as well
as an outer class can also access the private data of inner class.
-----------------------------------------------------------------
class MyOuter
{
private int x = 15;
class MyInner
{
public void seeOuter()
{
System.out.println("Outer x is "+x);
}
}
}
public class Test3
{
public static void main(String args[])
{
//Creating inner class object in a single line
MyOuter.MyInner m = new MyOuter().new MyInner();
m.seeOuter();
}
}
----------------------------------------------------------------
class MyOuter
{
static int x = 7;
class MyInner
{
public static void seeOuter() //MyInner.seeOuter();
{
System.out.println("Outer x is "+x);
}
}
}

public class Test4


{
public static void main(String args[])
{
MyOuter.MyInner.seeOuter();
}
}
-----------------------------------------------------------------
class Car
{
private String make;
private String model;
private Engine engine;

public Car(String make, String model, int horsePower)


{
this.make = make;
this.model = model;
this.engine = new Engine(horsePower);
}

//Inner class
private class Engine
{
private int horsePower;

public Engine(int horsePower)


{
this.horsePower = horsePower;
}

public void start()


{
System.out.println("Engine started! Horsepower: " + horsePower);
}

public void stop()


{
System.out.println("Engine stopped.");
}
}
public void startCar()
{
System.out.println("Starting " + make + " " + model);
this.engine.start();
}

public void stopCar()


{
System.out.println("Stopping " + make + " " + model);
this.engine.stop();
}
}
public class Test5
{

public static void main(String[] args) {

Car myCar = new Car("Swift", "Desire", 1200);

myCar.startCar();

myCar.stopCar();
}
}

Note :- In the above example Car object is interacting with Engine object.
-----------------------------------------------------------------
class Laptop
{
private String brand;
private String model;
private Motherboard motherboard;

public Laptop(String brand, String model, String motherboardModel, String chipset)


{
this.brand = brand;
this.model = model;
this.motherboard = new Motherboard(motherboardModel, chipset);
}

public void switchOn()


{
System.out.println("Turning on " + brand + " " + model);
this.motherboard.boot();
}

//Motherboard inner class


public class Motherboard
{
private String model;
private String chipset;
public Motherboard(String model, String chipset)
{
this.model = model;
this.chipset = chipset;
}

public void boot()


{
System.out.println("Booting " + brand + " " + model + " with " + chipset + " chipset");
}
}
}
public class Test6
{
public static void main(String[] args)
{

Laptop laptop = new Laptop("HP", "ENVY", "IRIS", "Intel");

laptop.switchOn();
}
}
-----------------------------------------------------------------
class Person
{
private String name;
private int age;
private Heart heart;

public Person(String name, int age)


{
this.name = name;
this.age = age;
this.heart = new Heart();
}

public void describe()


{
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Heart beats per minute: " + heart.getBeatsPerMinute());
}

// Inner class representing the Heart


private class Heart
{
private int beatsPerMinute;

public Heart() {
this.beatsPerMinute = 72;
}

public int getBeatsPerMinute()


{
return this.beatsPerMinute;
}

public void setBeatsPerMinute(int beatsPerMinute)


{
this.beatsPerMinute = beatsPerMinute;
}
}
}
public class Test7
{
public static void main(String[] args)
{
Person person = new Person("Virat", 30);
person.describe();
}
}
-----------------------------------------------------------------
class University
{
private String name;

public University(String name)


{
this.name = name;
}

public void displayUniversityName()


{
System.out.println("University Name: " + name);
}

public class Department


{
private String name;
private String headOfDepartment;

public Department(String name, String headOfDepartment)


{
this.name = name;
this.headOfDepartment = headOfDepartment;
}

// Method to display department details


public void displayDepartmentDetails()
{
System.out.println("Department Name: " + name);
System.out.println("Head of Department: " + headOfDepartment);
displayUniversityName();
}
}
}
public class Test8
{
public static void main(String[] args)
{

University university = new University("JNTU");

University.Department cs = university.new Department("Computer Science", "Dr. John");

University.Department ee = university.new Department("Electrical Engineering", "Dr. Scott");

cs.displayDepartmentDetails();
ee.displayDepartmentDetails();
}
}
----------------------------------------------------------------
class OuterClass
{
private int x = 200;
class InnerClass
{
public void display() //Inner class display method
{
System.out.println("Inner class display method");
}

public void getValue()


{
display();
System.out.println("Can access outer private var :"+x);
}
}

public void display() //Outer class display method


{
System.out.println("Outer class display");
}
}
public class Test9
{
public static void main(String [] args)
{
OuterClass.InnerClass inobj = new OuterClass().new InnerClass();
inobj.getValue();

new OuterClass().display();
}
}
----------------------------------------------------------------
class OuterClass
{
int x;
final class InnerClass //private, def, prot, public, abstract & final
{
int x;
}
}
public class Test10
{
}
-----------------------------------------------------------------
2) Method local inner class :
-------------------------------
If a class is declared inside the method then it is called method local inner class.

We cann’t apply any access modifier on method local inner class but they can be marked as abstract and
final.

A local inner class we can’t access outside of the method that means the scope of method local inner
class within the same method only.

package com.ravi.has_a_reln;

class Outer
{
private String str = "Outer Data";

public void access()


{
class Local
{
String str = "Local class Data";

public void accessOuter()


{
System.out.println(Outer.this.str);
System.out.println(str);
}
}
new Local().accessOuter();
}
}

public class Test11 {

public static void main(String[] args)


{
new Outer().access();
}

}
----------------------------------------------------------------
//local inner class we can’t access outside of the method
class MyOuter3
{
private String x = "Outer class Data";

public void doSttuff()


{
String z = "local variable";
class MyInner
{
String z = "CLASS variable";
public void seeOuter()
{
System.out.println("Outer x is "+x);
System.out.println("Local variable z is : "+z);
}
}
}
MyInner mi = new MyInner();
mi.seeOuter();

}
public class Test12
{
public static void main(String args[])
{
MyOuter3 m = new MyOuter3();
m.doSttuff();
}
}
----------------------------------------------------------------
3) Static Nested Inner class :
---------------------------------
A static inner class which is declared with static keyword inside an outer class is called static Nested inner
class.

It cann’t access non-static variables and methods i.e (instance members) of outer class.

For static nested inner class, Outer class object is not required.

If a static nested inner class contains static method then object is not required for inner class. On the
other hand if the static inner class contains instance method then we need to create an object for static
nested inner class.

//static nested inner class


class BigOuter
{
static class Nest //static nested inner class
{
void go() //Instance method of static inner class
{
System.out.println("Hello welcome to static nested class");
}
}
}
class Test13
{
public static void main(String args[])
{
BigOuter.Nest n = new BigOuter.Nest();
n.go();
}
}
----------------------------------------------------------------
class Outer
{
static int x=15;

static class Inner


{
void msg()
{
System.out.println("x value is "+x);
}
}
}
class Test14
{
public static void main(String args[])
{
Outer.Inner obj=new Outer.Inner();
obj.msg();
}
}
-----------------------------------------------------------------
class Outer
{
static int x = 25;
static class Inner
{
static void msg()
{
System.out.println("x value is "+x);
}
}
}
class Test15
{
public static void main(String args[])
{
Outer.Inner.msg();
}
}
-----------------------------------------------------------------
class Outer
{
int x=15; //error (not possible because try to access instance variable)
static class Inner
{
void msg()
{
System.out.println("x value is "+x);
}
}
}
class Test16
{
public static void main(String args[])
{
Outer.Inner obj=new Outer.Inner();
obj.msg();
}
}
-----------------------------------------------------------------
4) Anonymous inner class :
------------------------------
It is an inner class which is defined inside a method without any name and for this kind of inner class only
single Object is created. (Singleton class)

An anonymous inner class is mainly used for extending a class or implementing an interface that means
creating sub type of a class or interface.

*A normal class can implement any number of interfaces but an anonymous inner class can implement
only one interface at a time.

A normal class can extend one class and implement any number of interfaces at the same time but an
anonymous inner class can extend one class or can implement one interface at a time.

Inside an anonymous inner class we can write static , non static variable, static block and non-static
block. Here we can’t write abstract method and constructor.

//Anonymous inner class


class Tech
{
public void tech()
{
System.out.println("Tech");
}
}
public class Test17
{
public static void main(String... args)
{
Tech a = new Tech() //Anonymous inner class
{
@Override
public void tech()
{
System.out.println("anonymous tech");
}
};
a.tech();
}
}
-----------------------------------------------------------------
@FunctionalInterface
interface Vehicle
{
void move(); //SAM(Single Abstract Method)
}
class Test18
{
public static void main(String[] args)
{
Vehicle car = new Vehicle()
{
@Override
public void move()
{
System.out.println("Moving with Car...");
}
};
car.move();

Vehicle bike = new Vehicle()


{
@Override
public void move()
{
System.out.println("Moving with Bike...");
}
};
bike.move();
}
}
----------------------------------------------------------------
class Test19
{
public static void main(String[] args)
{
//Anonymous class with Runnable
Runnable r1 = new Runnable()
{

@Override
public void run()
{
System.out.println("Run method implementation inside Runnable");
}
};
Thread obj = new Thread(r1);
obj.start();

//Anonymous Thread class with reference


Thread t1 = new Thread()
{
@Override
public void run()
{
System.out.println("Anonymous Thread class with reference...");
}
};
t1.start();

//Anonymous Thread class without reference


new Thread()
{
@Override
public void run()
{
System.out.println("Anonymous Thread class without reference...");
}
}.start();
}
}
-----------------------------------------------------------------

Method Reference :
------------------
It is a new feature introduced from java 1.8 onwards.

It is mainly used to write concise coding.

By using method reference we can refer an existing method which is available at API level or Project
level.

We can use this technique in the body of Lambda expression just to call method defination.

The enitire method body will be automatically placed into Lambda Expression.

It is used to enhance the code reusability.

It uses :: (Double Colon Operator)

Method Reference Examples :


----------------------------
MethodRef.java
----------------
package com.ravi.method_ref;

interface Worker
{
void work();
}

class Employee
{
public void work()
{
System.out.println("Employee is working");
}
}

public class MethodRef {


public static void main(String[] args)
{
//By using Lambda
Worker w1 = ()-> System.out.println("Worker is working");
w1.work();

//By using method reference


Worker w2 = new Employee()::work;
w2.work();

}
---------------------------------------------------------------
package com.ravi.method_ref;

interface Worker
{
void work();
}

class Employee
{
public static void salary()
{
System.out.println("Employee Salary");
}
}

public class MethodRef {

public static void main(String[] args)


{
Worker w1 = Employee::salary;
w1.work();

}
----------------------------------------------------------------
package com.ravi.method_ref;

interface Worker
{
void work(double salary);
}

class Employee
{

public static void salary()


{
System.out.println("Employee Salary");
}
public static void salary(double salary)
{
System.out.println("Scott Salary :"+salary);
}
}

public class MethodRef {

public static void main(String[] args)


{
Worker w1 = Employee::salary;
w1.work(23000);

}
----------------------------------------------------------------
There are 4 types of method reference

1) Static Method Reference(ClassName::methodName)


2) Instance Method Reference(objectReference::methodName)
3) Constructor Reference (ClassName::new)
4) Arbitrary Referenec (ClassName::instanceMethodName)

Programs on above references :


------------------------------
Program on static method Reference :
-------------------------------------
package com.ravi.static_method_reference;

import java.util.Vector;

class EvenOrOdd
{
public static void isEven(int number)
{
if (number % 2 == 0)
{
System.out.println(number + " is even");
}
else
{
System.out.println(number + " is odd");
}
}
}
public class StaticMethodReferenceDemo1
{
public static void main(String[] args)
{
Vector<Integer> numbers = new Vector<>();
numbers.add(5);
numbers.add(2);
numbers.add(9);
numbers.add(12);
System.out.println("By using Lambda....");
numbers.forEach(x -> EvenOrOdd.isEven(x));

System.out.println("_______________________________");

System.out.println("By using static method reference");


numbers.forEach(EvenOrOdd::isEven);
}
}
-----------------------------------------------------------------
2)Instance Method Reference
----------------------------
package com.ravi.instance_method_reference;

interface Trainer
{
void getTraining(String name, int experience);
}

class InstanceMethod
{
public void getTraining(String name, int experience)
{
System.out.println("Trainer name is :"+name+" having "+experience+" years of experience.");
}
}

public class InstanceMethodReferenceDemo


{
public static void main(String[] args)
{
//Using Lambda Expression
Trainer t1 = (name, exp)-> System.out.println("Trainer name is :"+name+" and total experience is
:"+exp);
t1.getTraining("Smith", 5);

//By using Method reference


Trainer t2 = new InstanceMethod()::getTraining;
t2.getTraining("Scott", 10);

}
}

----------------------------------------------------------------
3) Constructor Reference (ClassName::new)
-----------------------------------------
package com.ravi.constructor_reference;
@FunctionalInterface
interface A
{
Test createObject();
}

class Test
{
public Test()
{
System.out.println("Test class Constructor invoked");
}
}
public class ConstructorReferenceDemo1
{
public static void main(String[] args)
{
//By using Lambda
A a1 = ()-> new Test();

a1.createObject();

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

//By Using Method Reference


A a2 = Test::new; //calling Test class constructor
a2.createObject();
}
}
----------------------------------------------------------------
package com.ravi.constructor_reference;

import java.util.function.Function;

class MyClass
{
private int value;

public MyClass(int value)


{
this.value = value;
}

public int getValue()


{
return this.value;
}
}

public class ConstructorReferenceDemo2


{
public static void main(String[] args)
{
Function<Integer, MyClass> constructorRef = MyClass::new;
MyClass obj = constructorRef.apply(10);

System.out.println("Value: " + obj.getValue());


}
}

---------------------------------------------------------------
//Array Constructor Reference

package com.ravi.constructor_reference;

import java.util.Scanner;
import java.util.function.Function;

class Person
{
private String name;

public Person(String name)


{
this.name = name;
}

public String getName()


{
return name;
}
}

public class ConstructorReferenceDemo3


{
public static void main(String[] args) {

Function<Integer, Person[]> arrayConstructorRef = Person[]::new;

Person[] people = arrayConstructorRef.apply(5); //5 is size of Array

Scanner sc = new Scanner(System.in);

for (int i = 0; i < people.length; i++)


{
System.out.println("Enter person name at "+i+" position :");
String name = sc.nextLine();
people[i] = new Person(name);
}

System.out.println("Names of people:");
for (Person person : people)
{
System.out.println(person.getName());
}
}
}
---------------------------------------------------------------
Arbitrary Reference :(ClassName::instanceMethodName)
-----------------------------------------------------
Reference to an instance method of an arbitrary object of a
particular type.

Lambda Expression Method Reference


------------------- -----------------
s -> s.length(); String::length;
s -> s.toUpperCase(); String::toUpperCase;
(i1,i2)-> i1.compareTo(i2); Integer::compareTo
(s1,s2)-> s1.compareTo(s2); String::compareTo
----------------------------------------------------------------
package com.ravi.arbitary_reference;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ArbitaryRefDemo1


{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(9,5,3,7,2);

//By using Lambda


Collections.sort(list,(i1,i2)->i1.compareTo(i2));
list.forEach(System.out::println);

//By Arbitrary Reference


Collections.sort(list,Integer::compareTo);
list.forEach(System.out::println);

String[] stringArray = { "Virat","Rohit","Ajinkya","Dhoni","Aswin"};


Arrays.sort(stringArray, String::compareTo);
System.out.println(Arrays.toString(stringArray));

}
}
---------------------------------------------------------------
package com.ravi.arbitary_reference;

import java.util.Arrays;

class Person
{
String name;

public Person(String name)


{
this.name = name;
}

public int personInstanceMethod1(Person person)


{
return this.name.compareTo(person.name);
}

@Override
public String toString() {
return "Person [name=" + name + "]";
}

public class ArbitraryRefDemo2


{
public static void main (String[] args) throws Exception
{
Person[] personArray = {new Person("C"),new Person("B"), new Person("A")};
Arrays.sort(personArray, Person::personInstanceMethod1);

System.out.println(Arrays.toString(personArray));

Note : Any instance method we can refere by using the class name
which known as Arbitrary method reference.
-----------------------------------------------------------------

You might also like