Java English Medium Book - 2
Java English Medium Book - 2
Remember these important things about printf: // declare and initialize two variables
Everything you want to print should be kept inside int a = 1;
parentheses (). int b = 3;
The text to be printed is enclosed within double
// print the output
quotes "".
System.out.println("This is output");
Each System.out.println() statement ends with a
semicolon ;. Here, we have used two single-line comments:
Not following the above rules will result in errors and // declare and initialize two variables
your code will not run successfully.
// print the output
The Java compiler ignores everything from // to the Comments make our code readable for future
end of line. Hence, it is also known as End of reference.
Line comment. Comments are used for debugging purposes.
We can use comments for code collaboration as it
Multi-line Comment helps peer developers to understand our code.
When we want to write comments in multiple lines,
we can use the multi-line comment. To write multi- Note: Comments are not and should not be used as a
line comments, we can use the /*....*/ symbol. For substitute to explain poorly written code. Always try
example, to write clean, understandable code, and then use
comments as an addition.
/* This is an example of multi-line comment. In most cases, always use comments to explain 'why'
* The program prints "Hello, World!" to the rather than 'how' and you are good to go.
standard output.
*/
class HelloWorld {
Java Fundamentals
public static void main(String[] args) {
Java Variables and Literals
System.out.println("Hello, World!"); In the previous tutorial you learnt about Java
} comments. Now, let's learn about variables and literals
} in Java.
byte range;
6. double type char letter1 = '9';
The double data type is a double-precision 64-bit System.out.println(letter1); // prints 9
floating-point.
It should never be used for precise values such as char letter2 = 65;
currency. System.out.println(letter2); // prints A
Default value: 0.0 (0.0d)
}
Example 6: Java double data type }
class Main {
public static void main(String[] args) { Here, we have assigned 9 as a character (specified by
single quotes) to the letter1 variable. However,
double number = -42.3; the letter2 variable is assigned 65 as an integer
System.out.println(number); // prints -42.3 number (no single quotes).
}
Hence, A is printed to the output. It is because Java
}
treats characters as an integer and the ASCII value
7. float type of A is 65.
The float data type is a single-precision 32-bit floating-
point. Learn more about single-precision and double-
precision floating-point if you are interested. String type
It should never be used for precise values such as Java also provides support for character strings
currency. via java.lang.String class. Strings in Java are not
Default value: 0.0 (0.0f) primitive types. Instead, they are objects. For example,
String myString = "Java Programming";
Example 7: Java float data type Here, myString is an object of the String class.
class Main {
public static void main(String[] args) { Java Operators
Operators are symbols that perform operations on
float number = -42.3f; variables and values. For example, + is an operator
System.out.println(number); // prints -42.3
used for addition, while * is also an operator used for
}
} multiplication.
Operators in Java can be classified into 5 types:
1. Arithmetic Operators
Notice that we have used -42.3f instead of -42.3 in the
2. Assignment Operators
above program. It's because -42.3 is a double literal. 3. Relational Operators
To tell the compiler to treat -42.3 as float rather 4. Logical Operators
than double , you need to use f or F . 5. Unary Operators
6. Bitwise Operators
8. char type
It's a 16-bit Unicode character. 1. Java Arithmetic Operators
The minimum value of the char data type Arithmetic operators are used to perform arithmetic
operations on variables and data. For example,
is '\u0000' (0) and the maximum value of the
a+b;
is '\uffff' . Here, the + operator is used to add two
Default value: '\u0000' variables a and b . Similarly, there are various other
arithmetic operators in Java.
Example 8: Java char data type
class Main { Operator Operation
public static void main(String[] args) {
+ Addition
- Subtraction
char letter = '\u0051';
* Multiplication
System.out.println(letter); // prints Q
} / Division
} % Modulo Operation (Remainder
after division)
Here, the Unicode value of Q is \u0051. Hence, we
Example 1: Arithmetic Operators
get Q as the output. class Main {
Here is another example: public static void main(String[] args) {
class Main {
public static void main(String[] args) { // declare variables
int a = 12, b = 5;
+= a += b; a = a + b;
// addition operator -= a -= b; a = a - b;
System.out.println("a + b = " + (a + b)); *= a *= b; a = a * b;
/= a /= b; a = a / b;
// subtraction operator %= a %= b; a = a % b;
System.out.println("a - b = " + (a - b));
Example 2: Assignment Operators
// multiplication operator class Main {
System.out.println("a * b = " + (a * b)); public static void main(String[] args) {
// && operator
System.out.println((5 > 3) && (8 > 5)); // true Example 5: Increment and Decrement Operators
System.out.println((5 > 3) && (8 < 5)); // false class Main {
public static void main(String[] args) {
// || operator
System.out.println((5 < 3) || (8 > 5)); // true // declare variables
System.out.println((5 > 3) || (8 < 5)); // true int a = 12, b = 12;
System.out.println((5 < 3) || (8 < 5)); // false int result1, result2;
// original value // checks if str is an instance of
System.out.println("Value of a: " + a); // the String class
result = str instanceof String;
// increment operator System.out.println("Is str an object of String? " +
result1 = ++a; result);
System.out.println("After increment: " + result1); }
}
System.out.println("Value of b: " + b);
Output
// decrement operator Is str an object of String? true
result2 = --b; Here, str is an instance of the String class. Hence, the
System.out.println("After decrement: " + result2); instanceof operator returns true.
}
} Java Ternary Operator
The ternary operator (conditional operator) is
Output shorthand for the if-then-else statement. For example,
Value of a: 12 variable = Expression ? expression1 : expression2
After increment: 13
Value of b: 12 Here's how it works.
After decrement: 11 If the Expression is true, expression1 is assigned to
the variable.
In the above program, we have used the ++ and -- If the Expression is false, expression2 is assigned to
operator as prefixes (++a, --b). We can also use these the variable.
operators as postfix (a++, b++). Let's see an example of a ternary operator.
There is a slight difference when these operators are class Java {
used as prefix versus when they are used as a postfix. public static void main(String[] args) {
Double number = -10.6; Example: Get Integer Input From the User
import java.util.Scanner;
System.out.println(5);
System.out.println(number); class Input {
} public static void main(String[] args) {
}
Scanner input = new Scanner(System.in);
When you run the program, the output will be:
5 System.out.print("Enter an integer: ");
-10.6 int number = input.nextInt();
System.out.println("You entered " + number);
Here, you can see that we have not used the quotation
marks. It is because to display integers, variables and // closing the scanner object
so on, we don't use quotation marks. input.close();
}
Example: Print Concatenated Strings }
class PrintVariables {
public static void main(String[] args) { Output:
Enter an integer: 23
Double number = -10.6; You entered 23
In the above example, notice the line, Note: We have used the close() method to close the
System.out.println("I am " + "awesome."); object. It is recommended to close the scanner object
Here, we have used the + operator to concatenate once the input is taken.
(join) the two strings: "I am " and "awesome.".
And also, the line, Example: Get float, double and String Input
System.out.println("Number = " + number); import java.util.Scanner;
Here, first the value of variable number is evaluated.
Then, the value is concatenated to the string: "Number class Input {
= ". public static void main(String[] args) {
Java Input Scanner input = new Scanner(System.in);
Java provides different ways to get input from the
user. However, in this tutorial, you will learn to get // Getting float input
input from user using the object of Scanner class. System.out.print("Enter float: ");
In order to use the object of Scanner , we need to float myFloat = input.nextFloat();
import java.util.Scanner package. System.out.println("Float entered = " + myFloat);
// statement
This is a valid Java program. Here, we have a block if int number = 10;
{...} . However, there is no any statement inside this
block. // checks if number is less than 0
if (number < 0) {
class AssignmentOperator {
System.out.println("The number is negative."); }
public static void main(String[] args) { // start of
block System.out.println("Statement outside if block"); }}
class Main {
if (condition1) {
public static void main(String[] args) {
// codes}
int number = 10;
else if(condition2) {
// checks if number is greater than 0
// codes}
if (number > 0) {
else if (condition3) {
System.out.println("The number is positive."); }
// codes}
// execute this block
else {
// if number is not greater than 0
// codes}
else {
Here, if statements are executed from the top towards
System.out.println("The number is not positive."); the bottom. When the test condition is true , codes
}
inside the body of that if block is executed. And,
System.out.println("Statement outside if...else program control jumps outside the if...else...if ladder.
block"); If all test expressions are false , codes inside the body
of else are executed.
}}
How the if...else...if ladder works?
Output
Output else {
The number is 0.
largest = n3;
In the above example, we are checking
whether number is positive, negative, or zero. Here, }}
we have two condition expressions:
number > 0 - checks if number is greater than 0 System.out.println("Largest Number: " + largest);
number < 0 - checks if number is less than 0
Here, the value of number is 0 . So both the }}
conditions evaluate to false . Hence the statement
inside the body of else is executed.
Output:
Note: Java provides a special operator called ternary
operator, which is a kind of shorthand notation Largest Number: 4.5
of if...else...if statement. In the above programs, we have assigned the value
of variables ourselves to make this easier.
However, in real-world applications, these values may
come from user input data, log files, form submission,
4. Java Nested if..else Statement
etc.
In Java, it is also possible to use if..else statements
inside an if...else statement. It's called the
nested if...else statement. Java Ternary Operator
Here's a program to find the largest of 3 numbers using In Java, a ternary operator can be used to replace
the nested if...else statement. the if…else statement in certain situations.
Example 5: Nested if...else Statement
Ternary Operator in Java
class Main { A ternary operator evaluates the test condition and
executes a block of code based on the result of the
public static void main(String[] args) { condition.
Its syntax is:
// declaring double type variables condition ? expression1 : expression2;
Here, condition is evaluated and
if condition is true, expression1 is executed. Here, both programs give the same output. However,
And, if condition is false, expression2 is executed. the use of the ternary operator makes our code more
readable and clean.
The ternary operator takes 3
operands (condition, expression1, and expression2). Note: You should only use the ternary operator if the
Hence, the name ternary operator. resulting statement is short.
Example: Java Ternary Operator
import java.util.Scanner;
class Main { Nested Ternary Operators
public static void main(String[] args) { It is also possible to use one ternary operator inside
// take input from users another ternary operator. It is called the nested ternary
Scanner input = new Scanner(System.in); operator in Java.
System.out.println("Enter your marks: "); Here's a program to find the largest of 3 numbers using
double marks = input.nextDouble(); the nested ternary operator.
// ternary operator checks if class Main {
// marks is greater than 40 public static void main(String[] args) {
String result = (marks > 40) ? "pass" : "fail"; // create a variable
System.out.println("You " + result + " the exam."); int n1 = 2, n2 = 9, n3 = -11;
input.close(); // nested ternary operator
}} // to find the largest number
Output 1 int largest = (n1 >= n2) ? ((n1 >= n3) ? n1 : n3) :
Enter your marks: ((n2 >= n3) ? n2 : n3);
75 System.out.println("Largest Number: " + largest);
You pass the exam. }}
Suppose the user enters 75. Then, the condition marks Output
> 40 evaluates to true. Hence, the first Largest Number: 9
expression "pass" is assigned to result. In the above example, notice the use of the ternary
operator,
Output 2 (n1 >= n2) ? ((n1 >=n3) ? n1 : n3) : ((n2 >= n3) ? n2 :
Enter your marks: n3);
24 Here,
You fail the exam. (n1 >= n2) - first test condition that checks if n1 is
Now, suppose the user enters 24. Then, the greater than n2
(n1 >= n3) - second test condition that is executed if
condition marks > 40 evaluates to false. Hence, the
the first condition is true
second expression "fail" is assigned to result. (n2 >= n3) - third test condition that is executed if the
first condition is false
When to use the Ternary Operator?
In Java, the ternary operator can be used to replace
certain types of if...else statements. For example, Note: It is not recommended to use nested ternary
You can replace this code operators. This is because it makes our code more
class Main { complex.
public static void main(String[] args) {
// create a variable
int number = 24;
Java for Loop
if(number > 0) { In computer programming, loops are used to repeat a
block of code. For example, if you want to show a
System.out.println("Positive Number"); }
else { message 100 times, then rather than typing the same
System.out.println("Negative Number"); }}} code 100 times, you can use a loop.
With In Java, there are three types of loops.
class Main { for loop
public static void main(String[] args) { while loop
// create a variable do...while loop
int number = 24; This tutorial focuses on the for loop. You will learn
String result = (number > 0) ? "Positive Number" : about the other types of loops in the upcoming
"Negative Number"; tutorials.
System.out.println(result); }}
Java for Loop
Output Java for loop is used to run a block of code for a
Positive Number certain number of times. The syntax of for loop is:
for (initialExpression; testExpression;
updateExpression) {
// body of the loop } 4
Here, 5
1. The initialExpression initializes and/or Here is how the program works.
declares variables and executes only once. Iteration Variable Condition: i Action
2. The condition is evaluated. If the condition is true, 1st i=1 true 1 is printed. i is
the body of the for loop is executed. n=5 increased to 2.
3. The updateExpression updates the value 2nd i=2 true 2 is printed. i is
n=5 increased to 3.
of initialExpression.
3rd i=3 true 3 is printed. i is
4. The condition is evaluated again. The process n=5 increased to 4.
continues until the condition is false. 4th i=4 true 4 is printed. i is
n=5 increased to 5.
Example 1: Display a Text Five Times 5th i=5 true 5 is printed. i is
// Program to print a text 5 times n=5 increased to 6.
class Main { 6th i=6 false The loop is
public static void main(String[] args) { n=5 terminated.
int n = 5;
// for loop Example 3: Display Sum of n Natural Numbers
for (int i = 1; i <= n; ++i) { // Program to find the sum of natural numbers from 1
System.out.println("Java is fun"); }}} to 1000.
Output class Main {
Java is fun public static void main(String[] args) {
Java is fun int sum = 0;
Java is fun int n = 1000;
Java is fun // for loop
Java is fun for (int i = 1; i <= n; ++i) {
Here is how this program works. // body inside for loop
Iteration Variable Condition: i Action sum += i; // sum = sum + i
1st i=1 true Java is fun }
n=5 is printed. i System.out.println("Sum = " + sum); }}
is increased
to 2. Output:
2nd i=2 true Java is fun Sum = 500500
n=5 is printed. i
is increased Here, the value of sum is 0 initially. Then, the for loop
to 3.
is iterated from i = 1 to 1000. In each iteration, i is
3rd i=3 true Java is fun
n=5 is printed. i added to sum and its value is increased by 1.
is increased When i becomes 1001, the test condition
to 4. is false and sum will be equal to 0 + 1 + 2 + .... +
4th i=4 true Java is fun 1000.
n=5 is printed. i The above program to add the sum of natural numbers
is increased can also be written as
to 5. // Program to find the sum of natural numbers from 1
5th i=5 true Java is fun to 1000.
n=5 is printed. i
is increased class Main {
to 6. public static void main(String[] args) {
6th i=6 false The loop is
n=5 terminated. int sum = 0;
int n = 1000;
Example 2: Display numbers from 1 to 5
// Program to print numbers from 1 to 5 // for loop
class Main { for (int i = n; i >= 1; --i) {
public static void main(String[] args) { // body inside for loop
int n = 5; sum += i; // sum = sum + i
// for loop }
for (int i = 1; i <= n; ++i) {
System.out.println(i); }}} System.out.println("Sum = " + sum);
Output }
1 }
2 The output of this program is the same as the Example
3 3.
item - each item of array/collection is assigned to this
Java for-each Loop variable
The Java for loop has an alternative syntax that makes dataType - the data type of the array/collection
it easy to iterate through arrays and collections. For
example, Example 1: Print Array Elements
// print array elements // print array elements
System.out.println("Enter a number");
number = input.nextInt(); Flowchart of Java do while loop
}
System.out.println("Sum = " + sum); Let's see the working of do...while loop.
input.close();
Example 3: Display Numbers from 1 to 5
}
// Java Program to display numbers from 1 to 5
}
import java.util.Scanner;
Output
Enter a number // Program to find the sum of natural numbers from 1
25 to 100.
Enter a number
9 class Main {
Enter a number public static void main(String[] args) {
5
Enter a number int i = 1, n = 5;
-3
Sum = 39 // do...while loop from 1 to 5
In the above program, we have used the Scanner do {
class to take input from the user. Here, nextInt() takes System.out.println(i);
integer input from the user. i++;
The while loop continues until the user enters a } while(i <= n);
negative number. During each iteration, the number }
entered by the user is added to the sum variable. }
When the user enters a negative number, the loop Output
terminates. Finally, the total sum is displayed. 1
2 Sum = 39
3 Here, the user enters a positive number, that number is
4 added to the sum variable. And this process continues
5 until the number is negative. When the number is
Here is how this program works. negative, the loop terminates and displays the sum
Iteration Variable Condition: i without adding the negative number.
Action Output 2
i=1n=5 not 1 is printed. Enter a number
checked i is -8
increased to Sum is 0
2. Here, the user enters a negative number. The test
1st i=2n=5 true 2 is condition will be false but the code inside of the loop
printed. i is executes once.
increased to
3. Infinite while loop
2nd i=3n=5 true 3 is printed. If the condition of a loop is always true, the loop runs
i is for infinite times (until the memory is full). For
increased to example,
4. // infinite while loop
3rd i=4n=5 true 4 is printed. while(true){
i is // body of loop
increased to }
5.
4th i=5n=5 true 5 is printed. Here is an example of an infinite do...while loop.
i is
// infinite do...while loop
increased to int count = 1;
6.
do {
// body of loop
Example 4: Sum of Positive Numbers } while(count == 1)
// Java program to find the sum of positive numbers In the above programs, the textExpression is
import java.util.Scanner;
always true. Hence, the loop body will run for infinite
times.
class Main {
public static void main(String[] args) {
for and while loops
int sum = 0; The for loop is used when the number of iterations is
int number = 0; known. For example,
for (int i = 1; i <=5; ++i) {
// create an object of Scanner class // body of loop
Scanner input = new Scanner(System.in); }
And while and do...while loops are generally used
// do...while loop continues when the number of iterations is unknown. For
// until entered number is positive example,
do { while (condition) {
// add only positive numbers // body of loop
sum += number; }
System.out.println("Enter a number");
number = input.nextInt(); Java break Statement
} while(number >= 0); While working with loops, it is sometimes desirable to
skip some statements inside the loop or terminate the
System.out.println("Sum = " + sum); loop immediately without checking the test
input.close(); expression.
} In such cases, break and continue statements are
} used. You will learn about the Java continue
Output 1 statement in the next tutorial.
Enter a number
25 The break statement in Java terminates the loop
Enter a number
immediately, and the control of the program moves to
9
the next statement following the loop.
Enter a number
It is almost always used with decision-making
5
statements (Java if...else Statement).
Enter a number
Here is the syntax of the break statement in Java:
-3
break;
How break statement works? while (true) {
System.out.print("Enter a number: ");
sum += number;
}
Working of Java break Statement System.out.println("Sum = " + sum);
}
Example 1: Java break statement }
class Test {
public static void main(String[] args) { Output:
Enter a number: 3.2
// for loop Enter a number: 5
for (int i = 1; i <= 10; ++i) { Enter a number: 2.3
Enter a number: 0
// if the value of i is 5 the loop terminates Enter a number: -4.5
if (i == 5) { Sum = 10.5
break; In the above program, the test expression of
} the while loop is always true. Here, notice the line,
System.out.println(i); if (number < 0.0) {
} break;
} }
} This means when the user input negative numbers, the
while loop is terminated.
Output:
1 Java break and Nested Loop
2 In the case of nested loops, the break statement
3 terminates the innermost loop.
4
In the above program, we are using the for loop to
print the value of i in each iteration.
if (i == 5) {
break;
}
This means when the value of i is equal to 5, the loop
terminates. Hence we get the output with values less
than 5 only.
Output:
i = 1; j = 1
i = 1; j = 2
i = 2; j = 1
In the above example, the labeled break statement is
used to terminate the loop labeled as first. That is,
first:
for(int i = 1; i < 5; i++) {...}
Here, if we change the statement break first; to break
second; the program will behave differently. In this
case, for loop labeled as second will be terminated.
For example,
class LabeledBreak {
Working of the labeled break statement in Java public static void main(String[] args) {
As you can see in the above image, we have used
the label identifier to specify the outer loop. Now, // the for loop is labeled as first
notice how the break statement is used (break label;). first:
Here, the break statement is terminating the labeled for( int i = 1; i < 5; i++) {
statement (i.e. outer loop). Then, the control of the
program jumps to the statement after the labeled // the for loop is labeled as second
statement. second:
Here's another example: for(int j = 1; j < 3; j ++ ) {
while (testExpression) {
// codes System.out.println("i = " + i + "; j = " +j);
second:
while (testExpression) { // the break statement terminates the loop
// codes labeled as second
while(testExpression) { if ( i == 2)
// codes break second;
break second; }
} }
} }
// control jumps here }
}
In the above example, when the statement break Output:
second; is executed, the while loop labeled i = 1; j = 1
as second is terminated. And, the control of the i = 1; j = 2
i = 2; j = 1
program moves to the statement after the
i = 3; j = 1
second while loop. i = 3; j = 2
i = 4; j = 1
Example 3: labeled break Statement i = 4; j = 2
class LabeledBreak {
public static void main(String[] args) {
Java continue Statement
// the for loop is labeled as first While working with loops, sometimes you might want
first: to skip some statements or terminate the loop. In such
for( int i = 1; i < 5; i++) { cases, break and continue statements are used.
// the for loop is labeled as second Here, we will learn about the continue statement.
second:
for(int j = 1; j < 3; j ++ ) { Java continue
System.out.println("i = " + i + "; j = " +j); The continue statement skips the current iteration of a
loop (for, while, do...while, etc).
// the break statement breaks the first for After the continue statement, the program moves to
loop
the end of the loop. And, test expression is evaluated
if ( i == 2)
(update statement is evaluated in case of the for loop).
break first; Here's the syntax of the continue statement.
} continue;
}
Note: The continue statement is almost always used in class Main {
decision-making statements (if...else Statement). public static void main(String[] args) {
// if number is negative
// continue statement is executed
if (number <= 0.0) {
continue;
}
sum += number;
}
System.out.println("Sum = " + sum);
input.close();
}
}
Working of Java continue Statement Output:
Enter number 1: 2.2
Example 1: Java continue statement Enter number 2: 5.6
class Main { Enter number 3: 0
public static void main(String[] args) { Enter number 4: -2.4
Enter number 5: -3
// for loop Sum = 7.8
for (int i = 1; i <= 10; ++i) {
In the above example, we have used the for loop to
// if value of i is between 4 and 9 print the sum of 5 positive numbers. Notice the line,
// continue is executed if (number < 0.0) {
if (i > 4 && i < 9) { continue;
continue; }
} Here, when the user enters a negative number,
System.out.println(i); the continue statement is executed. This skips the
} current iteration of the loop and takes the program
} control to the update expression of the loop.
}
Output:
1 Note: To take input from the user, we have used
2 the Scanner object.
3
4
9 Java continue with Nested Loop
10 In the case of nested loops in Java,
In the above program, we are using the for loop to the continue statement skips the current iteration of
print the value of i in each iteration. the innermost loop.
Notice the statement,
if (i > 4 && i < 9) {
continue;
}
Here, the continue statement is executed when the
value of i becomes more than 4 and less than 9.
It then skips the print statement for those values.
Hence, the output skips the values 5, 6, 7, and 8.
int i = 1, j = 1;
// outer loop
while (i <= 3) {
Note: The use of labeled continue is often discouraged // match the value of week
as it makes your code hard to understand. If you are in case 44:
a situation where you have to use labeled continue, size = "Large";
break;
refactor your code and try to solve it in a different way
to make it more readable. case 48:
size = "Extra Large";
Java switch Statement break;
The switch statement allows us to execute a block of
code among many alternatives. default:
Syntax: size = "Unknown";
switch (expression) { break;
case value1: }
// code System.out.println("Size: " + size);
break; }
}
case value2:
// code Output:
break; Size: Large
In the above example, we have used
... the switch statement to find the size. Here, we have a
... variable number. The variable is compared with the
value of each case statement.
default: Since the value matches with 44, the code of case 44 is
// default statements executed.
} size = "Large";
How does the switch-case statement work? break;
The expression is evaluated once and compared with
the values of each case. Here, the size variable is assigned with the
If expression matches with value1, the code of case value Large.
value1 are executed. Similarly, the code of case
value2 is executed if expression matches with value2
If there is no match, the code of the default case is
executed
default:
System.out.println("Default case");
}
}
}
Output
Case 2
Case 3
Default case
In the above example, expression matches with case
2. Here, we haven't used the break statement after
each case.
Hence, all the cases after case 2 are also executed.
This is why the break statement is needed to terminate
the switch-case statement after the matching case.
int expression = 9;
switch(expression) {
case 2:
System.out.println("Small Size");
break;
Java Arrays
An array is a collection of similar types of data.
For example, if we want to store the names of 100
Java
people then we can create an array of the string type
Arrays initialization
that can store 100 names.
String[] array = new String[100]; Note:
Here, the above array cannot store more than 100 Array indices always start from 0. That is, the first
element of an array is at index 0.
names. The number of values in a Java array is always
fixed. If the size of an array is n, then the last element of the
array will be at index n-1.
How to declare an array in Java?
In Java, here is how we can declare an array. How to Access Elements of an Array in Java?
dataType[] arrayName; AD
dataType - it can be primitive data We can access the element of an array using the index
types like int, char, double, byte, etc. or Java objects number. Here is the syntax for accessing elements of
an array,
arrayName - it is an identifier
// access array elements
For example, array[index]
double[] data;
Let's see an example of accessing array elements using
Here, data is an array that can hold values of index numbers.
type double. Example: Access Array Elements
But, how many elements can array this hold? class Main {
Good question! To define the number of elements that public static void main(String[] args) {
an array can hold, we have to allocate memory for the
array in Java. For example, // create an array
// declare an array int[] age = {12, 4, 5, 2, 5};
double[] data;
// access each array elements
// allocate memory System.out.println("Accessing Elements of Array:");
data = new double[10]; System.out.println("First Element: " + age[0]);
System.out.println("Second Element: " + age[1]);
Here, the array can store 10 elements. We can also say System.out.println("Third Element: " + age[2]);
that the size or length of the array is 10. System.out.println("Fourth Element: " + age[3]);
In Java, we can declare and allocate the memory of an System.out.println("Fifth Element: " + age[4]);
array in one single statement. For example, }
double[] data = new double[10]; }
Output:
Length of row 1: 3
Length of row 2: 4
2-dimensional Array Length of row 3: 1
Remember, Java uses zero-based indexing, that is,
indexing of arrays in Java starts with 0 and not 1. In the above example, we are creating a
Let's take another example of the multidimensional multidimensional array named a. Since each
array. This time we will be creating a 3-dimensional component of a multidimensional array is also an
array. For example, array (a[0], a[1] and a[2] are also arrays).
String[][][] data = new String[3][4][2]; Here, we are using the length attribute to calculate the
length of each row.
Here, data is a 3d array that can hold a maximum of
24 (3*4*2) elements of type String. Example: Print all elements of 2d array Using Loop
class MultidimensionalArray {
How to initialize a 2d array in Java? public static void main(String[] args) {
Here is how we can initialize a 2-dimensional array in
Java. int[][] a = {
int[][] a = { {1, -2, 3},
{1, 2, 3}, {-4, -5, 6, 9},
{4, 5, 6, 9}, {7},
{7}, };
};
for (int i = 0; i < a.length; ++i) {
As we can see, each element of the multidimensional for(int j = 0; j < a[i].length; ++j) {
array is an array itself. And also, unlike C/C++, each System.out.println(a[i][j]);
row of the multidimensional array in Java can be of }
different lengths. }
}
}
Output:
1
-2
3
-4
-5
6
9
7
// copying from index 2 to 5 (5 is not included) Here, the deepToString() method is used to provide a
int[] destination2 = Arrays.copyOfRange(source, better representation of the 2-dimensional array.
2, 5);
System.out.println("destination2 = " + Copying 2d Arrays using arraycopy()
Arrays.toString(destination2)); To make the above code more simpler, we can replace
} the inner loop with System.arraycopy() as in the case
} of a single-dimensional array. For example,
import java.util.Arrays;
Output
destination1 = [2, 3, 12, 4, 12, -2] class Main {
destination2 = [12, 4, 12] public static void main(String[] args) {
In the above example, notice the line, int[][] source = {
int[] destination1 = Arrays.copyOfRange(source, 0, {1, 2, 3, 4},
source.length); {5, 6},
{0, 2, 42, -4, 5}
Here, we can see that we are creating };
the destination1 array and copying the source array to
it at the same time. We are not creating int[][] destination = new int[source.length][];
the destination1 array before calling
the copyOfRange() method. for (int i = 0; i < source.length; ++i) {
5. Copying 2d Arrays Using Loop // allocating space for each row of destination
Similar to the single-dimensional array, we can also array
copy the 2-dimensional array using the for loop. For destination[i] = new int[source[i].length];
example, System.arraycopy(source[i], 0, destination[i],
import java.util.Arrays; 0, destination[i].length);
}
class Main {
public static void main(String[] args) { // displaying destination array
Here,
returnType - It specifies what type of value a method
returns For example if a method has an int return type
then it returns an integer value.
Working of Java Method Call
If the method does not return a value, its return type
is void. Example 1: Java Methods
methodName - It is an identifier that is used to refer to class Main {
the particular method in a program.
method body - It includes the programming // create a method
statements that are used to perform some tasks. The public int addNumbers(int a, int b) {
method body is enclosed inside the curly braces { }. int sum = a + b;
// return value
For example,
return sum;
int addNumbers() {
}
// code
}
public static void main(String[] args) {
In the above example, the name of the method
int num1 = 25;
is adddNumbers(). And, the return type is int. We
int num2 = 15;
will learn more about return types later in this tutorial.
This is the simple syntax of declaring a method. // create an object of Main
However, the complete syntax of declaring a method Main obj = new Main();
is // calling method
modifier static returnType nameOfMethod int result = obj.addNumbers(num1, num2);
(parameter1, parameter2, ...) { System.out.println("Sum is: " + result);
// method body }
} }
Here, Output
modifier - It defines access types whether the method Sum is: 40
is public, private, and so on.
static - If we use the static keyword, it can be accessed In the above example, we have created a method
without creating objects. named addNumbers(). The method takes two
parameters a and b. Notice the line,
For example, the sqrt() method of standard Math
int result = obj.addNumbers(num1, num2);
class is static. Hence, we can directly
call Math.sqrt() without creating an instance Here, we have called the method by passing two
of Math class. arguments num1 and num2. Since the method is
parameter1/parameter2 - These are values passed to a returning some value, we have stored the value in
method. We can pass any number of arguments to a the result variable.
method.
Calling a Method in Java Note: The method is not static. Hence, we are calling
In the above example, we have declared a method the method using the object of the class.
named addNumbers(). Now, to use the method, we
need to call it.
Here's is how we can call the addNumbers() method. Java Method Return Type
// calls the method A Java method may or may not return a value to the
addNumbers(); function call. We use the return statement to return
any value. For example,
int addNumbers() {
...
return sum;
}
Here, we are returning the variable sum. Since the // code
return type of the function is int. The sum variable }
should be of int type. Otherwise, it will generate an
// method with no parameter
error.
int addNumbers(){
Example 2: Method Return Type
// code
class Main {
}
// create a method
If a method is created with parameters, we need to
public static int square(int num) {
pass the corresponding values while calling the
method. For example,
// return statement
// calling the method with two parameters
return num * num;
addNumbers(25, 15);
}
// calling the method with no parameters
public static void main(String[] args) {
addNumbers()
int result;
Example 3: Method Parameters
// call the method
class Main {
// store returned value to result
result = square(10);
// method with no parameter
public void display1() {
System.out.println("Squared value of 10 is: " +
System.out.println("Method without parameter");
result);
}
}
}
// method with single parameter
public void display2(int a) {
Output:
System.out.println("Method with a single
Squared value of 10 is: 100
parameter: " + a);
}
In the above program, we have created a method
named square(). The method takes a number as its public static void main(String[] args) {
parameter and returns the square of the number.
Here, we have mentioned the return type of the // create an object of Main
method as int. Hence, the method should always Main obj = new Main();
return an integer value.
// calling method with no parameter
obj.display1();
Output
Method without parameter
Method with a single parameter: 24
Representation of the Java method returning a value Here, the parameter of the method is int. Hence, if we
Note: If the method does not return any value, we use
the void keyword as the return type of the method. For pass any other data type instead of int, the compiler
example, will throw an error. It is because Java is a strongly
public void square(int a) { typed language.
int square = a * a; Note: The argument 24 passed to
System.out.println("Square is: " + square); the display2() method during the method call is called
} the actual argument.
The parameter a accepted by the method definition is
known as a formal argument. We need to specify the
Method Parameters in Java type of formal arguments. And, the type of actual
A method parameter is a value accepted by the arguments and formal arguments should always
method. As mentioned earlier, a method can also have match.
any number of parameters. For example,
// method with two parameters
int addNumbers(int a, int b) {
2. Methods make code more readable and easier to
Standard Library Methods debug. Here, the getSquare() method keeps the code
The standard library methods are built-in methods in to compute the square in a block. Hence, makes it
Java that are readily available for use. These standard more readable.
libraries come along with the Java Class Library (JCL)
in a Java archive (*.jar) file with JVM and JRE. Java Method Overloading
For example,
In Java, two or more methods may have the same
print() is a method of java.io.PrintSteam. name if they differ in parameters (different number of
The print("...") method prints the string inside parameters, different types of parameters, or both).
quotation marks. These methods are called overloaded methods and this
sqrt() is a method of Math class. It returns the square feature is called method overloading. For example:
root of a number. void func() { ... }
Here's a working example: void func(int a) { ... }
Example 4: Java Standard Library Method float func(double a) { ... }
public class Main { float func(int a, float b) { ... }
public static void main(String[] args) {
Here, the func() method is overloaded. These methods
// using the sqrt() method have the same name but accept different arguments.
System.out.print("Square root of 4 is: " +
Math.sqrt(4));
} Note: The return types of the above methods are not
} the same. It is because method overloading is not
associated with return types. Overloaded methods
Output:
may have the same or different return types, but they
Square root of 4 is: 2.0
must differ in parameters.
public static void main(String[] args) { public static void main(String[] args) {
// call the constructor
Main obj = new Main(); // call constructor with no parameter
Main obj1 = new Main();
Static Methods
// call constructor with a single parameter Static methods are also called class methods. It is
Main obj2 = new Main("Python"); because a static method belongs to the class rather
than the object of a class.
obj1.getName(); And we can invoke static methods directly using the
obj2.getName(); class name. For example,
} class Test {
} // static method inside the Test class
public static void method() {...}
Output }
Programming Language: Java
Programming Language: Python class Main {
// invoking the static method
In the above example, we have two Test.method();
constructors: Main() and Main(String language). }
Here, both the constructors initialize the value of the Here, we can see that the static method can be
variable language with different values. accessed directly from other classes using the class
Based on the parameter passed during object creation, name.
different constructors are called, and different values In every Java program, we have declared
are assigned. the main method static. It is because to run the
It is also possible to call one constructor from another program the JVM should be able to invoke the main
constructor. method during the initial phase where no objects exist
in the memory.
Note: We have used this keyword to specify the Example 1: Java static and non-static Methods
variable of the class. class StaticTest {
In the above example, the length() method calculates System.out.println("Strings first and third are equal:
the total number of characters in the string and returns " + result2);
it. }
}
// create 3 strings
String first = "java programming";
Here, we have created a string variable Here, we are directly providing the value of the string
named example. The variable holds the string "Hello! (Java). Hence, the compiler first checks the string pool
". to see if the string already exists.
Now, suppose we want to change the string. If the string already exists, the new string is not
// add another string "World" created. Instead, the new reference, example points to
// to the previous tring example the already existing string (Java).
example = example.concat(" World"); If the string doesn't exist, a new string (Java) is
created.
Here, we are using the concat() method to add 2. While creating strings using the new keyword,
another string "World" to the previous string. String example = new String("Java");
It looks like we are able to change the value of the
previous string. However, this is not true. Here, the value of the string is not directly provided.
Let's see what has happened here: Hence, a new "Java" string is created even
1. JVM takes the first string "Hello! " though "Java" is already present inside the memory
2. creates a new string by adding "World" to the first pool.
string
3. assigns the new string "Hello! World" to Methods of Java String
the example variable Besides those mentioned above, there are
various string methods present in Java. Here are some
4. The first string "Hello! " remains unchanged
of those methods:
Creating Strings Using the New Keyword
Methods Description
So far, we have created strings like primitive types in
contains() Checks whether the string
Java.
contains a substring.
Since strings in Java are objects, we can create strings
substring() Returns the substring of the
using the new keyword as well. For example,
string.
// create a string using the new keyword
join() Joins the given strings using
String name = new String("Java String");
the delimiter.
replace() Replaces the specified old
In the above example, we have created a
character with the specified
string name using the new keyword. new character.
Here, when we create a string object, replaceAll() Replaces all substrings
the String() constructor is invoked. matching the regex pattern.
replaceFirst() Replaces the first matching
Note: The String class provides various other substring.
constructors to create strings. charAt() Returns the character present
in the specified location.
getBytes() Converts the string to an array
Example: Create Java Strings Using the New of bytes.
Keyword indexOf() Returns the position of the
class Main { specified character in the
public static void main(String[] args) { string.
compareTo() Compares two strings in the
// create a string using new dictionary order.
String name = new String("Java String"); compareToIgn Compares two strings, ignoring
oreCase() case differences.
trim() Removes any leading and
System.out.println(name); // print Java String trailing whitespaces.
} format() Returns a formatted string.
} split() Breaks the string into an array
of strings.
Create String Using Literals vs. New Keyword toLowerCase() Converts the string to
Now that we know how strings are created lowercase.
using string literals and the new keyword, let's see toUpperCase() Converts the string to
what is the major difference between them. uppercase.
In Java, the JVM maintains a string pool to store all valueOf() Returns the string
of its strings inside the memory. The string pool helps representation of the specified
in reusing the strings. argument.
1. While creating strings using string literals, toCharArray() Converts the string to a char
String example = "Java"; array.
matches() Checks whether the string
matches the given regex.
startsWith() Checks if the string begins with void message(){
the given string. System.out.println("This is a message");
endsWith() Checks if the string ends with }
the given string. }
isEmpty() Checks whether a string is
empty or not. Here, the Logger class has the default access modifier.
intern() Returns the canonical And the class is visible to all the classes that belong to
representation of the string. the defaultPackage package. However, if we try to use
contentEquals() Checks whether the string is the Logger class in another class outside of
equal to charSequence. defaultPackage, we will get a compilation error.
hashCode() Returns a hash code for the
string. Private Access Modifier
subSequence() Returns a subsequence from When variables and methods are declared private,
the string. they cannot be accessed outside of the class. For
example,
class Data {
Java Access Modifiers // private variable
What are Access Modifiers? private String name;
In Java, access modifiers are used to set the }
accessibility (visibility)
of classes, interfaces, variables, methods, constructors, public class Main {
data members, and the setter methods. For example, public static void main(String[] main){
class Animal {
public void method1() {...} // create an object of Data
Data d = new Data();
private void method2() {...}
} // access private variable and field from another
class
In the above example, we have declared 2 methods: d.name = "Programiz";
method1() and method2(). Here, }
method1 is public - This means it can be accessed by }
other classes.
method2 is private - This means it can not be In the above example, we have declared a private
accessed by other classes. variable named name. When we run the program, we
Note the keyword public and private. These are will get the following error:
access modifiers in Java. They are also known as Main.java:18: error: name has private access in Data
visibility modifiers. d.name = "Programiz";
^
Note: You cannot set the access modifier of getters The error is generated because we are trying to access
methods. the private variable of the Data class from
the Main class.
Types of Access Modifier You might be wondering what if we need to access
Before you learn about types of access modifiers, make those private variables. In this case, we can use the
sure you know about Java Packages. getters and setters method. For example,
There are four access modifiers keywords in Java and class Data {
they are: private String name;
Modifier Description
Default declarations are visible only within // getter method
the package (package private) public String getName() {
Private declarations are visible within the return this.name;
class only }
Protected declarations are visible within the // setter method
package or all subclasses public void setName(String name) {
Public declarations are visible everywhere this.name= name;
}
Default Access Modifier }
If we do not explicitly specify any access modifier for public class Main {
classes, methods, variables, etc, then by default the public static void main(String[] main){
default access modifier is considered. For example, Data d = new Data();
package defaultPackage;
class Logger { // access the private variable using the getter and
setter
d.setName("Programiz"); Note: We cannot declare classes or
System.out.println(d.getName()); interfaces protected in Java.
}
}
Public Access Modifier
Output: When methods, variables, classes, and so on are
The name is Programiz declared public, then we can access them from
anywhere. The public access modifier has no scope
In the above example, we have a private variable restriction. For example,
named name. In order to access the variable from the // Animal.java file
outer class, we have used // public class
methods: getName() and setName(). These methods public class Animal {
are called getter and setter in Java. // public variable
Here, we have used the setter method (setName()) to public int legCount;
assign value to the variable and the getter method
(getName()) to access the variable. // public method
public void display() {
We have used this keyword inside the setName() to
System.out.println("I am an animal.");
refer to the variable of the class.
System.out.println("I have " + legCount + "
legs.");
}
Note: We cannot declare classes and interfaces private
}
in Java. However, the nested classes can be declared
private. // Main.java
public class Main {
public static void main( String[] args ) {
Protected Access Modifier // accessing the public class
When methods and data members are Animal animal = new Animal();
declared protected, we can access them within the
same package as well as from subclasses. For example, // accessing the public variable
class Animal { animal.legCount = 4;
// protected method // accessing the public method
protected void display() { animal.display();
System.out.println("I am an animal"); }
} }
}
Output:
class Dog extends Animal { I am an animal.
public static void main(String[] args) { I have 4 legs.
int age;
Main(int age){
age = age;
}
Accessibility of all Access Modifiers in Java public static void main(String[] args) {
Main obj = new Main(8);
System.out.println("obj.age = " + obj.age);
Java this Keyword }
In Java, this keyword is used to refer to the current }
object inside a method or a constructor. For example,
class Main { Output:
int instVar; obj.age = 0
Main(int instVar){
In the above example, we have passed 8 as a value to
this.instVar = instVar;
System.out.println("this reference = " + this); the constructor. However, we are getting 0 as an
} output. This is because the Java compiler gets
confused because of the ambiguity in names between
public static void main(String[] args) { instance the variable and the parameter.
Main obj = new Main(8); Now, let's rewrite the above code using this keyword.
System.out.println("object reference = " + obj); class Main {
}
} int age;
Main(int age){
Output: this.age = age;
this reference = Main@23fc625e }
object reference = Main@23fc625e
public static void main(String[] args) {
In the above example, we created an object Main obj = new Main(8);
named obj of the class Main. We then print the System.out.println("obj.age = " + obj.age);
reference to the object obj and this keyword of the }
}
class.
Here, we can see that the reference of
Output:
both obj and this is the same. It means this is nothing
obj.age = 8
but the reference to the current object.
Now, we are getting the expected output. It is because
Use of this Keyword
when the constructor is called, this inside the
There are various situations where this keyword is
constructor is replaced by the object obj that has
commonly used.
1. Using this for Ambiguity Variable Names called the constructor. Hence the age variable is
In Java, it is not allowed to declare two or assigned value 8.
more variables having the same name inside a scope Also, if the name of the parameter and instance
(class scope or method scope). However, instance variable is different, the compiler automatically
variables and parameters may have the same name. appends this keyword. For example, the code:
For example, class Main {
class MyClass { int age;
// instance variable
int age; Main(int i) {
age = i; private Complex(int i){
} // invokes the constructor with 2 parameters
} this(i, i);
}
is equivalent to:
class Main { // constructor with no parameter
int age; private Complex(){
// invokes the constructor with single parameter
Main(int i) { this(0);
this.age = i; }
}
} @Override
public String toString(){
2. this with Getters and Setters return this.a + " + " + this.b + "i";
Another common use of this keyword is in setters and }
getters methods of a class. For example:
class Main { public static void main( String[] args ) {
String name;
// creating object of Complex class
// setter method // calls the constructor with 2 parameters
void setName( String name ) { Complex c1 = new Complex(2, 3);
this.name = name;
} // calls the constructor with a single parameter
Complex c2 = new Complex(3);
// getter method
String getName(){ // calls the constructor with no parameters
return this.name; Complex c3 = new Complex();
}
// print objects
public static void main( String[] args ) { System.out.println(c1);
Main obj = new Main(); System.out.println(c2);
System.out.println(c3);
// calling the setter and the getter method }
obj.setName("Toshiba"); }
System.out.println("obj.name: "+obj.getName());
} Output:
} 2 + 3i
3 + 3i
Output: 0 + 0i
obj.name: Toshiba
Here, we have used this keyword: In the above example, we have used this keyword,
to assign value inside the setter method to call the constructor Complex(int i, int j) from the
to access value inside the getter method constructor Complex(int i)
to call the constructor Complex(int i) from the
3. Using this in Constructor Overloading constructor Complex()
While working with constructor overloading, we Notice the line,
might have to invoke one constructor from another System.out.println(c1);
constructor. In such a case, we cannot call the
constructor explicitly. Instead, we have to
Here, when we print the object c1, the object is
use this keyword.
converted into a string. In this process, the toString() is
Here, we use a different form of this keyword. That
called. Since we override the toString() method inside
is, this(). Let's take an example,
our class, we get the output according to that method.
class Complex {
One of the huge advantages of this() is to reduce the
private int a, b; amount of duplicate code. However, we should be
always careful while using this().
// constructor with 2 parameters This is because calling constructor from another
private Complex( int i, int j ){ constructor adds overhead and it is a slow process.
this.a = i; Another huge advantage of using this() is to reduce
this.b = j; the amount of duplicate code.
}
Output
name is an instance of String: true
obj is an instance of Main: true
Output
I eat dog food
I can bark
Types of inheritance
There are five types of inheritance.
1. Single Inheritance 4. Multiple Inheritance
In single inheritance, a single subclass extends from a In multiple inheritance, a single subclass extends from
single superclass. For example, multiple superclasses. For example,
5. Hybrid Inheritance
Hybrid inheritance is a combination of two or more
types of inheritance. For example,
In the above example, the subclass Dog overrides the class Main {
method displayInfo() of the superclass Animal. public static void main(String[] args) {
Dog dog1 = new Dog();
Whenever we call displayInfo() using the d1 (object
dog1.printMessage();
of the subclass), the method inside the subclass is
}
called.
}
Notice that, the displayInfo() is declared protected in
the Animal superclass. The same method has Output
the public access specifier in the Dog subclass. This is I am a dog
possible because the public provides larger access than
the protected. In this example, by making an
object dog1 of Dog class, we can call its
Overriding Abstract Methods method printMessage() which then executes
In Java, abstract classes are created to be the the display() statement.
superclass of other classes. And, if a class contains an Since display() is defined in both the classes, the
abstract method, it is mandatory to override it. method of subclass Dog overrides the method of
We will learn more about abstract classes and
superclass Animal. Hence, the display() of the
overriding of abstract methods in later tutorials.
subclass is called.
Java super
The super keyword in Java is used in subclasses to
access superclass members
(attributes, constructors and methods).
// this calls overridden method In this example, we have defined the same instance
super.display(); field type in both the superclass Animal and the
} subclass Dog.
} We then created an object dog1 of the Dog class.
Then, the printType() method is called using this
class Main { object.
public static void main(String[] args) { Inside the printType() function,
Dog dog1 = new Dog();
dog1.printMessage(); type refers to the attribute of the subclass Dog.
} super.type refers to the attribute of the superclass
} Animal.
Hence, System.out.println("I am a " + type); prints I
Output am a mammal. And, System.out.println("I am an " +
I am a dog super.type); prints I am an animal.
I am an animal
3. Use of super() to access superclass constructor
Here, how the above program works. As we know, when an object of a class is created, its
default constructor is automatically called.
To explicitly call the superclass constructor from the
subclass constructor, we use super(). It's a special form
of the super keyword.
super() can be used only inside the subclass
constructor and must be the first statement.
class Main {
public static void main(String[] args) {
Dog dog1 = new Dog();
}
}
Output
Type: Animal
I am a dog
Java Abstract Class and Abstract Methods class Main extends Language {
Java Abstract Class public static void main(String[] args) {
The abstract class in Java cannot be instantiated (we
cannot create objects of abstract classes). We use // create an object of Main
the abstract keyword to declare an abstract class. For Main obj = new Main();
example,
// create an abstract class // access method of abstract class
abstract class Language { // using object of Main class
// fields and methods obj.display();
} }
... }
// regular method Here, obj is the object of the child class Main. We are
void method2() { calling the method of the abstract class using the
System.out.println("This is regular method"); object obj.
}
} Implementing Abstract Methods
If the abstract class includes any abstract method, then
all the child classes inherited from the abstract
Java Abstract Method superclass must provide the implementation of the
A method that doesn't have its body is known as an abstract method. For example,
abstract method. We use the same abstract keyword abstract class Animal {
to create abstract methods. For example, abstract void makeSound();
abstract void display();
public void eat() {
Here, display() is an abstract method. The body System.out.println("I can eat.");
}
of display() is replaced by ;.
}
If a class contains an abstract method, then the class
should be declared abstract. Otherwise, it will generate class Dog extends Animal {
an error. For example,
// error // provide implementation of abstract method
// class should be abstract public void makeSound() {
class Language { System.out.println("Bark bark");
}
// abstract method }
abstract void method1();
} class Main {
public static void main(String[] args) {
Example: Java Abstract Class and Method
Though abstract classes cannot be instantiated, we can // create an object of Dog class
create subclasses from it. We can then access members Dog d1 = new Dog();
of the abstract class using the object of the subclass.
For example, d1.makeSound();
abstract class Language { d1.eat();
}
// method of abstract class }
public void display() {
Output brake differently for different motorbikes, however,
Bark bark what brake does will be the same.
I can eat. Let's take an example that helps us to better
understand Java abstraction.
In the above example, we have created an abstract
class Animal. The class contains an abstract Example 3: Java Abstraction
method makeSound() and a non-abstract abstract class MotorBike {
method eat(). abstract void brake();
}
We have inherited a subclass Dog from the
superclass Animal. Here, the subclass Dog provides class SportsBike extends MotorBike {
the implementation for the abstract
method makeSound(). // implementation of abstract method
We then used the object d1 of the Dog class to call public void brake() {
methods makeSound() and eat(). System.out.println("SportsBike Brake");
}
}
Note: If the Dog class doesn't provide the
implementation of the abstract class MountainBike extends MotorBike {
method makeSound(), Dog should also be declared as
// implementation of abstract method
abstract. This is because the public void brake() {
subclass Dog inherits makeSound() from Animal. System.out.println("MountainBike Brake");
}
}
Accesses Constructor of Abstract Classes
An abstract class can have constructors like the regular class Main {
class. And, we can access the constructor of an public static void main(String[] args) {
abstract class from the subclass using MountainBike m1 = new MountainBike();
the super keyword. For example, m1.brake();
abstract class Animal { SportsBike s1 = new SportsBike();
Animal() { s1.brake();
…. }
} }
}
Output:
class Dog extends Animal { MountainBike Brake
Dog() { SportsBike Brake
super();
... In the above example, we have created an abstract
} super class MotorBike. The superclass MotorBike has
} an abstract method brake().
The brake() method cannot be implemented
Here, we have used the super() inside the constructor
inside MotorBike. It is because every bike has
of Dog to access the constructor of the Animal.
different implementation of brakes. So, all the
Note that the super should always be the first subclasses of MotorBike would have different
statement of the subclass constructor.
implementation of brake().
Java Abstraction So, the implementation of brake() in MotorBike is
The major use of abstract classes and methods is to kept hidden.
achieve abstraction in Java. Here, MountainBike makes its own implementation
Abstraction is an important concept of object-oriented of brake() and SportsBike makes its own
programming that allows us to hide unnecessary implementation of brake().
details and only show the needed information.
This allows us to manage complexity by omitting or Note: We can also use interfaces to achieve
hiding details with a simpler, higher-level idea.
abstraction in Java.
A practical example of abstraction can be motorbike
brakes. We know what brake does. When we apply
the brake, the motorbike will stop. However, the Key Points to Remember
working of the brake is kept hidden from us. We use the abstract keyword to create abstract classes
The major advantage of hiding the working of the and methods.
brake is that now the manufacturer can implement An abstract method doesn't have any implementation
(method body).
A class containing abstract methods should also be In the above example, we have created an interface
abstract. named Polygon. The interface contains an abstract
We cannot create objects of an abstract class. method getArea().
To implement features of an abstract class, we inherit Here, the Rectangle class implements Polygon. And,
subclasses from it and create objects of the subclass.
provides the implementation of the getArea() method.
A subclass must override all abstract methods of an
abstract class. However, if the subclass is declared
abstract, it's not mandatory to override abstract Example 2: Java Interface
methods. // create an interface
We can access the static attributes and methods of an interface Language {
abstract class using the reference of the abstract class. void getName(String name);
For example, }
Animal.staticMethod();
// class implements interface
class ProgrammingLanguage implements Language {
Java Interface // implementation of abstract method
An interface is a fully abstract class. It includes a public void getName(String name) {
group of abstract methods (methods without a body). System.out.println("Programming Language: " +
We use the interface keyword to create an interface in name);
Java. For example, }
interface Language { }
public void getType();
class Main {
public void getVersion(); public static void main(String[] args) {
} ProgrammingLanguage language = new
ProgrammingLanguage();
Here, language.getName("Java");
Language is an interface. }
It includes abstract }
methods: getType() and getVersion().
Output
Implementing an Interface Programming Language: Java
Like abstract classes, we cannot create objects of In the above example, we have created an interface
interfaces. named Language. The interface includes an abstract
To use an interface, other classes must implement it. method getName().
We use the implements keyword to implement an Here, the ProgrammingLanguage class implements
interface. the interface and provides the implementation for the
method.
Example 1: Java Interface
interface Polygon { Implementing Multiple Interfaces
void getArea(int length, int breadth); In Java, a class can also implement multiple interfaces.
} For example,
interface A {
// implement the Polygon interface // members of A
class Rectangle implements Polygon { }
class Square extends Polygon { We can achieve polymorphism in Java using the
following ways:
// renders Square 1. Method Overriding
public void render() { 2. Method Overloading
System.out.println("Rendering Square..."); 3. Operator Overloading
}
} 1. Java Method Overriding
During inheritance in Java, if the same method is
class Circle extends Polygon { present in both the superclass and the subclass. Then,
the method in the subclass overrides the same method
// renders circle in the superclass. This is called method overriding.
public void render() { In this case, the same method will perform one
System.out.println("Rendering Circle..."); operation in the superclass and another operation in
} the subclass. For example,
} Example 1: Polymorphism using method overriding
class Language {
class Main { public void displayInfo() {
public static void main(String[] args) { System.out.println("Common English Language");
}
// create an object of Square }
Square s1 = new Square();
s1.render(); class Java extends Language {
@Override
// create an object of Circle public void displayInfo() {
Circle c1 = new Circle(); System.out.println("Java Programming Language");
c1.render(); }
} }
}
class Main {
public static void main(String[] args) { // method with single parameter
public void display(char symbol) {
// create an object of Java class for (int i = 0; i < 10; i++) {
Java j1 = new Java(); System.out.print(symbol);
j1.displayInfo(); }
}
// create an object of Language class }
Language l1 = new Language();
l1.displayInfo(); class Main {
} public static void main(String[] args) {
} Pattern d1 = new Pattern();
In the above example, we have created a superclass // call method with a single argument
named Language and a subclass named Java. Here, d1.display('#');
the method displayInfo() is present in }
both Language and Java. }Output:
**********
The use of displayInfo() is to print the information.
However, it is printing different information ##########
in Language and Java.
Based on the object used to call the method, the In the above example, we have created a class
corresponding information is printed. named Pattern. The class contains a method
named display() that is overloaded.
// method with no arguments
display() {...}
Output: Output:
Engine Type for 8WD= Bigger Total Ports = 3
Engine Type for 4WD = Smaller In the above program, we have created a static class
named USB inside the class MotherBoard. Notice the
In the above program, we have the inner class line,
named Engine inside the outer class Car. Here, notice MotherBoard.USB usb = new MotherBoard.USB();
the line, Here, we are creating an object of USB using the
if(Car.this.carType.equals("4WD")) {...} name of the outer class.
We are using this keyword to access Now, let's see what would happen if you try to access
the carType variable of the outer class. You may have the members of the outer class:
noticed that instead of using this.carType we have
used Car.this.carType. Example 4: Accessing members of Outer class inside
It is because if we had not mentioned the name of the Static Inner Class
class MotherBoard {
outer class Car, then this keyword will represent the
String model;
member inside the inner class. public MotherBoard(String model) {
Similarly, we are also accessing the method of the this.model = model;
outer class from the inner class. }
if (Car.this.getCarName().equals("Crysler") {...}
It is important to note that, although // static nested class
the getCarName() is a private method, we are able to static class USB{
access it from the inner class. int usb2 = 2;
int usb3 = 1;
Static Nested Class int getTotalPorts(){
In Java, we can also define a static class inside // accessing the variable model of the outer
another class. Such class is known as static nested classs
class. Static nested classes are not called static inner if(MotherBoard.this.model.equals("MSI")) {
classes. return 4;
Unlike inner class, a static nested class cannot access }
the member variables of the outer class. It is because else {
the static nested class doesn't require you to create an return usb2 + usb3;
instance of the outer class. }
OuterClass.NestedClass obj = new }
OuterClass.NestedClass(); }
Here, we are creating an object of the static nested }
class by simply using the class name of the outer class. public class Main {
Hence, the outer class cannot be referenced public static void main(String[] args) {
using OuterClass.this.
// create an object of the static nested class
Example 3: Static Inner Class
MotherBoard.USB usb = new
class MotherBoard {
MotherBoard.USB();
System.out.println("Total Ports = " +
// static nested class
usb.getTotalPorts());
static class USB{
}
int usb2 = 2;
}
int usb3 = 1;
int getTotalPorts(){
When we try to run the program, we will get an error:
return usb2 + usb3;
}
error: non-static variable this cannot be referenced }
from a static context }
This is because we are not using the object of the outer
class to create an object of the inner class. Hence, there // static class
is no reference to the outer class Motherboard stored static class Mammal {
in Motherboard.this. public void displayInfo() {
System.out.println("I am a mammal.");
Key Points to Remember }
Java treats the inner class as a regular member of a }
class. They are just like methods and variables }
declared inside a class.
Since inner classes are members of the outer class, you class Main {
can apply any access modifiers public static void main(String[] args) {
// object creation of the outer class
like private, protected to your inner class which is not
Animal animal = new Animal();
possible in normal classes.
Since the nested class is a member of its enclosing
// object creation of the non-static class
outer class, you can use the dot (.) notation to access Animal.Reptile reptile = animal.new Reptile();
the nested class and its members. reptile.displayInfo();
Using the nested class will make your code more
readable and provide better encapsulation. // object creation of the static nested class
Non-static nested classes (inner classes) have access to Animal.Mammal mammal = new
other members of the outer/enclosing class, even if Animal.Mammal();
they are declared private. mammal.displayInfo();
In this tutorial, we will learn about nested static In the above program, we have two nested
classes. class Mammal and Reptile inside a class Animal.
AD
Java Nested Static Class To create an object of the non-static class Reptile, we
We use the keyword static to make our nested class have used
static. Animal.Reptile reptile = animal.new Reptile()
To create an object of the static class Mammal, we
Note: In Java, only nested classes are allowed to be have used
static. Animal.Mammal mammal = new Animal.Mammal()
Like regular classes, static nested classes can include Accessing Members of Outer Class
both static and non-static fields and methods. For In Java, static nested classes are associated with the
example, outer class. This is why static nested classes can only
Class Animal { access the class members (static fields and methods) of
static class Mammal { the outer class.
// static and non-static members of Mammal Let's see what will happen if we try to access non-
} static fields and methods of the outer class.
// members of Animal
} Example: Accessing Non-static members
Static nested classes are associated with the outer class Animal {
class. static class Mammal {
To access the static nested class, we don't need objects public void displayInfo() {
of the outer class. System.out.println("I am a mammal.");
}
Example: Static Nested Class }
class Animal {
class Reptile {
// inner class public void displayInfo() {
class Reptile { System.out.println("I am a reptile.");
public void displayInfo() { }
System.out.println("I am a reptile."); }
Java Anonymous Class
public void eat() { In Java, a class can contain another class known as
System.out.println("I eat food."); nested class. It's possible to create a nested class
} without giving any name.
} A nested class that doesn't have any name is known as
an anonymous class.
class Main { An anonymous class must be defined inside another
public static void main(String[] args) { class. Hence, it is also known as an anonymous inner
Animal animal = new Animal(); class. Its syntax is:
Animal.Reptile reptile = animal.new Reptile(); class outerClass {
reptile.displayInfo();
// defining anonymous class
Animal.Mammal mammal = new object1 = new Type(parameterList) {
Animal.Mammal(); // body of the anonymous class
mammal.displayInfo(); };
mammal.eat(); }
}
} Anonymous classes usually extend subclasses or
implement interfaces.
Output Here, Type can be
Main.java:28: error: cannot find symbol 1. a superclass that an anonymous class extends
mammal.eat(); 2. an interface that an anonymous class implements
^ The above code creates an object, object1, of an
symbol: method eat()
anonymous class at runtime.
location: variable mammal of type Mammal
1 error
compiler exit status 1 Note: Anonymous classes are defined inside an
expression. So, the semicolon is used at the end of
In the above example, we have created a non-static
method eat() inside the class Animal. anonymous classes to indicate the end of the
Now, if we try to access eat() using the expression.
object mammal, the compiler shows an error.
It is because mammal is an object of a static class and Example 1: Anonymous Class Extending a Class
we cannot access non-static methods from static class Polygon {
classes. public void display() {
System.out.println("Inside the Polygon class");
Static Top-level Class }
As mentioned above, only nested classes can be static. }
We cannot have static top-level classes.
Let's see what will happen if we try to make a top-level class AnonymousDemo {
class static. public void createClass() {
static class Animal {
public static void displayInfo() { // creation of anonymous class extending class
System.out.println("I am an animal"); Polygon
} Polygon p1 = new Polygon() {
} public void display() {
System.out.println("Inside an anonymous
class Main { class.");
public static void main(String[] args) { }
Animal.displayInfo(); };
} p1.display();
} }
}
Output
Main.java:1: error: modifier static not allowed here class Main {
static class Animal { public static void main(String[] args) {
^ AnonymousDemo an = new AnonymousDemo();
1 error an.createClass();
compiler exit status 1 }
In the above example, we have tried to create a static }
class Animal. Since Java doesn't allow static top-level
class, we will get an error. Output
Inside an anonymous class.
In the above example, we have created a Java Singleton Class
class Polygon. It has a single method display().
We then created an anonymous class that extends the In Java, Singleton is a design pattern that ensures that
class Polygon and overrides the display() method. a class can only have one object.
When we run the program, an object p1 of the To create a singleton class, a class must implement the
anonymous class is created. The object then calls following properties:
the display() method of the anonymous class. Create a private constructor of the class to restrict
object creation outside of the class.
Example 2: Anonymous Class Implementing an Create a private attribute of the class type that refers
Interface to the single object.
interface Polygon { Create a public static method that allows us to create
public void display(); and access the object we created. Inside the method,
} we will create a condition that restricts us from
creating more than one object.
class AnonymousDemo {
public void createClass() { Example: Java Singleton Class Syntax
class SingletonExample {
// anonymous class implementing interface
Polygon p1 = new Polygon() { // private field that refers to the object
public void display() { private static SingletonExample singleObject;
System.out.println("Inside an anonymous
class."); private SingletonExample() {
} // constructor of the SingletonExample class
}; }
p1.display();
} public static SingletonExample getInstance() {
} // write code that allows us to create only one
object
class Main { // access the object as per our need
public static void main(String[] args) { }
AnonymousDemo an = new AnonymousDemo(); }
an.createClass(); In the above example,
}
private static SingletonExample singleObject - a
}
reference to the object of the class.
Output private SingletonExample() - a
Inside an anonymous class. private constructor that restricts creating objects
In the above example, we have created an anonymous outside of the class.
class that implements the Polygon interface. public static SingletonExample getInstance() - this
method returns the reference to the only object of the
Advantages of Anonymous Classes class. Since the method static, it can be accessed using
In anonymous classes, objects are created whenever the class name.
they are required. That is, objects are created to
perform some specific tasks. For example, Use of Singleton in Java
Object = new Example() { Singletons can be used while working with databases.
public void display() { They can be used to create a connection pool to access
System.out.println("Anonymous class overrides the database while reusing the same connection for all
the method display()."); the clients. For example,
} class Database {
}; private static Database dbObject;
Here, an object of the anonymous class is created
dynamically when we need to override private Database() {
the display() method. }
Anonymous classes also help us to make our code
concise. public static Database getInstance() {
// get the value of the field type // get the value of field color
String typeValue = (String) field1.get(d1); String colorValue = (String) field1.get(d1);
System.out.println("Value: " + typeValue); System.out.println("Value: " + colorValue);
// get the access modifier of the field type // get the access modifier of color
int mod = field1.getModifiers(); int mod2 = field1.getModifiers();
// convert the modifier to String form // convert the access modifier to string
String modifier1 = Modifier.toString(mod); String modifier2 = Modifier.toString(mod2);
System.out.println("Modifier: " + modifier1); System.out.println("Modifier: " + modifier2);
System.out.println(" "); }
}
catch (Exception e) {
catch (Exception e) { e.printStackTrace();
e.printStackTrace(); }
} }
} }
}
Output
Output Value: brown
Value: labrador Modifier: private
Modifier: public
In the above example, we have created a class
In the above example, we have created a class named Dog. The class contains a private field
named Dog. It includes a public field named type. named color. Notice the statement.
Notice the statement, Field field1 = obj.getDeclaredField("color");
Field field1 = obj.getField("type");
field1.setAccessible(true);
Here, we are accessing the public field of the Dog class
and assigning it to the object field1 of the Field class. Here, we are accessing color and assigning it to the
We then used various methods of the Field class:
object field1 of the Field class. We then used field1 to
field1.set() - sets the value of the field
field1.get() - returns the value of field modify the accessibility of color and allows us to
field1.getModifiers() - returns the value of the field in make changes to it.
integer form We then used field1 to perform various operations on
Similarly, we can also access and modify private fields the private field color.
as well. However, the reflection of private field is little
bit different than the public field. For example, 3. Reflection of Java Constructor
import java.lang.Class; We can also inspect different constructors of a class
import java.lang.reflect.*; using various methods provided by
the Constructor class. For example,
class Dog { import java.lang.Class;
private String color; import java.lang.reflect.*;
}
class Dog {
class Main { // public constructor without parameter
public static void main(String[] args) { public Dog() {
try { }
// create an object of Dog // private constructor with a single parameter
Dog d1 = new Dog(); private Dog(int age) {
}}
// create an object of Class class Main {
public static void main(String[] args) { If you want to use the ResultSet interface in your
try { code, just import the java.sql package (Importing
// create an object of Dog packages will be discussed later in the article).
Dog d1 = new Dog();
// create an object of Class As mentioned earlier, packages are just containers for
// using getClass() Java classes, interfaces and so on. These packages help
Class obj = d1.getClass(); you to reserve the class namespace and create a
// get all constructors of Dog maintainable code.
Constructor[] constructors = For example, you can find two Date classes in Java.
obj.getDeclaredConstructors();
However, the rule of thumb in Java programming is
for (Constructor c : constructors) {
that only one unique class name is allowed in a Java
// get the name of constructors
project.
System.out.println("Constructor Name: " +
c.getName());
How did they manage to include two classes with
// get the access modifier of constructors
// convert it into string form the same name Date in JDK?
int modifier = c.getModifiers(); This was possible because these two Date classes
String mod = Modifier.toString(modifier); belong to two different packages:
System.out.println("Modifier: " + mod); java.util.Date - this is a normal Date class that can be
// get the number of parameters in constructors used anywhere.
System.out.println("Parameters: " + java.sql.Date - this is a SQL Date used for the SQL
c.getParameterCount()); query and such.
System.out.println(""); } }
catch (Exception e) { Based on whether the package is defined by the user or
e.printStackTrace(); }}} not, packages are divided into two categories:
Here, any class that is declared within the test Once the package is created, a similar folder structure
directory belongs to the com.test package. will be created on your file system as well. Now, you
can create classes, interfaces, and so on inside the
Here's the code: package.
package com.test;
class Test {
public static void main(String[] args){
System.out.println("Hello World!");
}
}
Output:
Hello World!
Here, the Test class now belongs to How to import packages in Java?
the com.test package. Java has an import statement that allows you to
import an entire package (as in earlier examples), or
Package Naming convention use only certain classes and interfaces defined in the
The package name must be unique (like a domain package.
name). Hence, there's a convention to create a package The general form of import statement is:
as a domain name, but in reverse order. For import package.name.ClassName; // To import a
example, com.company.name certain class only
Here, each level of the package is a directory in your import package.name.* // To import the whole
file system. Like this: package
└── com
└── company For example,
└── name import java.util.Date; // imports only Date class
import java.io.*; // imports everything inside
And, there is no limitation on how many java.io package
subdirectories (package hierarchy) you can create.
The import statement is optional in Java.
How to create a package in Intellij IDEA? If you want to use class/interface from a certain
In IntelliJ IDEA, here's how you can create a package: package, you can also use its fully qualified name,
1. Right-click on the source folder. which includes its full package hierarchy.
2. Go to new and then package. Here is an example to import a package using
the import statement.
import java.util.Date;
Output:
formattedValue = $99.50
Here,
1. the Helper class is defined
in com.programiz package. As you can see from the image above,
2. the Helper class is imported to a different file. The file the Throwable class is the root class in the hierarchy.
contains UseHelper class. Note that the hierarchy splits into two branches: Error
3. The getFormattedDollar() method of the Helper class and Exception.
is called from inside the UseHelper class. Errors
Errors represent irrecoverable conditions such as Java
virtual machine (JVM) running out of memory,
memory leaks, stack overflow errors, library
incompatibility, infinite recursion, etc.
Errors are usually beyond the control of the
programmer and we should not try to handle errors.
Exceptions
Java import package Exceptions can be caught and handled by the
program.
In Java, the import statement is written directly after
When an exception occurs within a method, it creates
the package statement (if it exists) and before the class an object. This object is called the exception object.
definition. It contains information about the exception such as
the name and description of the exception and state of
For example, the program when the exception occurred.
package package.name; We will learn how to handle these exceptions in the
import package.ClassName; // only import a Class next tutorial. In this tutorial, we will now focus on
different types of exceptions in Java.
class MyClass {
// body
}
Java Exception Types When an exception occurs, it is caught by
The exception hierarchy also has two the catch block. The catch block cannot be used
branches: RuntimeException and IOException . without the try block.
Example: Exception handling using try...catch
1. RuntimeException class Main {
A runtime exception happens due to a programming public static void main(String[] args) {
error. They are also known as unchecked exceptions.
These exceptions are not checked at compile-time but try {
run-time. Some of the common runtime exceptions
are: // code that generate exception
Improper use of an API - IllegalArgumentException int divideByZero = 5 / 0;
Null pointer access (missing the initialization of System.out.println("Rest of code in try block");
a variable) - NullPointerException }
Out-of-bounds array access -
ArrayIndexOutOfBoundsException catch (ArithmeticException e) {
System.out.println("ArithmeticException => " +
Dividing a number by 0 - ArithmeticException e.getMessage());
You can think about it in this way. "If it is a runtime }
exception, it is your fault". }
The NullPointerException would not have occurred if }
you had checked whether the variable was initialized
or not before using it. Output
An ArrayIndexOutOfBoundsException would not ArithmeticException => / by zero
have occurred if you tested the array index against the In the example, we are trying to divide a number
array bounds. by 0 . Here, this code generates an exception.
To handle the exception, we have put the code, 5 /
2. IOException 0 inside the try block. Now when an exception
An IOException is also known as a checked
occurs, the rest of the code inside the try block is
exception. They are checked by the compiler at the skipped.
compile-time and the programmer is prompted to
The catch block catches the exception and statements
handle these exceptions.
Some of the examples of checked exceptions are: inside the catch block is executed.
Trying to open a file that doesn't exist results If none of the statements in the try block generates an
in FileNotFoundException exception, the catch block is skipped.
Trying to read past the end of a file
Now we know about exceptions, we will learn 2. Java finally block
about handling exceptions in the next tutorial. In Java, the finally block is always executed no matter
whether there is an exception or not.
Java Exception Handling The finally block is optional. And, for each try block,
In the last tutorial, we learned about Java exceptions. there can be only one finally block.
We know that exceptions abnormally terminate the
execution of a program.
The basic syntax of finally block is:
This is why it is important to handle exceptions.
Here's a list of different approaches to handle try {
exceptions in Java. //code
try...catch block }
finally block catch (ExceptionType1 e1) {
throw and throws keyword // catch block
}
finally {
1. Java try...catch block
// finally block always executes
The try-catch block is used to handle exceptions in
}
Java. Here's the syntax of try...catch block:
If an exception occurs, the finally block is executed
try {
// code after the try...catch block. Otherwise, it is executed
} after the try block. For each try block, there can be
catch(Exception e) { only one finally block.
// code
} Example: Java Exception Handling using finally
Here, we have placed the code that might generate an block
exception inside the try block. Every try block is class Main {
followed by a catch block. public static void main(String[] args) {
try {
// code that generates exception Example: Java throws keyword
int divideByZero = 5 / 0; import java.io.*;
}
class Main {
catch (ArithmeticException e) { // declareing the type of exception
System.out.println("ArithmeticException => " + public static void findFile() throws IOException {
e.getMessage());
} // code that may generate IOException
File newFile = new File("test.txt");
finally { FileInputStream stream = new
System.out.println("This is the finally block"); FileInputStream(newFile);
} }
}
} public static void main(String[] args) {
try {
Output findFile();
ArithmeticException => / by zero }
This is the finally block catch (IOException e) {
In the above example, we are dividing a number System.out.println(e);
by 0 inside the try block. Here, this code generates }
an ArithmeticException . }
}
The exception is caught by the catch block. And, then
the finally block is executed. Output
Note: It is a good practice to use the finally block. It is java.io.FileNotFoundException: test.txt (The system
because it can include important cleanup codes like, cannot find the file specified)
code that might be accidentally skipped by When we run this program, if the file test.txt does not
return, continue or break exist, FileInputStream throws
closing a file or connection a FileNotFoundException which extends
the IOException class.
3. Java throw and throws keyword The findFile() method specifies that
The Java throw keyword is used to explicitly throw a an IOException can be thrown. The main() method
single exception. calls this method and handles the exception if it is
When we throw an exception, the flow of the thrown.
If a method does not handle exceptions, the type of
program moves from the try block to the catch block. exceptions that may occur within it must be specified
in the throws clause.
Example: Exception handling using Java throw
class Main {
public static void divideByZero() { Java try...catch
The try...catch block in Java is used to handle
// throw an exception exceptions and prevents the abnormal termination of
throw new ArithmeticException("Trying to divide the program.
by 0"); Here's the syntax of a try...catch block in Java.
} try{
// code
public static void main(String[] args) { }
divideByZero(); catch(exception) {
} // code
} }
Output The try block includes the code that might generate
Exception in thread "main"
an exception.
java.lang.ArithmeticException: Trying to divide by 0
at Main.divideByZero(Main.java:5) The catch block includes the code that is executed
at Main.main(Main.java:9) when there occurs an exception inside the try block.
In the above example, we are explicitly throwing
the ArithmeticException using the throw keyword. Example: Java try...catch block
Similarly, the throws keyword is used to declare the class Main {
public static void main(String[] args) {
type of exceptions that might occur within the method.
It is used in the method declaration.
try {
int divideByZero = 5 / 0;
System.out.println("Rest of code in try block");} Java try...catch...finally block
catch (ArithmeticException e) { In Java, we can also use the finally block after
System.out.println("ArithmeticException => " + the try...catch block. For example,
e.getMessage()); }}} import java.io.*;
Output Output
/ by zero Main.java:6: error: Alternatives in a multi-catch
statement cannot be related by subclassing
Catching multiple exceptions in a single catch block
reduces code duplication and increases efficiency. In this
The bytecode generated while compiling this program example, ArithmeticException and ArrayIndexOutO
will be smaller than the program having fBoundsException are both subclasses of
multiple catch blocks as there is no code redundancy. the Exception class. So, we get a compilation error.
Note: If a catch block handles multiple exceptions,
the catch parameter is implicitly final . This means we
cannot assign any values to catch parameters. Java try-with-resources
The try-with-resources statement automatically closes
Catching base Exception all the resources at the end of the statement. A
When catching multiple exceptions in a resource is an object to be closed at the end of the
single catch block, the rule is generalized to program.
specialized. Its syntax is:
This means that if there is a hierarchy of exceptions in try (resource declaration) {
the catch block, we can catch the base exception only // use of the resource
instead of catching multiple specialized exceptions. } catch (ExceptionType e1) {
Let's take an example. // catch block
Example 3: Catching base exception class only }
class Main {
public static void main(String[] args) { As seen from the above syntax, we declare the try-
try { with-resources statement by,
int array[] = new int[10]; 1. declaring and instantiating the resource within
array[10] = 30 / 0; the try clause.
} catch (Exception e) {
2. specifying and handling all exceptions that might be
System.out.println(e.getMessage());
thrown while closing the resource.
}
Note: The try-with-resources statement closes all the
}
resources that implement the AutoCloseable interface.
}
We know that all the exception classes are subclasses Example 1: try-with-resources
of the Exception class. So, instead of catching import java.io.*;
multiple specialized exceptions, we can simply catch
the Exception class. class Main {
public static void main(String[] args) {
String line;
If the base exception class has already been specified
try(BufferedReader br = new BufferedReader(new
in the catch block, do not use child exception classes FileReader("test.txt"))) {
in the same catch block. Otherwise, we will get a while ((line = br.readLine()) != null) {
compilation error. System.out.println("Line =>"+line);
Let's take an example. }
} catch (IOException e) {
Example 4: Catching base and child exception System.out.println("IOException in try block =>"
classes + e.getMessage());
class Main { }
public static void main(String[] args) { }
try { }
int array[] = new int[10];
array[10] = 30 / 0; Output if the test.txt file is not found.
IOException in try-with-resources block =>test.txt class Main {
(No such file or directory) public static void main(String[] args) {
BufferedReader br = null;
Output if the test.txt file is found. String line;
Entering try-with-resources block
Line =>test line try {
System.out.println("Entering try block");
In this example, we use an instance br = new BufferedReader(new
of BufferedReader to read data from the test.txt file. FileReader("test.txt"));
Declaring and instantiating the BufferedReader inside while ((line = br.readLine()) != null) {
System.out.println("Line =>"+line);
the try-with-resources statement ensures that its }
instance is closed regardless of whether } catch (IOException e) {
the try statement completes normally or throws an System.out.println("IOException in try block =>"
exception. + e.getMessage());
If an exception occurs, it can be handled using } finally {
the exception handling blocks or the throws keyword. System.out.println("Entering finally block");
try {
Suppressed Exceptions if (br != null) {
In the above example, exceptions can be thrown from br.close();
the try-with-resources statement when: }
The file test.txt is not found. } catch (IOException e) {
System.out.println("IOException in finally block
Closing the BufferedReader object. =>"+e.getMessage());
An exception can also be thrown from the try block as }
a file read can fail for many reasons at any time.
AD }
If exceptions are thrown from both the try block and }
the try-with-resources statement, exception from }
the try block is thrown and exception from the try-
Output
with-resources statement is suppressed. Entering try block
Retrieving Suppressed Exceptions Line =>line from test.txt file
In Java 7 and later, the suppressed exceptions can be Entering finally block
retrieved by calling
the Throwable.getSuppressed() method from the As we can see from the above example, the use
exception thrown by the try block. of finally block to clean up resources makes the code
This method returns an array of all suppressed more complex.
exceptions. We get the suppressed exceptions in Notice the try...catch block in the finally block as
the catch block. well? This is because an IOException can also occur
catch(IOException e) { while closing the BufferedReader instance inside
System.out.println("Thrown exception=>" +
this finally block so it is also caught and handled.
e.getMessage());
Throwable[] suppressedExceptions = The try-with-resources statement does automatic
e.getSuppressed(); resource management. We need not explicitly close
for (int i=0; i<suppressedExceptions.length; i++) { the resources as JVM automatically closes them. This
System.out.println("Suppressed exception=>" + makes the code more readable and easier to write.
suppressedExceptions[i]);
} 2. try-with-resources with multiple resources
} We can declare more than one resource in the try-
with-resources statement by separating them with a
Advantages of using try-with-resources semicolon ;
Here are the advantages of using try-with-resources:
1. finally block not required to close the resource
Before Java 7 introduced this feature, we had to use Example 3: try with multiple resources
import java.io.*;
the finally block to ensure that the resource is closed
import java.util.*;
to avoid resource leaks. class Main {
Here's a program that is similar to Example 1. public static void main(String[] args) throws
However, in this program, we have used finally block IOException{
to close resources. try (Scanner scanner = new Scanner(new
Example 2: Close resource using finally block File("testRead.txt"));
import java.io.*;
PrintWriter writer = new PrintWriter(new Example 1: @Override Annotation Example
File("testWrite.txt"))) { class Animal {
while (scanner.hasNext()) { public void displayInfo() {
writer.print(scanner.nextLine()); System.out.println("I am an animal.");
} }
} }
}
} class Dog extends Animal {
@Override
If this program executes without generating any public void displayInfo() {
exceptions, Scanner object reads a line from System.out.println("I am a dog.");
the testRead.txt file and writes it in a }
}
new testWrite.txt file.
When multiple declarations are made, the try-with- class Main {
resources statement closes these resources in reverse public static void main(String[] args) {
order. In this example, the PrintWriter object is closed Dog d1 = new Dog();
d1.displayInfo();
first and then the Scanner object is closed.
}
}
Java 9 try-with-resources enhancement
In Java 7, there is a restriction to the try-with- Output
resources statement. The resource needs to be I am a dog.
declared locally within its block.
try (Scanner scanner = new Scanner(new In this example, the method displayInfo() is present in
File("testRead.txt"))) { both the superclass Animal and subclass Dog . When
// code this method is called, the method of the subclass is
} called instead of the method in the superclass.
If we declared the resource outside the block in Java 7, Annotation formats
it would have generated an error message. Annotations may also include elements
Scanner scanner = new Scanner(new (members/attributes/parameters).
File("testRead.txt"));
try (scanner) {
1. Marker Annotations
// code
Marker annotations do not contain
} members/elements. It is only used for marking a
declaration.
To deal with this error, Java 9 improved the try-with- Its syntax is:
resources statement so that the reference of the @AnnotationName()
resource can be used even if it is not declared locally.
The above code will now execute without any Since these annotations do not contain elements,
compilation error. parentheses can be excluded. For example,
@Override
Java Annotations
Java annotations are metadata (data about data) for 2. Single element Annotations
our program source code. A single element annotation contains only one
They provide additional information about the element.
program to the compiler but are not part of the Its syntax is:
program itself. These annotations do not affect the @AnnotationName(elementName = "elementValue")
execution of the compiled program.
Annotations start with @ . Its syntax is: If there is only one element, it is a convention to name
@AnnotationName that element as value .
@AnnotationName(value = "elementValue")
Let's take an example of @Override annotation.
In this case, the element name can be excluded as
The @Override annotation specifies that the method
well. The element name will be value by default.
that has been marked with this annotation overrides
@AnnotationName("elementValue")
the method of the superclass with the same method
name, return type, and parameter list.
3. Multiple element Annotations
It is not mandatory to use @Override when These annotations contain multiple elements
overriding a method. However, if we use it, the separated by commas.
compiler gives an error if something is wrong (such as
wrong parameter type) while overriding the method. Its syntax is:
@AnnotationName(element1 = "value1", element2 =
"value2") This declaration specifies non-null variable str of
type String to avoid NullPointerException .
Annotation placement @NonNull List<String> newList;
Any declaration can be marked with annotation by
placing it above that declaration. As of Java 8,
This declaration specifies a non-null list of
annotations can also be placed before a type.
type String .
1. Above declarations
As mentioned above, Java annotations can be placed List<@NonNull String> newList;
above class, method, interface, field, and other
program element declarations. This declaration specifies a list of non-null values of
Example 2: @SuppressWarnings Annotation type String .
Example Type casts
import java.util.*; newStr = (@NonNull String) str;
If we add another abstract method, let's say public static void main(String[] args) throws
@FunctionalInterface Exception {
public interface MyFuncInterface{ Main obj = new Main();
public void firstMethod(); // this is an abstract obj.method1();
method }
public void secondMethod(); // this throws compile }
error
} Output
Test method 1
Now, when we run the program, we will get the
following warning: Meta Annotations
Unexpected @FunctionalInterface annotation Meta-annotations are annotations that are applied to
@FunctionalInterface ^ MyFuncInterface is not a other annotations.
functional interface 1. @Retention
multiple non-overriding abstract methods found in The @Retention annotation specifies the level up to
interface MyFuncInterface which the annotation will be available.
Its syntax is:
It is not mandatory to @Retention(RetentionPolicy)
use @FunctionalInterface annotation. The compiler
will consider any interface that meets the functional There are 3 types of retention policies:
interface definition as a functional interface. RetentionPolicy.SOURCE - The annotation is
We use this annotation to make sure that the available only at the source level and is ignored by the
functional interface has only one abstract method. compiler.
However, it can have any number of default and static RetentionPolicy.CLASS - The annotation is available
methods because they have an implementation. to the compiler at compile-time, but is ignored by the
@FunctionalInterface Java Virtual Machine (JVM).
public interface MyFuncInterface{ RetentionPolicy.RUNTIME - The annotation is
public void firstMethod(); // this is an abstract available to the JVM.
method For example,
default void secondMethod() { ... } @Retention(RetentionPolicy.RUNTIME)
default void thirdMethod() { ... } public @interface MyCustomAnnotation{ ... }
}
2. @Documented
Custom Annotations By default, custom annotations are not included in
It is also possible to create our own custom the official Java documentation. To include our
annotations. annotation in the Javadoc documentation, we use
Its syntax is: the @Documented annotation.
[Access Specifier] @interface<AnnotationName> { For example,
DataType <Method Name>() [default value]; @Documented
} public @interface MyCustomAnnotation{ ... }
Here is what you need to know about custom 3. @Target
annotation: We can restrict an annotation to be applied to specific
Annotations can be created by
targets using the @Target annotation.
using @interface followed by the annotation name.
Its syntax is:
The annotation can have elements that look like @Target(ElementType)
methods but they do not have an implementation.
The default value is optional. The parameters cannot
have a null value.
The return type of the method can
be primitive, enum, string, class name or array of these
types.
Example 6: Custom annotation example
@interface MyCustomAnnotation {
String value() default "default value";
The ElementType can have one of the following The value defined in the @Repeatable annotation is
types: the container annotation. The container annotation
has a variable value of array type of the above
Element Type Target repeatable annotation. Here, Universities are the
containing annotation type.
ElementType.ANNOTATION_TYPE Annotation
public @interface Universities {
type
University[] value();
}
ElementType.CONSTRUCTOR Constructors
Disabling Assertions The above switch statement indicates that the days of
To disable assertions, we use: the week can be only one of the above 7 values.
java -da arguments Having no default case means that the programmer
OR believes that one of these cases will always be
java -disableassertions arguments executed.
To disable assertion in system classes, we use: However, there might be some cases that have not yet
java -dsa:arguments been considered where the assumption is actually
OR false.
java -disablesystemassertions:arguments This assumption should be checked using an assertion
to make sure that the default switch case is not
The arguments that can be passed while disabling reached.
assertions are the same as while enabling them. default:
assert false: dayofWeek + " is invalid day";
Advantages of Assertion
1. Quick and efficient for detecting and correcting bugs. If dayOfWeek has a value other than the valid days,
2. Assertion checks are done only during development
an AssertionError is thrown.
and testing. They are automatically removed in the
production code at runtime so that it won’t slow the
execution of the program. 2. Documenting assumptions
3. It helps remove boilerplate code and make code more To document their underlying assumptions, many
readable. programmers use comments. Let’s take an example.
4. Refactors and optimizes code with increased if (i % 2 == 0) {
confidence that it functions correctly. ...
} else { // We know (i % 2 == 1)
When to use Assertions ...
1. Unreachable codes }
Unreachable codes are codes that do not execute when
we try to run the program. Use assertions to make sure Use assertions instead.
unreachable codes are actually unreachable. Comments can get out-of-date and out-of-sync as the
Let’s take an example. program grows. However, we will be forced to update
void unreachableCodeMethod() { the assert statements; otherwise, they might fail for
System.out.println("Reachable code"); valid conditions too.
return; if (i % 2 == 0) {
// Unreachable code ...
System.out.println("Unreachable code"); } else {
assert false; assert i % 2 == 1 : i;
} ...
}
Let’s take another example of a switch statement
without a default case.
When not to use Assertions
1. Argument checking in public methods Java List
Arguments in public methods may be provided by the
user.
So, if an assertion is used to check these arguments,
the conditions may fail and result in AssertionError .
Java Collections Framework
The Java collections framework provides a set of
Instead of using assertions, let it result in the
interfaces and classes to implement various data
appropriate runtime exceptions and handle these
structures and algorithms.
exceptions.
For example, the LinkedList class of the collections
2. To evaluate expressions that affect the program framework provides the implementation of the doubly-
operation linked list data structure.
Do not call methods or evaluate exceptions that can
later affect the program operation in assertion Interfaces of Collections FrameWork
conditions. The Java collections framework provides various
Let us take an example of a list weekdays which interfaces. These interfaces include several methods to
perform different operations on collections.
contains the names of all the days in a week.
In this way, we can ensure that all the weekends are As mentioned earlier, the Collection interface
removed from the weekdays regardless of the includes subinterfaces that are implemented by Java
assertion being enabled or disabled. As a result, it does classes.
not affect the program operation in the future. All the methods of the Collection interface are also
present in its subinterfaces.
Here are the subinterfaces of the Collection Interface:
List Interface
The List interface is an ordered collection that allows
us to add and remove elements like an array.
Set Interface ArrayList: [Dog, Cat, Horse]
The Set interface allows us to store elements in
different sets similar to the set in mathematics. It In the later tutorials, we will learn about the
cannot have duplicate elements. collections framework (its interfaces and classes) in
detail with the help of examples.
Queue Interface
The Queue interface is used when we want to store Java Collection Interface
and access elements in First In, First Out manner. The Collection interface is the root interface of the
Java collections framework.
Java Map Interface There is no direct implementation of this interface.
In Java, the Map interface allows elements to be However, it is implemented through its subinterfaces
stored in key/value pairs. Keys are unique names that like List , Set , and Queue .
can be used to access a particular element in a map. For example, the ArrayList class implements
And, each key has a single value associated with it. the List interface which is a subinterface of
the Collection Interface.
Java Iterator Interface
In Java, the Iterator interface provides methods that
can be used to access elements of collections.
Output
ArrayList: [Java, Python, Swift]
push() Method
class Main {
public static void main(String[] args) {
Stack<String> animals= new Stack<>();
pop() Method
To remove an element from the top of the stack, we
use the pop() method. For example,
import java.util.Stack;
class Main {
public static void main(String[] args) {
Stack<String> animals= new Stack<>();
Here, Type indicates the stack's type. For example, peek() Method
// Create Integer type stack The peek() method returns an object from the top of
Stack<Integer> stacks = new Stack<>(); the stack. For example,
import java.util.Stack;
System.out.println("Stack: " + animals);
class Main {
public static void main(String[] args) { // Check if stack is empty
Stack<String> animals= new Stack<>(); boolean result = animals.empty();
System.out.println("Is the stack empty? " +
// Add elements to Stack result);
animals.push("Dog"); }
animals.push("Horse"); }
animals.push("Cat");
System.out.println("Stack: " + animals); Output
Stack: [Dog, Horse, Cat]
// Access element from the top Is the stack empty? False
String element = animals.peek();
System.out.println("Element at top: " + element); Use ArrayDeque Instead of Stack
The Stack class provides the direct implementation of
} the stack data structure. However, it is recommended
} not to use it. Instead, use the ArrayDeque class
Output (implements the Deque interface) to implement the
Stack: [Dog, Horse, Cat] stack data structure in Java.
Element at top: Cat
search() Method
To search an element in the stack, we use Java Queue
the search() method. It returns the position of the
element from the top of the stack. For example,
import java.util.Stack;
Java Queue Interface
class Main { The Queue interface of the Java collections
public static void main(String[] args) {
framework provides the functionality of the queue
Stack<String> animals= new Stack<>();
data structure. It extends the Collection interface.
// Add elements to Stack
animals.push("Dog"); Classes that Implement Queue
animals.push("Horse"); Since the Queue is an interface, we cannot provide
animals.push("Cat"); the direct implementation of it.
System.out.println("Stack: " + animals); In order to use the functionalities of Queue , we need
to use classes that implement it:
// Search an element ArrayDeque
int position = animals.search("Horse"); LinkedList
System.out.println("Position of Horse: " + PriorityQueue
position);
}
}
Output
Stack: [Dog, Horse, Cat]
Position of Horse: 2
empty() Method
To check whether a stack is empty or not, we use Interfaces that extend Queue
the empty() metho The Queue interface is also extended by various
d. For example, subinterfaces:
import java.util.Stack; Deque
class Main { BlockingQueue
public static void main(String[] args) { BlockingDeque
Stack<String> animals= new Stack<>();
class Main {
class Main {
Java PriorityQueue public static void main(String[] args) {
The PriorityQueue class provides the functionality of
the heap data structure. // Creating a priority queue
It implements the Queue interface. PriorityQueue<Integer> numbers = new
PriorityQueue<>();
Output
PriorityQueue: [2, 4]
Updated PriorityQueue: [1, 4, 2]
Unlike normal queues, priority queue elements are
Here, we have created a priority queue
retrieved in sorted order.
Suppose, we want to retrieve elements in the named numbers . We have inserted 4 and 2 to the
ascending order. In this case, the head of the priority queue.
queue will be the smallest element. Once this element Although 4 is inserted before 2, the head of the queue
is retrieved, the next smallest element will be the head is 2. It is because the head of the priority queue is the
of the queue. smallest element of the queue.
It is important to note that the elements of a priority We have then inserted 1 to the queue. The queue is
queue may not be sorted. However, elements are now rearranged to store the smallest element 1 to the
always retrieved in sorted order. head of the queue.
In the above example, we have created a priority Besides methods available in the Queue interface,
queue passing CustomComparator class as an the Deque interface also includes the following
argument. methods:
The CustomComparator class implements
addFirst() - Adds the specified element at the
the Comparator interface. beginning of the deque. Throws an exception if the
We then override the compare() method. The method deque is full.
now causes the head of the element to be the largest
number. addLast() - Adds the specified element at the end of
the deque. Throws an exception if the deque is full.
Java Deque Interface
The Deque interface of the Java collections offerFirst() - Adds the specified element at the
framework provides the functionality of a double- beginning of the deque. Returns false if the deque is
ended queue. It extends the Queue interface. full.
offerLast() - Adds the specified element at the end of
Working of Deque
In a regular queue, elements are added from the rear the deque. Returns false if the deque is full.
and removed from the front. However, in a deque, we
can insert and remove elements from both front and getFirst() - Returns the first element of the deque.
rear. Throws an exception if the deque is empty.
getLast() - Returns the last element of the deque.
Throws an exception if the deque is empty.
peekFirst() - Returns the first element of the deque.
Classes that implement Deque Returns null if the deque is empty.
In order to use the functionalities of
the Deque interface, we need to use classes that peekLast() - Returns the last element of the deque.
implement it: Returns null if the deque is empty.
ArrayDeque
LinkedList
removeFirst() - Returns and removes the first element
of the deque. Throws an exception if the deque is
empty.
removeLast() - Returns and removes the last element
of the deque. Throws an exception if the deque is
empty.
pollFirst() - Returns and removes the first element of
the deque. Returns null if the deque is empty.
How to use Deque? pollLast() - Returns and removes the last element of
In Java, we must import the java.util.Deque package the deque. Returns null if the deque is empty.
to use Deque .
// Array implementation of Deque Deque as Stack Data Structure
Deque<String> animal1 = new ArrayDeque<>(); The Stack class of the Java Collections
framework provides the implementation of the stack.
// LinkedList implementation of Deque However, it is recommended to use Deque as a stack
Deque<String> animal2 = new LinkedList<>(); instead of the Stack class. It is because methods
of Stack are synchronized.
Here, we have created
Here are the methods the Deque interface provides to
objects animal1 and animal2 of
implement stack:
classes ArrayDeque and LinkedList , respectively. push() - adds an element at the beginning of deque
pop() - removes an element from the beginning of
deque
peek() - returns an element from the beginning of
deque
Implementation of Deque in ArrayDeque Class
import java.util.Deque;
import java.util.ArrayDeque;
class Main {
Java Doubly LinkedList
public static void main(String[] args) { Each element in a linked list is known as a node. It
// Creating Deque using the ArrayDeque class consists of 3 fields:
Deque<Integer> numbers = new Prev - stores an address of the previous element in the
ArrayDeque<>();
list. It is null for the first element
// add elements to the Deque Next - stores an address of the next element in the list.
numbers.offer(1); It is null for the last element
numbers.offerLast(2); Data - stores the actual data
numbers.offerFirst(3);
System.out.println("Deque: " + numbers); Creating a Java LinkedList
Here is how we can create linked lists in Java:
// Access elements of the Deque LinkedList<Type> linkedList = new LinkedList<>();
int firstElement = numbers.peekFirst();
System.out.println("First Element: " + Here, Type indicates the type of a linked list. For
firstElement); example,
// create Integer type linked list
int lastElement = numbers.peekLast(); LinkedList<Integer> linkedList = new
System.out.println("Last Element: " + LinkedList<>();
lastElement); // create String type linked list
LinkedList<String> linkedList = new LinkedList<>();
// Remove elements from the Deque
int removedNumber1 = numbers.pollFirst(); Example: Create LinkedList in Java
System.out.println("Removed First Element: " + import java.util.LinkedList;
removedNumber1);
class Main {
int removedNumber2 = numbers.pollLast(); public static void main(String[] args){
System.out.println("Removed Last Element: " +
removedNumber2); // create linkedlist
LinkedList<String> animals = new LinkedList<>();
System.out.println("Updated Deque: " +
numbers); // Add elements to LinkedList
} animals.add("Dog");
} animals.add("Cat");
animals.add("Cow");
System.out.println("LinkedList: " + animals);
Output }
Deque: [3, 1, 2] }
First Element: 3
Last Element: 2 Output
Removed First Element: 3 LinkedList: [Dog, Cat, Cow]
Removed Last Element: 2
Updated Deque: [1] In the above example, we have created
a LinkedList named animals .
Java LinkedList
Here, we have used the add() method to add elements
The LinkedList class of the Java collections
to the LinkedList. We will learn more about
framework provides the functionality of the linked list
the add() method later in this tutorial.
data structure (doubly linkedlist).
Working of a Java LinkedList
Elements in linked lists are not stored in sequence.
Instead, they are scattered and connected through
links (Prev and Next).
Java LinkedList Implementation In the above example, we have created a LinkedList
Here we have 3 elements in a linked list. named animals . Here, we have used
Dog - it is the first element that holds null as previous the add() method to add elements to animals .
address and the address of Cat as the next address Notice the statement,
Cat - it is the second element that holds an address animals.add(1, "Horse");
of Dog as the previous address and the address
Here, we have used the index number parameter. It is
of Cow as the next address an optional parameter that specifies the position where
Cow - it is the last element that holds the address the new element is added.
of Cat as the previous address and null as the next
element
2. Access LinkedList elements
The get() method of the LinkedList class is used to
Methods of Java LinkedList access an element from the LinkedList. For example,
LinkedList provides various methods that allow us to import java.util.LinkedList;
perform different operations in linked lists. We will
look at four commonly used LinkedList Operators in class Main {
this tutorial: public static void main(String[] args) {
Add elements LinkedList<String> languages = new
Access elements LinkedList<>();
Change elements
Remove elements // add elements in the linked list
languages.add("Python");
1. Add elements to a LinkedList languages.add("Java");
We can use the add() method to add an element languages.add("JavaScript");
(node) at the end of the LinkedList. For example, System.out.println("LinkedList: " + languages);
import java.util.LinkedList;
// get the element from the linked list
class Main { String str = languages.get(1);
public static void main(String[] args){ System.out.print("Element at index 1: " + str);
// create linkedlist }
LinkedList<String> animals = new LinkedList<>(); }
Output Output
ArrayDeque: [Dog, Cat, Horse] ArrayDeque: [Dog, Cat, Cow, Horse]
Head Element: Dog Removed Element: Dog
First Element: Dog New ArrayDeque: [Cat, Cow, Horse]
Removed First Element: Cat ArrayDeque<String> animals= new
Removed Last Element: Horse ArrayDeque<>();
animals.add("Dog");
2. Remove elements using the poll(), pollFirst() and animals.add("Cat");
pollLast() method animals.add("Horse");
poll() - returns and removes the first element of the System.out.println("ArrayDeque: " + animals);
array deque
pollFirst() - returns and removes the first element of // Using clear()
animals.clear();
the array deque (equivalent to poll() )
pollLast() - returns and removes the last element of System.out.println("New ArrayDeque: " +
the array deque animals);
}
Note: If the array deque is }
empty, poll(), pollFirst() and pollLast() returns null if
the element is not found. Output
For example, ArrayDeque: [Dog, Cat, Horse]
import java.util.ArrayDeque; New ArrayDeque: []
class Main {
public static void main(String[] args) {
ArrayDeque<String> stack = new
ArrayDeque<>();
Implementation of BlockingQueue in
ArrayBlockingQueue
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
ArrayBlockingQueue: [Dog, Cat, Horse]
Creating ArrayBlockingQueue
In order to create an array blocking queue, we must Access Elements
import peek() - Returns an element from the front of the array
the java.util.concurrent.ArrayBlockingQueue package. blocking queue. It returns null if the queue is empty.
Once we import the package, here is how we can iterator() - Returns an iterator object to sequentially
create an array blocking queue in Java: access elements from the array blocking queue. It
ArrayBlockingQueue<Type> animal = new throws an exception if the queue is empty. We must
ArrayBlockingQueue<>(int capacity); import the java.util.Iterator package to use it.
For example,
Here, import java.util.concurrent.ArrayBlockingQueue;
Type - the type of the array blocking queue import java.util.Iterator;
capacity - the size of the array blocking queue
For example, class Main {
// Creating String type ArrayBlockingQueue with size public static void main(String[] args) {
5 ArrayBlockingQueue<String> animals = new
ArrayBlockingQueue<String> animals = new ArrayBlockingQueue<>(5);
ArrayBlockingQueue<>(5);
// Add elements
// Creating Integer type ArrayBlockingQueue with animals.add("Dog");
size 5 animals.add("Cat");
ArrayBlockingQueue<Integer> age = new animals.add("Horse");
ArrayBlockingQueue<>(5); System.out.println("ArrayBlockingQueue: " +
animals);
Note: It is compulsory to provide the size of the array.
// Using peek()
Methods of ArrayBlockingQueue String element = animals.peek();
The ArrayBlockingQueue class provides the System.out.println("Accessed Element: " +
implementation of all the methods in element);
the BlockingQueue interface.
These methods are used to insert, access and delete // Using iterator()
elements from array blocking queues. Iterator<String> iterate = animals.iterator();
Also, we will learn about two System.out.print("ArrayBlockingQueue
methods put() and take() that support the blocking Elements: ");
operation in the array blocking queue.
These two methods distinguish the array blocking while(iterate.hasNext()) {
queue from other typical queues. System.out.print(iterate.next());
System.out.print(", ");
Insert Elements }
add() - Inserts the specified element to the array }
blocking queue. It throws an exception if the queue is }
full.
offer() - Inserts the specified element to the array Output
blocking queue. It returns false if the queue is full. ArrayBlockingQueue: [Dog, Cat, Horse]
For example, Accessed Element: Dog
import java.util.concurrent.ArrayBlockingQueue; ArrayBlockingQueue Elements: Dog, Cat, Horse,
Output
Why use ArrayBlockingQueue?
The ArrayBlockingQueue uses arrays as its internal Note: It is not compulsory to provide the size of the
storage. linked list.
It is considered as a thread-safe collection. Hence, it is
generally used in multi-threading applications. Methods of LinkedBlockingQueue
Suppose, one thread is inserting elements to the queue The LinkedBlockingQueue class provides the
and another thread is removing elements from the implementation of all the methods in
queue. the BlockingQueue interface.
Now, if the first thread is slower than the second These methods are used to insert, access and delete
thread, then the array blocking queue can make the elements from linked blocking queues.
second thread waits until the first thread completes its Also, we will learn about two
operations. methods put() and take() that support the blocking
operation in the linked blocking queue.
These two methods distinguish the linked blocking
Java LinkedBlockingQueue queue from other typical queues.
class Main {
public static void main(String[] args) {
LinkedBlockingQueue<String> animals = new
LinkedBlockingQueue<>(5);
// Using add()
animals.add("Dog");
Creating LinkedBlockingQueue animals.add("Cat");
In order to create a linked blocking queue, we must
import // Using offer()
the java.util.concurrent.LinkedBlockingQueue packag animals.offer("Horse");
e. System.out.println("LinkedBlockingQueue: " +
Here is how we can create a linked blocking queue in animals);
Java: }
}
1. Without the initial capacity
LinkedBlockingQueue<Type> animal = new Output
LinkedBlockingQueue<>(); LinkedBlockingQueue: [Dog, Cat, Horse]
animals.add("Dog"); Output
animals.add("Cat"); LinkedBlockingQueue: [Dog, Cat]
animals.add("Horse");
System.out.println("LinkedBlockingQueue " + Here, the put() method may throw
animals); an InterruptedException if it is interrupted while
waiting. Hence, we must enclose it inside a try..catch
// Using remove() block.
String element1 = animals.remove();
System.out.println("Removed Element:"); take() Method
System.out.println("Using remove(): " + To return and remove an element from the front of the
element1); linked blocking queue, we can use the take() method.
If the linked blocking queue is empty, it waits until
// Using poll() there are elements in the linked blocking queue to be
String element2 = animals.poll(); deleted.
System.out.println("Using poll(): " + element2); For example,
import java.util.concurrent.LinkedBlockingQueue;
// Using clear()
animals.clear(); class Main {
System.out.println("Updated public static void main(String[] args) {
LinkedBlockingQueue " + animals); LinkedBlockingQueue<String> animals = new
} LinkedBlockingQueue<>(5);
try {
//Add elements to animals
Java Map
animals.put("Dog");
animals.put("Cat"); Java Map Interface
System.out.println("LinkedBlockingQueue: " + The Map interface of the Java collections
animals); framework provides the functionality of the map data
structure.
// Remove an element
String element = animals.take(); Working of Map
System.out.println("Removed Element: " + In Java, elements of Map are stored
element); in key/value pairs. Keys are unique values associated
System.out.println("New with individual Values.
LinkedBlockingQueue: " + animals); A map cannot contain duplicate keys. And, each key
} is associated with a single value.
catch(Exception e) {
System.out.println(e);
}
}
}
Output
LinkedBlockingQueue: [Dog, Cat]
Removed Element: Dog
New LinkedBlockingQueue: [Cat]
class Main {
class Main {
Create a HashMap public static void main(String[] args) {
In order to create a hash map, we must import
the java.util.HashMap package first. Once we import // create a hashmap
the package, here is how we can create hashmaps in HashMap<String, Integer> numbers = new
Java. HashMap<>();
// hashMap creation with 8 capacity and 0.6 load System.out.println("Initial HashMap: " + numbers);
factor // put() method to add elements
HashMap<K, V> numbers = new HashMap<>(); numbers.put("One", 1);
numbers.put("Two", 2);
In the above code, we have created a hashmap numbers.put("Three", 3);
named numbers. Here, K represents the key type System.out.println("HashMap after put(): " +
and V represents the type of values. For example, numbers);
}
HashMap<String, Integer> numbers = new }
HashMap<>();
Output
Here, the type of keys is String and the type Initial HashMap: {}
of values is Integer. HashMap after put(): {One=1, Two=2, Three=3}
In the above example, we have created
a HashMap named numbers. Here, we have used // return set view of key/value pairs
the put() method to add elements to numbers. // using entrySet()
Notice the statement, System.out.println("Key/Value mappings: " +
languages.entrySet());
numbers.put("One", 1); }
}
Here, we are passing the String value One as the key
and Integer value 1 as the value to the put() method. Output
HashMap: {1=Java, 2=Python, 3=JavaScript}
2. Access HashMap Elements Keys: [1, 2, 3]
We can use the get() method to access the value from Values: [Java, Python, JavaScript]
the hashmap. For example, Key/Value mappings: [1=Java, 2=Python,
import java.util.HashMap; 3=JavaScript]
Here, the remove() method takes the key as its // create a HashMap
parameter. It then returns the value associated with HashMap<Integer, String> languages = new
the key and removes the entry. HashMap<>();
We can also remove the entry only under certain languages.put(1, "Java");
conditions. For example, languages.put(2, "Python");
languages.put(3, "JavaScript");
remove(2, "C++"); System.out.println("HashMap: " + languages);
Here, the remove() method only removes the entry if // iterate through keys only
the key 2 is associated with the value C++. Since 2 is System.out.print("Keys: ");
not associated with C++, it doesn't remove the entry. for (Integer key : languages.keySet()) {
System.out.print(key);
Other Methods of Method System.out.print(", ");
HashMap Description }
clear() removes all compute() computes
mappings from the a new value for the // iterate through values only
HashMap specified key System.out.print("\nValues: ");
computeIfAbsent() computeIfPresent() for (String value : languages.values()) {
computes value if computes a value System.out.print(value);
a mapping for the key is for mapping if the key is System.out.print(", ");
not present present }
merge()merges the clone() makes the copy of
specified mapping to the the HashMap // iterate through key/value entries
HashMap System.out.print("\nEntries: ");
containsKey() checks if containsValue() for (Entry<Integer, String> entry :
the specified key is checks if languages.entrySet()) {
present in Hashmap Hashmap contains the System.out.print(entry);
specified value System.out.print(", ");
size() returns the isEmpty() checks if }
number of items in the Hashmap is empty }
HashMap }
Other Methods of Method
HashMap Description Output
clear() removes all compute() computes HashMap: {1=Java, 2=Python, 3=JavaScript}
mappings from the a new value for the Keys: 1, 2, 3,
HashMap specified key Values: Java, Python, JavaScript,
computeIfAbsent() computeIfPresent()
Entries: 1=Java, 2=Python, 3=JavaScript,
computes value if computes a value
a mapping for the key is for mapping if the key is
not present present
merge()merges the clone() makes the copy of
Note that we have used the Map.Entry in the above Java LinkedHashMap
example. It is the nested class of the Map interface that The LinkedHashMap class of the Java collections
returns a view (elements) of the map. framework provides the hash table and linked
list implementation of the Map interface.
We first need to import
The LinkedHashMap class extends the HashMap class
the java.util.Map.Entry package in order to use this to store its entries in a hash table. It internally
class. maintains a doubly-linked list among all of its entries
This nested class returns a view (elements) of the map. to order its entries.
class Main {
public static void main(String[] args) {
// create a treemap
TreeMap<String, Integer> evenNumbers = new
TreeMap<>();
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
System.out.println("TreeMap: " + evenNumbers); Creating a LinkedHashMap
In order to create a linked hashmap, we must import
// create hashmap from the treemap the java.util.LinkedHashMap package first. Once we
HashMap<String, Integer> numbers = new import the package, here is how we can create linked
hashmaps in Java.
HashMap<>(evenNumbers);
numbers.put("Three", 3);
System.out.println("HashMap: " + numbers); // LinkedHashMap with initial capacity 8 and load
} factor 0.6
} LinkedHashMap<Key, Value> numbers = new
LinkedHashMap<>(8, 0.6f);
Output
TreeMap: {Four=4, Two=2} In the above code, we have created a linked hashmap
HashMap: {Two=2, Three=3, Four=4} named numbers.
Here,
In the above example, we have created Key - a unique identifier used to associate each
element (value) in a map
a TreeMap named evenNumbers. Notice the
expression, Value - elements associated by the keys in a map
Notice the part new LinkedHashMap<>(8, 0.6). Here,
numbers = new HashMap<>(evenNumbers) the first parameter is capacity and the second
parameter is loadFactor.
Here, we are creating a HashMap named numbers capacity - The capacity of this linked hashmap is 8.
using the TreeMap. Meaning, it can store 8 entries.
Note: While creating a hashmap, we can include loadFactor - The load factor of this linked hashmap is
optional parameters: capacity and load factor. For 0.6. This means, whenever our hash map is filled by
example, 60%, the entries are moved to a new hash table of
double the size of the original hash table.
HashMap<K, V> numbers = new HashMap<>(8, Default capacity and load factor
0.6f); It's possible to create a linked hashmap without
defining its capacity and load factor. For example,
Here, //LinkedHashMap with default capacity and load
8 (capacity is 8) - This means it can store 8 entries. factor
LinkedHashMap<Key, Value> numbers1 = new
0.6f (load factor is 0.6) - This means whenever our
hash table is filled by 60%, the entries are moved to a LinkedHashMap<>();
new hash table double the size of the original hash
table. By default,
If the optional parameters not used, then the the capacity of the linked hashmap will be 16
the load factor will be 0.75
default capacity will be 16 and the default load
factor will be 0.75. Note: The LinkedHashMap class also allows us to
define the order of its entries. For example
// LinkedHashMap with specified order evenNumbers.put("Four", 4);
LinkedHashMap<Key, Value> numbers2 = new System.out.println("Original LinkedHashMap: "
LinkedHashMap<>(capacity, loadFactor, + evenNumbers);
accessOrder);
// Using putIfAbsent()
Here, accessOrder is a boolean value. Its default value evenNumbers.putIfAbsent("Six", 6);
is false. In this case entries in the linked hashmap are System.out.println("Updated LinkedHashMap():
ordered on the basis of their insertion order. " + evenNumbers);
However, if true is passed as accessOrder, entries in
the linked hashmap will be ordered from least-recently //Creating LinkedHashMap of numbers
accessed to most-recently accessed. LinkedHashMap<String, Integer> numbers =
new LinkedHashMap<>();
Creating LinkedHashMap from Other Maps numbers.put("One", 1);
Here is how we can create a linked hashmap
containing all the elements of other maps. // Using putAll()
import java.util.LinkedHashMap; numbers.putAll(evenNumbers);
System.out.println("New LinkedHashMap: " +
class Main { numbers);
public static void main(String[] args) { }
// Creating a LinkedHashMap of even numbers }
LinkedHashMap<String, Integer> evenNumbers
= new LinkedHashMap<>(); Output
evenNumbers.put("Two", 2); Original LinkedHashMap: {Two=2, Four=4}
evenNumbers.put("Four", 4); Updated LinkedHashMap: {Two=2, Four=4, Six=6}
System.out.println("LinkedHashMap1: " + New LinkedHashMap: {One=1, Two=2, Four=4,
evenNumbers); Six=6}
class Main {
public static void main(String[] args) {
Java WeakHashMap
The WeakHashMap class of the Java collections
LinkedHashMap<String, Integer> numbers = framework provides the feature of the hash table data
new LinkedHashMap<>(); structure.
numbers.put("One", 1); It implements the Map interface.
numbers.put("Two", 2);
numbers.put("Three", 3); Note: Keys of the weak hashmap are of
System.out.println("LinkedHashMap: " + the WeakReference type.
numbers); The object of a weak reference type can be garbage
collected in Java if the reference is no longer used in
// remove method with single parameter the program.
int value = numbers.remove("Two"); Let us learn to create a weak hash map first. Then, we
System.out.println("Removed value: " + value); will learn how it differs from a hashmap.
Create a WeakHashMap // Perform garbage collection
In order to create a weak hashmap, we must import System.gc();
the java.util.WeakHashMap package first. Once we
import the package, here is how we can create weak System.out.println("WeakHashMap after garbage
hashmaps in Java. collection: " + numbers);
}
//WeakHashMap creation with capacity 8 and load }
factor 0.6
WeakHashMap<Key, Value> numbers = new Output
WeakHashMap<>(8, 0.6); WeakHashMap: {Four=4, Two=2}
WeakHashMap after garbage collection: {Four}
In the above code, we have created a weak hashmap
named numbers.
Here, As we can see, when the key two of a weak hashmap
Key - a unique identifier used to associate each is set to null and perform garbage collection, the key is
element (value) in a map removed.
Value - elements associated by keys in a map It is because unlike hashmaps, keys of weak hashmaps
Notice the part new WeakHashMap<>(8, 0.6). Here, are of weak reference type. This means the entry of a
the first parameter is capacity and the second map are removed by the garbage collector if the key to
parameter is loadFactor. that entry is no longer used. This is useful to save
capacity - The capacity of this map is 8. Meaning, it resources.
can store 8 entries. Now let us see the same implementation in a
loadFactor - The load factor of this map is 0.6. This hashmap.
means whenever our hash table is filled by 60%, the import java.util.HashMap;
entries are moved to a new hash table of double the
size of the original hash table. class Main {
Default capacity and load factor public static void main(String[] args) {
It is possible to create a weak hashmap without // Creating HashMap of even numbers
defining its capacity and load factor. For example, HashMap<String, Integer> numbers = new
HashMap<>();
// WeakHashMap with default capacity and load
factor String two = new String("Two");
WeakHashMap<Key, Value> numbers1 = new Integer twoValue = 2;
WeakHashMap<>(); String four = new String("Four");
Integer fourValue = 4;
By default,
the capacity of the map will be 16 // Inserting elements
the load factor will be 0.75 numbers.put(two, twoValue);
numbers.put(four, fourValue);
Differences Between HashMap and WeakHashMap System.out.println("HashMap: " + numbers);
Let us see the implementation of a weak hashmap in
Java. // Make the reference null
import java.util.WeakHashMap; two = null;
boolean result = sizes.remove(Size.SMALL, 28); In the above program, notice the statement
System.out.println("Is the entry {SMALL=28} sizes.replaceAll((key, oldValue) -> oldValue + 3);
removed? " + result);
Here, the method accesses all the entries of the map. It
System.out.println("Updated EnumMap: " + then replaces all the values with the new values
sizes); provided by the lambda expressions.
}
}
Output
EnumMap: {SMALL=28, MEDIUM=32,
LARGE=36, EXTRALARGE=40}
Removed Value: 32
Other Methods Class that implements SortedMap
Method Description Since SortedMap is an interface, we cannot create
clone() Creates a copy of the EnumMap objects from it.
containsKey() Searches the EnumMap for the In order to use the functionalities of
specified key and returns a boolean the SortedMap interface, we need to use the
result class TreeMap that implements it.
containsValue() Searches the EnumMap for the
specified value and returns a
boolean result
size() Returns the size of the EnumMap
clear() Removes all the entries from the
EnumMap
class Main {
// Using put()
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
// Using putIfAbsent()
evenNumbers.putIfAbsent("Six", 6);
System.out.println("TreeMap of even numbers: "
+ evenNumbers);
// Using putAll()
numbers.putAll(evenNumbers);
System.out.println("TreeMap of numbers: " +
numbers);
}
}
Here, the getOrDefault() method does not find the // Using replace()
key Five. Hence it returns the specified default value 5. numbers.replace("Second", 22);
numbers.replace("Third", 3, 33);
Remove TeeMap Elements System.out.println("TreeMap using replace: " +
remove(key) - returns and removes the entry numbers);
associated with the specified key from a TreeMap
remove(key, value) - removes the entry from the map // Using replaceAll()
only if the specified key is associated with the specified numbers.replaceAll((key, oldValue) -> oldValue
value and returns a boolean value + 2);
For example, System.out.println("TreeMap using replaceAll: "
import java.util.TreeMap; + numbers);
}
class Main { }
public static void main(String[] args) { Output
Original TreeMap: {First=1, Second=2, Third=3}
TreeMap<String, Integer> numbers = new TreeMap using replace(): {First=1, Second=22,
TreeMap<>(); Third=33}
TreeMap using replaceAll(): {First=3, Second=24, higherEntry() - Returns an entry associated with a key
Third=35} that is lowest among all those keys greater than the
specified key.
In the above program notice the statement lowerKey() - Returns the greatest key among all those
numbers.replaceAll((key, oldValue) -> oldValue + 2); keys that are less than the specified key.
Here, we have passed a lambda expression as an lowerEntry() - Returns an entry associated with a key
argument. that is greatest among all those keys that are less than
The replaceAll() method accesses all the entries of the the specified key.
map. It then replaces all the elements with the new ceilingKey() - Returns the lowest key among those
values (returned from the lambda expression). keys that are greater than the specified key. If the key
passed as an argument is present in the map, it returns
Methods for Navigation that key.
Since the TreeMap class implements NavigableMap, it ceilingEntry() - Returns an entry associated with a key
provides various methods to navigate over the that is lowest among those keys that are greater than
elements of the treemap. the specified key. It an entry associated with the key
passed an argument is present in the map, it returns
1. First and Last Methods the entry associated with that key.
firstKey() - returns the first key of the map floorKey() - Returns the greatest key among those keys
firstEntry() - returns the key/value mapping of the first that are less than the specified key. If the key passed as
key of the map an argument is present, it returns that key.
lastKey() - returns the last key of the map floorEntry() - Returns an entry associated with a key
lastEntry() - returns the key/value mapping of the last that is greatest among those keys that are less than the
key of the map specified key. If the key passed as argument is present,
For example, it returns that key.
import java.util.TreeMap; For example,
Output Output
TreeMap: {First=1, Fourth=2, Second=2, Third=3} TreeMap: {Third=3, Second=2, Fourth=4, First=1}
In the above example, we have created a treemap
Using subMap() Method: passing CustomComparator class as an argument.
Without boolean value: {Fourth=4, Second=2} The CustomComparator class implements
With boolean value: {Second=2, Third=3} the Comparator interface.
We then override the compare() method to sort
Other Methods of TreeMap elements in reverse order.
Method Description
clone() Creates a copy of the
TreeMap Java ConcurrentMap Interface
containsKey() Searches the TreeMap for The ConcurrentMap interface of the Java collections
the specified key and framework provides a thread-safe map. That is,
returns a boolean result multiple threads can access the map at once without
containsValue() Searches the TreeMap for affecting the consistency of entries in a map.
ConcurrentMap is known as a synchronized map. merge() - Merges the new specified value with the old
It extends the Map interface. value of the specified key if the key is already mapped
to a certain value. If the key is not already mapped,
Class that implements ConcurrentMap the method simply associates the specified value to our
Since ConcurrentMap is an interface, we cannot create key.
objects from it.
In order to use the functionalities of Implementation of ConcurrentMap in
the ConcurrentMap interface, we need to use the ConcurrentHashMap
class ConcurrentHashMap that implements it. import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
class Main {
numbers.put("One", 1);
Methods of ConcurrentHashMap numbers.put("Two", 2);
The ConcurrentHashMap class provides methods that numbers.put("Three", 3);
allow us to perform various operations on the map. System.out.println("ConcurrentHashMap: " +
numbers);
// Using entrySet() class Main {
System.out.println("Key/Value mappings: " + public static void main(String[] args) {
numbers.entrySet());
ConcurrentHashMap<String, Integer> numbers
// Using keySet() = new ConcurrentHashMap<>();
System.out.println("Keys: " + numbers.keySet()); numbers.put("One", 1);
numbers.put("Two", 2);
// Using values() numbers.put("Three", 3);
System.out.println("Values: " + System.out.println("ConcurrentHashMap: " +
numbers.values()); numbers);
}
} // remove method with single parameter
int value = numbers.remove("Two");
Output System.out.println("Removed value: " + value);
ConcurrentHashMap: {One=1, Two=2, Three=3}
Key/Value mappings: [One=1, Two=2, Three=3] // remove method with two parameters
Keys: [One, Two, Three] boolean result = numbers.remove("Three", 3);
Values: [1, 2, 3] System.out.println("Is the entry {Three=3}
removed? " + result);
2. Using get() and getOrDefault()
get() - Returns the value associated with the specified System.out.println("Updated
key. Returns null if the key is not found. ConcurrentHashMap: " + numbers);
getOrDefault() - Returns the value associated with the }
specified key. Returns the specified default value if the }
key is not found.
For example, Output
import java.util.concurrent.ConcurrentHashMap; ConcurrentHashMap: {One=1, Two=2, Three=3}
Removed value: 2
class Main { Is the entry {Three=3} removed? True
public static void main(String[] args) { Updated ConcurrentHashMap: {One=1}
class Main {
Output
HashSet: [2, 4, 6]
New HashSet: [2, 4, 5, 6] Set Operations
The various methods of the HashSet class can also be
Access HashSet Elements used to perform various set operations.
To access the elements of a hash set, we can use
the iterator() method. In order to use this method, we Union of Sets
must import the java.util.Iterator package. For To perform the union between two sets, we can use
example, the addAll() method. For example,
Output Output
HashSet: [2, 5, 6] HashSet1: [2, 4]
HashSet using Iterator: 2, 5, 6, HashSet2: [1, 3]
Union is: [1, 2, 3, 4]
Remove Elements
remove() - removes the specified element from the set Intersection of Sets
removeAll() - removes all the elements from the set To perform the intersection between two sets, we can
For example, use the retainAll() method. For example
Subset
Java EnumSet
To check if a set is a subset of another set or not, we The EnumSet class of the Java collections
can use the containsAll() method. For example, framework provides a set implementation of elements
import java.util.HashSet; of a single enum.
Before you learn about EnumSet, make sure to know
class Main { about Java Enums.
public static void main(String[] args) { It implements the Set interface.
HashSet<Integer> numbers = new HashSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
System.out.println("HashSet1: " + numbers);
Other Methods
Method Description
copyOf() Creates a copy of the
EnumSet
contains() Searches the EnumSet for
the specified element and
returns a boolean result
isEmpty() Checks if the EnumSet is
empty
size() Returns the size of the
EnumSet
clear() Removes all the elements
from the EnumSet
Clonable and Serializable Interfaces Elements of LinkedHashSet are stored in hash tables
The EnumSet class also similar to HashSet.
implements Cloneable and Serializable interfaces. However, linked hash sets maintain a doubly-linked
Cloneable Interface list internally for all of its elements. The linked list
It allows the EnumSet class to make a copy of defines the order in which elements are inserted in
instances of the class. hash tables.
Serializable Interface
Whenever Java objects need to be transmitted over a Create a LinkedHashSet
network, objects need to be converted into bits or In order to create a linked hash set, we must import
bytes. This is because Java objects cannot be the java.util.LinkedHashSet package first.
transmitted over the network. Once we import the package, here is how we can
The Serializable interface allows classes to be create linked hash sets in Java.
serialized. This means objects of the classes
implementing Serializable can be converted into bits // LinkedHashSet with 8 capacity and 0.75 load
or bytes. factor
LinkedHashSet<Integer> numbers = new
LinkedHashSet<>(8, 0.75);
Why EnumSet?
The EnumSet provides an efficient way to store enum
Here, we have created a linked hash set
values than other set implementations
named numbers.
(like HashSet, TreeSet).
Notice, the part new LinkedHashSet<>(8, 0.75). Here,
An enum set only stores enum values of a specific
the first parameter is capacity and the second
enum. Hence, the JVM already knows all the possible
parameter is loadFactor.
values of the set.
capacity - The capacity of this hash set is 8. Meaning,
This is the reason why enum sets are internally
it can store 8 elements.
implemented as a sequence of bits. Bits specifies
loadFactor - The load factor of this hash set is 0.6.
whether elements are present in the enum set or not.
This means, whenever our hash table is filled by 60%,
The bit of a corresponding element is turned on if that
the elements are moved to a new hash table of double
element is present in the set.
the size of the original hash table.
By default,
the capacity of the linked hash set will be 16
the load factor will be 0.75
}
Creating LinkedHashSet from Other Collections }
Here is how we can create a linked hash set containing
all the elements of other collections. Output
LinkedHashSet: [2, 4, 6]
import java.util.LinkedHashSet; New LinkedHashSet: [2, 4, 6, 5]
import java.util.ArrayList;
Access LinkedHashSet Elements
class Main { To access the elements of a linked hash set, we can use
public static void main(String[] args) { the iterator()method. In order to use this method, we
// Creating an arrayList of even numbers must import the java.util.Iterator package. For
ArrayList<Integer> evenNumbers = new example,
ArrayList<>();
evenNumbers.add(2); import java.util.LinkedHashSet;
evenNumbers.add(4); import java.util.Iterator;
System.out.println("ArrayList: " +
evenNumbers); class Main {
public static void main(String[] args) {
// Creating a LinkedHashSet from an ArrayList LinkedHashSet<Integer> numbers = new
LinkedHashSet<Integer> numbers = new LinkedHashSet<>();
LinkedHashSet<>(evenNumbers); numbers.add(2);
System.out.println("LinkedHashSet: " + numbers.add(5);
numbers); numbers.add(6);
} System.out.println("LinkedHashSet: " +
} numbers);
class Main {
public static void main(String[] args) { LinkedHashSet Vs. TreeSet
LinkedHashSet<Integer> numbers = new Here are the major differences
LinkedHashSet<>(); between LinkedHashSet and TreeSet:
numbers.add(1); The TreeSet class implements the SortedSet interface.
numbers.add(2); That's why elements in a tree set are sorted. However,
numbers.add(3); the LinkedHashSet class only maintains the insertion
numbers.add(4); order of its elements.
System.out.println("LinkedHashSet1: " + A TreeSet is usually slower than a LinkedHashSet. It
numbers); is because whenever an element is added to a TreeSet,
it has to perform the sorting operation.
LinkedHashSet<Integer> primeNumbers = new LinkedHashSet allows the insertion of null values.
LinkedHashSet<>(); However, we cannot insert a null value to TreeSet.
primeNumbers.add(2);
primeNumbers.add(3);
System.out.println("LinkedHashSet2: " +
primeNumbers); Java SortedSet Interface
// Check if primeNumbers is a subset of numbers The SortedSet interface of the Java collections
boolean result = framework is used to store elements with some order
numbers.containsAll(primeNumbers); in a set.
System.out.println("Is LinkedHashSet2 is subset It extends the Set interface.
of LinkedHashSet1? " + result);
}
}
Output
LinkedHashSet1: [1, 2, 3, 4]
LinkedHashSet2: [2, 3]
Is LinkedHashSet2 is a subset of LinkedHashSet1?
True
Method Description
clone() Creates a copy of the
LinkedHashSet
contains() Searches the
LinkedHashSet for the Class that implements SortedSet
specified element and In order to use the functionalities of
returns a boolean result the SortedSet interface, we need to use
isEmpty() Checks if the the TreeSet class that implements it.
LinkedHashSet is empty
size() Returns the size of the
LinkedHashSet
clear() Removes all the elements
from the LinkedHashSet
Creating a TreeSet
Implementation of NavigableSet in TreeSet Class In order to create a tree set, we must import
import java.util.NavigableSet; the java.util.TreeSet package first.
import java.util.TreeSet; Once we import the package, here is how we can
create a TreeSet in Java.
class Main {
TreeSet<Integer> numbers = new TreeSet<>();
public static void main(String[] args) { Here, we have created a TreeSet without any
// Creating NavigableSet using the TreeSet arguments. In this case, the elements in TreeSet are
NavigableSet<Integer> numbers = new sorted naturally (ascending order).
TreeSet<>(); However, we can customize the sorting of elements by
using the Comparator interface. We will learn about it
// Insert elements to the set later in this tutorial.
Methods of TreeSet
The TreeSet class provides various methods that allow Output
us to perform various operations on the set. TreeSet: [2, 5, 6]
TreeSet using Iterator: 2, 5, 6,
Insert Elements to TreeSet
add() - inserts the specified element to the set Remove Elements
addAll() - inserts all the elements of the specified remove() - removes the specified element from the set
removeAll() - removes all the elements from the set
collection to the set
For example,
For example,
import java.util.TreeSet;
import java.util.TreeSet;
class Main {
class Main {
public static void main(String[] args) {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
TreeSet<Integer> evenNumbers = new
numbers.add(5);
TreeSet<>();
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Using the add() method
evenNumbers.add(2);
// Using the remove() method
evenNumbers.add(4);
boolean value1 = numbers.remove(5);
evenNumbers.add(6);
System.out.println("Is 5 removed? " + value1);
System.out.println("TreeSet: " + evenNumbers);
// Using the removeAll() method
TreeSet<Integer> numbers = new TreeSet<>();
boolean value2 = numbers.removeAll(numbers);
numbers.add(1);
System.out.println("Are all elements removed? "
+ value2);
// Using the addAll() method
}
numbers.addAll(evenNumbers);
}
System.out.println("New TreeSet: " + numbers);
}
Output
}
TreeSet: [2, 5, 6]
Is 5 removed? true
Output
Are all elements removed? True
TreeSet: [2, 4, 6]
New TreeSet: [1, 2, 4, 6]
Methods for Navigation
Since the TreeSet class implements NavigableSet, it
Access TreeSet Elements
provides various methods to navigate over the
To access the elements of a tree set, we can use
elements of the tree set.
the iterator() method. In order to use this method, we
must import java.util.Iterator package. For example,
1. first() and last() Methods
first() - returns the first element of the set
import java.util.TreeSet;
last() - returns the last element of the set
import java.util.Iterator;
For example,
class Main {
import java.util.TreeSet;
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
class Main {
numbers.add(2);
public static void main(String[] args) {
numbers.add(5);
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(6);
numbers.add(2);
System.out.println("TreeSet: " + numbers);
numbers.add(5);
numbers.add(6);
// Calling iterator() method
System.out.println("TreeSet: " + numbers);
Iterator<Integer> iterate = numbers.iterator();
System.out.print("TreeSet using Iterator: ");
// Using the first() method
// Accessing elements
int first = numbers.first();
while(iterate.hasNext()) {
System.out.println("First Number: " + first);
System.out.print(iterate.next());
System.out.print(", ");
// Using the last() method
}
int last = numbers.last();
}
System.out.println("Last Number: " + last);
}
}
} pollLast() - returns and removes the last element from
the set
Output For example,
TreeSet: [2, 5, 6]
First Number: 2 import java.util.TreeSet;
Last Number: 6
class Main {
2. ceiling(), floor(), higher() and lower() Methods public static void main(String[] args) {
higher(element) - Returns the lowest element among TreeSet<Integer> numbers = new TreeSet<>();
those elements that are greater than the numbers.add(2);
specified element. numbers.add(5);
lower(element) - Returns the greatest element among numbers.add(4);
those elements that are less than the specified element. numbers.add(6);
ceiling(element) - Returns the lowest element among System.out.println("TreeSet: " + numbers);
those elements that are greater than the
specified element. If the element passed exists in a tree // Using pollFirst()
set, it returns the element passed as an argument. System.out.println("Removed First Element: " +
floor(element) - Returns the greatest element among numbers.pollFirst());
those elements that are less than the specified element.
If the element passed exists in a tree set, it returns // Using pollLast()
the element passed as an argument. System.out.println("Removed Last Element: " +
For example, numbers.pollLast());
3. pollfirst() and pollLast() Methods // Using headSet() with specified boolean value
pollFirst() - returns and removes the first element from System.out.println("Using headSet with boolean
the set value: " + numbers.headSet(5, true));
}
} numbers.add(4);
numbers.add(6);
Output System.out.println("TreeSet: " + numbers);
TreeSet: [2, 4, 5, 6]
Using headSet without boolean value: [2, 4] // Using subSet() with default boolean value
Using headSet with boolean value: [2, 4, 5] System.out.println("Using subSet without
boolean value: " + numbers.subSet(4, 6));
tailSet(element, booleanValue)
The tailSet() method returns all the elements of a tree // Using subSet() with specified boolean value
set after the specified element (which is passed as a System.out.println("Using subSet with boolean
parameter) including the specified element. value: " + numbers.subSet(4, false, 6, true));
The booleanValue parameter is optional. Its default }
value is true. }
If false is passed as a booleanValue, the method
returns all the elements after the Output
specified element without including the TreeSet: [2, 4, 5, 6]
specified element. Using subSet without boolean value: [4, 5]
For example, Using subSet with boolean value: [5, 6]
3. Routine Data Manipulation Note: While performing the copy() method both the
In Java, the collections framework provides different lists should be of the same size.
methods that can be used to manipulate data.
reverse() - reverses the order of elements 4. Searching Using binarySearch()
fill() - replace every element in a collection with the The binarySearch() method of the Java collections
specified value framework searches for the specified element. It
copy() - creates a copy of elements from the specified returns the position of the element in the specified
source to destination collections. For example,
swap() - swaps the position of two elements in a
collection import java.util.Collections;
addAll() - adds all the elements of a collection to other import java.util.ArrayList;
collection
For example, class Main {
public static void main(String[] args) {
import java.util.Collections; // Creating an ArrayList
import java.util.ArrayList; ArrayList<Integer> numbers = new
ArrayList<>();
class Main { numbers.add(1);
public static void main(String[] args) { numbers.add(2);
// Creating an ArrayList numbers.add(3);
ArrayList<Integer> numbers = new
ArrayList<>(); // Using binarySearch()
numbers.add(1); int pos = Collections.binarySearch(numbers, 3);
numbers.add(2); System.out.println("The position of 3 is " + pos);
System.out.println("ArrayList1: " + numbers); }
}
// Using reverse()
Collections.reverse(numbers); Output
System.out.println("Reversed ArrayList1: " + The position of 3 is 2.
numbers);
Note: The collection should be sorted before
// Using swap() performing the binarySearch() method.
Collections.swap(numbers, 0, 1);
System.out.println("ArrayList1 using swap(): " +
numbers); 5. Composition
frequency() - returns the count of the number of times
ArrayList<Integer> newNumbers = new an element is present in the collection
ArrayList<>(); disjoint() - checks if two collections contain some
common element
// Using addAll For example,
newNumbers.addAll(numbers);
System.out.println("ArrayList2 using addAll(): " import java.util.Collections;
+ newNumbers); import java.util.ArrayList;
The List interface provides a listIterator() method that Example 2: Implementation of ListIterator
returns an instance of the ListIterator interface. In the example below, we have implemented
the previous() and previousIndex() methods of
Methods of ListIterator the ListIterator interface in an array list.
The ListIterator interface provides methods that can
be used to perform various operations on the elements import java.util.ArrayList;
of a list. import java.util.ListIterator;
hasNext() - returns true if there exists an element in
the list class Main {
next() - returns the next element of the list public static void main(String[] args) {
nextIndex() returns the index of the element that // Creating an ArrayList
the next() method will return ArrayList<Integer> numbers = new
previous() - returns the previous element of the list ArrayList<>();
previousIndex() - returns the index of the element that numbers.add(1);
the previous() method will return numbers.add(3);
remove() - removes the element returned by numbers.add(2);
either next() or previous() System.out.println("ArrayList: " + numbers);
set() - replaces the element returned by
either next() or previous() with the specified element // Creating an instance of ListIterator
ListIterator<Integer> iterate =
Example 1: Implementation of ListIterator numbers.listIterator();
In the example below, we have implemented iterate.next();
the next(), nextIndex() and hasNext() methods of iterate.next();
the ListIterator interface in an array list.
// Using the previous() method
import java.util.ArrayList; int number1 = iterate.previous();
import java.util.ListIterator; System.out.println("Previous Element: " +
number1);
class Main {
public static void main(String[] args) { // Using the previousIndex()
// Creating an ArrayList int index1 = iterate.previousIndex();
ArrayList<Integer> numbers = new System.out.println("Position of the Previous
ArrayList<>(); element: " + index1);
numbers.add(1); }
numbers.add(3); }
numbers.add(2);
System.out.println("ArrayList: " + numbers); Output
ArrayList: [1, 3, 2]
Previous Element: 3 Character Stream
Position of the Previous Element: 0
Character Stream
Java I/o Streams Character stream is used to read and write a single
character of data.
All the character stream classes are derived from base
abstract classes Reader and Writer.
Java I/O Streams
In Java, streams are the sequence of data that are read Java InputStream Class
from the source and written to the destination.
An input stream is used to read data from the source. The InputStream class of the java.io package is an
And, an output stream is used to write data to the abstract superclass that represents an input stream of
destination. bytes.
Since InputStream is an abstract class, it is not useful
by itself. However, its subclasses can be used to read
class HelloWorld {
data.
public static void main(String[] args) { Subclasses of InputStream
System.out.println("Hello, World!"); In order to use the functionality of InputStream, we
} can use its subclasses. Some of them are:
} FileInputStream
ByteArrayInputStream
For example, in our first Hello World example, we ObjectInputStream
have used System.out to print a string. Here,
the System.out is a type of output stream.
Similarly, there are input streams to take input.
Create an InputStream
In order to create an InputStream, we must import
We will learn about input streams and output streams
the java.io.InputStream package first. Once we import
in detail in the later tutorials. the package, here is how we can create the input
stream.
// Creates an InputStream
InputStream object1 = new FileInputStream();
Types of Streams
Depending upon the data a stream holds, it can be Here, we have created an input stream
classified into: using FileInputStream. It is because InputStream is an
Byte Stream abstract class. Hence we cannot create an object
of InputStream.
Available bytes in the file: 39
Methods of InputStream Data read from the file:
The InputStream class provides different methods that This is a line of text inside the file
are implemented by its subclasses. Here are some of
the commonly used methods: In the above example, we have created an input
read() - reads one byte of data from the input stream stream using the FileInputStream class. The input
read(byte[] array) - reads bytes from the stream and stream is linked with the file input.txt.
stores in the specified array
available() - returns the number of bytes available in InputStream input = new
the input stream FileInputStream("input.txt");
mark() - marks the position in the input stream up to
which data has been read To read data from the input.txt file, we have
reset() - returns the control to the point in the stream implemented these two methods.
where the mark was set
markSupported() - checks if input.read(array); // to read data from the input
the mark() and reset() method is supported in the stream
stream input.close(); // to close the input stream
skips() - skips and discards the specified number of
bytes from the input stream
close() - closes the input stream Java OutputStream Class
Example: InputStream Using FileInputStream The OutputStream class of the java.io package is an
Here is how we can implement InputStream using abstract superclass that represents an output stream of
the FileInputStream class. bytes.
Suppose we have a file named input.txt with the Since OutputStream is an abstract class, it is not useful
following content. by itself. However, its subclasses can be used to write
data.
This is a line of text inside the file.
Subclasses of OutputStream
Let's try to read this file using FileInputStream (a In order to use the functionality of OutputStream, we
subclass of InputStream). can use its subclasses. Some of them are:
FileOutputStream
import java.io.FileInputStream; ByteArrayOutputStream
import java.io.InputStream; ObjectOutputStream
class Main {
public static void main(String args[]) { Create an OutputStream
In order to create an OutputStream, we must import
byte[] array = new byte[100]; the java.io.OutputStream package first. Once we
import the package, here is how we can create the
try { output stream.
InputStream input = new
FileInputStream("input.txt"); // Creates an OutputStream
OutputStream object = new FileOutputStream();
System.out.println("Available bytes in the file: " +
input.available()); Here, we have created an object of output stream
using FileOutputStream. It is because OutputStream is
// Read byte from the input stream an abstract class, so we cannot create an object
input.read(array); of OutputStream.
System.out.println("Data read from the file: "); Note: We can also create the output stream from other
subclasses of the OutputStream class.
// Convert byte array into string
String data = new String(array); Methods of OutputStream
System.out.println(data); The OutputStream class provides different methods
that are implemented by its subclasses. Here are some
// Close the input stream of the methods:
input.close(); write() - writes the specified byte to the output stream
} catch (Exception e) { write(byte[] array) - writes the bytes from the
e.getStackTrace(); specified array to the output stream
} flush() - forces to write all data present in output
} stream to the destination
} close() - closes the output stream
Output
Example: OutputStream Using FileOutputStream Java FileInputStream Class
Here is how we can implement OutputStream using
the FileOutputStream class The FileInputStream class of the java.io package can
be used to read data (in bytes) from files.
import java.io.FileOutputStream; It extends the InputStream abstract class.
import java.io.OutputStream;
// Creates a ByteArrayInputStream that reads entire Here, the input stream includes all the data from the
array specified array. To read data from the input stream,
ByteArrayInputStream input = new we have used the read() method.
ByteArrayInputStream(byte[] arr);
available() Method
Here, we have created an input stream that reads To get the number of available bytes in the input
entire data from the arr array. However, we can also stream, we can use the available() method. For
create the input stream that reads only some data from example,
the array.
import java.io.ByteArrayInputStream;
// Creates a ByteArrayInputStream that reads a
portion of array public class Main {
ByteArrayInputStream input = new
ByteArrayInputStream(byte[] arr, int start, int length); public static void main(String args[]) {
Here the input stream reads the number of bytes equal // Creates an array of bytes
to length from the array starting from byte[] array = { 1, 2, 3, 4 };
the start position.
try {
Methods of ByteArrayInputStream ByteArrayInputStream input = new
The ByteArrayInputStream class provides ByteArrayInputStream(array);
implementations for different methods present in
the InputStream class. // Returns the available number of bytes
read() Method System.out.println("Available bytes at the
read() - reads the single byte from the array present in beginning: " + input.available());
the input stream
read(byte[] array) - reads bytes from the input stream // Reads 2 bytes from the input stream
and stores in the specified array input.read();
read(byte[] array, int start, int length) - reads the input.read();
number of bytes equal to length from the stream and
stores in the specified array starting from the // Returns the available number of bytes
position start System.out.println("Available bytes at the end: " +
input.available());
Example: ByteArrayInputStream to read data
input.close();
import java.io.ByteArrayInputStream;
}
public class Main {
catch (Exception e) {
public static void main(String[] args) {
e.getStackTrace();
// Creates an array of byte
} }}
Output methods of this class even after the close() method is
Available bytes at the beginning: 4 called.
Available bytes at the end: 2
Other Methods Of ByteArrayInputStream
In the above example, Methods Descriptions
We have used the available() method to check the finalize() ensures that the close()
number of available bytes in the input stream. method is called
We have then used the read() method 2 times to read 2 mark() marks the position in
bytes from the input stream. input stream up to which
Now, after reading the 2 bytes, we have checked the data has been read
available bytes. This time the available bytes decreased reset() returns the control to the
by 2. point in the input stream
where the mark was set
skip() Method markSupported() checks if the input stream
To discard and skip the specified number of bytes, we supports mark() and
can use the skip() method. For example, reset()
import java.io.ByteArrayInputStream;
String data = "This is a line of text inside the // Returns an array of bytes
string."; byte[] byteData = out.toByteArray();
System.out.print("Data using toByteArray(): ");
try { for(int i=0; i<byteData.length; i++) {
// Creates an output stream System.out.print((char)byteData[i]);
ByteArrayOutputStream out = new }
ByteArrayOutputStream();
byte[] array = data.getBytes(); // Returns a string
String stringData = out.toString();
// Writes data to the output stream System.out.println("\nData using toString(): " +
out.write(array); stringData);
catch(Exception e) { Output
e.getStackTrace(); Data using toByteArray(): This is data.
} Data using toString(): This is data.
}
} In the above example, we have created an array of
bytes to store the data returned by
Output the toByteArray() method.
Output stream: This is a line of text inside the string. We then have used the for loop to access each byte
from the array. Here, each byte is converted into the
In the above example, we have created a byte array corresponding character using typecasting.
output stream named output.
close() Method
ByteArrayOutputStream output = new To close the output stream, we can use
ByteArrayOutputStream(); the close() method.
However, the close() method has no effect
To write the data to the output stream, we have used in ByteArrayOutputStream class. We can use the
the write() method. methods of this class even after the close() method is
called.
Note: The getBytes() method used in the program
converts a string into an array of bytes. Other Methods of ByteArrayOutputStream
Methods Descriptions
Access Data from ByteArrayOutputStream size() returns the size of the
toByteArray() - returns the array present inside the array in the output stream
output stream flush() clears the output stream
Java ObjectInputStream Class class Main {
public static void main(String[] args) {
The ObjectInputStream class of the java.io package
can be used to read objects that were previously int data1 = 5;
written by ObjectOutputStream. String data2 = "This is programiz";
read() Method
Java BufferedInputStream Class read() - reads a single byte from the input stream
read(byte[] arr) - reads bytes from the stream and
The BufferedInputStream class of the java.io package stores in the specified array
is used with other input streams to read the data (in read(byte[] arr, int start, int length) - reads the number
bytes) more efficiently. of bytes equal to the length from the stream and stores
in the specified array starting from the position start
It extends the InputStream abstract class. AD
Suppose we have a file named input.txt with the
following content.
This is a line of text inside the file.
Let's try to read the file using BufferedInputStream.
import java.io.BufferedInputStream;
import java.io.FileInputStream;
class Main {
public static void main(String[] args) {
try {
// Creates a FileInputStream
FileInputStream file = new
FileInputStream("input.txt");
Working of BufferedInputStream
The BufferedInputStream maintains an internal buffer // Creates a BufferedInputStream
of 8192 bytes. BufferedInputStream input = new
During the read operation in BufferedInputStream, a BufferedInputStream(file);
chunk of bytes is read from the disk and stored in the
internal buffer. And from the internal buffer bytes are // Reads first byte from file
read individually. int i = input .read();
Hence, the number of communication to the disk is
reduced. This is why reading bytes is faster using while (i != -1) {
the BufferedInputStream. System.out.print((char) i);
System.out.println("Available bytes at the end: "
// Reads next byte from the file + buffer.available());
i = input.read();
} buffer.close();
input.close(); }
}
catch (Exception e) {
catch (Exception e) { e.getStackTrace();
e.getStackTrace(); }
} }
} }
}
Output Output
This is a line of text inside the file. Available bytes at the beginning: 39
In the above example, we have created a buffered Available bytes at the end: 36
input stream named buffer along
with FileInputStream. The input stream is linked with In the above example,
the file input.txt. We first use the available() method to check the
number of available bytes in the input stream.
FileInputStream file = new Then, we have used the read() method 3 times to read
FileInputStream("input.txt"); 3 bytes from the input stream.
BufferedInputStream buffer = new Now, after reading the bytes we again have checked
BufferedInputStream(file); the available bytes. This time the available bytes
decreased by 3.
Here, we have used the read() method to read an array
of bytes from the internal buffer of the buffered reader. skip() Method
To discard and skip the specified number of bytes, we
available() Method can use the skip() method. For example,
To get the number of available bytes in the input
stream, we can use the available() method. For
example, Import java.io.FileInputStream;
import java.io.BufferedInputStream;
Example: print() method with PrintStream class In the above example, we have created a print stream
import java.io.PrintStream; named output. The print stream is linked with the
file output.txt.
class Main { PrintStream output = new PrintStream("output.txt");
public static void main(String[] args) { To print the formatted text to the file, we have used
the printf() method.
String data = "This is a text inside the file."; Here, when we run the program, the output.txt file is
filled with the following content.
try { I am 25 years old.
PrintStream output = new
PrintStream("output.txt"); Other Methods Of PrintStream
Methods Descriptions
output.print(data); close() closes the print stream
output.close(); checkError() checks if there is an error
} in the stream and returns
catch(Exception e) {
a boolean result try {
append() appends the specified data
to the stream // trying to create a file based on the object
boolean value = file.createNewFile();
if (value) {
System.out.println("The new file is created.");
Java Reader/Writer }
else {
System.out.println("The file already exists.");
}
Java File Class }
catch(Exception e) {
e.getStackTrace();
The File class of the java.io package is used to perform
}
various operations on files and directories.
}
There is another package named java.nio that can be
}
used to work with files. However, in this tutorial, we
In the above example, we have created a file object
will focus on the java.io package.
named file. The file object is linked with the specified
file path.
File and Directory
File file = new File("newFile.txt");
A file is a named location that can be used to store
Here, we have used the file object to create the new
related information. For example,
file with the specified path.
main.java is a Java file that contains information
If newFile.txt doesn't exist in the current location, the
about the Java program.
file is created and this message is shown.
A directory is a collection of files and subdirectories. A
The new file is created.
directory inside a directory is known as subdirectory.
However, if newFile.txt already exists, we will see this
message.
Create a Java File Object The file already exists.
To create an object of File, we need to import
the java.io.File package first. Once we import the
package, here is how we can create objects of file. Java read files
// creates an object of File using the path To read data from the file, we can use subclasses of
File file = new File(String pathName); either InputStream or Reader.
Here, we have created a file object named file. The
object can be used to work with files and directories. Example: Read a file using FileReader
Suppose we have a file named input.txt with the
Note: In Java, creating a file object does not mean following content.
creating a file. Instead, a file object is an abstract This is a line of text inside the file.
representation of the file or directory pathname Now let's try to read the file using Java FileReader.
(specified in the parenthesis). // importing the FileReader class
import java.io.FileReader;
Java File Operation Methods
Operation Method Package class Main {
To create file createNewFile() java.io.File public static void main(String[] args) {
To read file read() java.io.FileReader
To write file write() java.io.FileWriter char[] array = new char[100];
To delete file delete() java.io.File try {
// Creates a reader using the FileReader
Java create files FileReader input = new FileReader("input.txt");
To create a new file, we can use
the createNewFile() method. It returns // Reads characters
true if a new file is created. input.read(array);
false if the file already exists in the specified location. System.out.println("Data in the file:");
System.out.println(array);
Example: Create a new File
// importing the File class // Closes the reader
import java.io.File; input.close();
}
class Main { catch(Exception e) {
public static void main(String[] args) { e.getStackTrace();
}
// create a file object for the current location }
File file = new File("newFile.txt"); }
Output
Data in the file: // creates a file object
This is a line of text inside the file. File file = new File("file.txt");
In the above example, we have used created an object
of FileReader named input. It is now linked with // deletes the file
the input.txt file. boolean value = file.delete();
FileReader input = new FileReader("input.txt"); if(value) {
To read the data from the input.txt file, we have used System.out.println("The File is deleted.");
the read() method of FileReader. }
else {
Java write to files System.out.println("The File is not deleted.");
To write data to the file, we can use subclasses of }
either OutputStream or Writer. }
}
Example: Write to file using FileWriter
// importing the FileWriter class Output
import java.io.FileWriter; The File is deleted.
Example: Reader Using FileReader Since Writer is an abstract class, it is not useful by
Here is how we can implement Reader using itself. However, its subclasses can be used to write
the FileReader class. data.
Suppose we have a file named input.txt with the
following content. Subclasses of Writer
This is a line of text inside the file. In order to use the functionality of the Writer, we can
Let's try to read this file using FileReader (a subclass use its subclasses. Some of them are:
of Reader). BufferedWriter
Import java.io.Reader; OutputStreamWriter
import java.io.FileReader; FileWriter
StringWriter
class Main {
public static void main(String[] args) { Create a Writer
In order to create a Writer, we must import
// Creates an array of character the java.io.Writer package first. Once we import the
char[] array = new char[100]; package, here is how we can create the writer.
// Reads characters Note: We can also create writers from other subclasses
input.read(array); of the Writer class.
System.out.println("Data in the stream:");
System.out.println(array); Methods of Writer
The Writer class provides different methods that are
// Closes the reader implemented by its subclasses. Here are some of the
input.close(); methods:
} write(char[] array) - writes the characters from the
specified array to the output stream
catch(Exception e) { write(String data) - writes the specified string to the
e.getStackTrace(); writer
} append(char c) - inserts the specified character to the
} current writer
flush() - forces to write all the data present in the writer For example, some characters required 2 bytes to be
to the corresponding destination stored in the storage. To read such data we can use the
close() - closes the writer input stream reader that reads the 2 bytes together and
converts into the corresponding character.
Example: Writer Using FileWriter
Here is how we can implement the Writer using Create an InputStreamReader
the FileWriter class. In order to create an InputStreamReader, we must
import the java.io.InputStreamReader package first.
import java.io.FileWriter; Once we import the package here is how we can create
import java.io.Writer; the input stream reader.
// Creates an InputStream
public class Main { FileInputStream file = new FileInputStream(String
path);
public static void main(String args[]) {
// Creates an InputStreamReader
String data = "This is the data in the output file"; InputStreamReader input = new
InputStreamReader(file);
try { In the above example, we have created
// Creates a Writer using FileWriter an InputStreamReader named input along with
Writer output = new FileWriter("output.txt"); the FileInputStream named file.
Here, the data in the file are stored using some default
character encoding.
// Writes string to the file AD
output.write(data); However, we can specify the type of character
encoding (UTF8 or UTF16) in the file as well.
// Closes the writer // Creates an InputStreamReader specifying the
output.close(); character encoding
} InputStreamReader input = new
InputStreamReader(file, Charset cs);
catch (Exception e) { Here, we have used the Charset class to specify the
e.getStackTrace(); character encoding in the file.
}
} Methods of InputStreamReader
} The InputStreamReader class provides
implementations for different methods present in
In the above example, we have created a writer using the Reader class.
the FileWriter class. The writer is linked with the
file output.txt. read() Method
Writer output = new FileWriter("output.txt"); read() - reads a single character from the reader
read(char[] array) - reads the characters from the
To write data to the output.txt file, we have reader and stores in the specified array
implemented these methods. read(char[] array, int start, int length) - reads the
output.write(); // To write data to the file number of characters equal to length from the reader
output.close(); // To close the writer and stores in the specified array starting from the start
For example, suppose we have a file
When we run the program, the output.txt file is filled named input.txt with the following content.
with the following content.
This is a line of text inside the file.
This is a line of text inside the file.
Let's try to read this file using InputStreamReader.
Here, we have used the Charset class to specify the getEncoding() Method
type of character encoding. The getEncoding() method can be used to get the type
of encoding that is used to write data to the output
Methods of OutputStreamWriter stream. For example,
The OutputStreamWriter class provides
implementations for different methods present in import java.io.OutputStreamWriter;
the Writer class. import java.nio.charset.Charset;
import java.io.FileOutputStream;
write() Method
write() - writes a single character to the writer class Main {
write(char[] array) - writes the characters from the public static void main(String[] args) {
specified array to the writer
write(String data) - writes the specified string to the try {
writer // Creates an output stream
FileOutputStream file = new
Example: OutputStreamWriter to write data to a FileOutputStream("output.txt");
File
// Creates an output stream reader with default
import java.io.FileOutputStream; encoding
import java.io.OutputStreamWriter; OutputStreamWriter output1 = new
OutputStreamWriter(file);
public class Main {
// Creates an output stream reader specifying the
public static void main(String args[]) { encoding
OutputStreamWriter output2 = new
String data = "This is a line of text inside the file."; OutputStreamWriter(file, Charset.forName("UTF8"));
In the above example, we have created 2 output FileReader input = new FileReader(File fileObj);
stream writer named output1 and output2.
output1 does not specify the character encoding. Here, we have created a file reader that will be linked
Hence the getEncoding() method returns the default to the file specified by the object of the file.
character encoding.
output2 specifies the character encoding, UTF8. In the above example, the data in the file are stored
Hence the getEncoding() method returns the specified using some default character encoding.
character encoding. However, since Java 11 we can specify the type of
character encoding (UTF-8 or UTF-16) in the file as
Note: We have used the Charset.forName() method to well.
specify the type of character encoding.
FileReader input = new FileReader(String file,
close() Method Charset cs);
To close the output stream writer, we can use
the close() method. Once the close() method is called, Here, we have used the Charset class to specify the
we cannot use the writer to write the data. character encoding of the file reader.
flush() forces to write all the data present in the read() Method
writer to the corresponding destination read() - reads a single character from the reader
read(char[] array) - reads the characters from the
append() inserts the specified character to the reader and stores in the specified array
current writer read(char[] array, int start, int length) - reads the
number of characters equal to length from the reader
and stores in the specified array starting from the
position start
Java FileReader Class For example, suppose we have a file
named input.txt with the following content.
The FileReader class of the java.io package can be
used to read data (in characters) from files. This is a line of text inside the file.
It extends the InputSreamReader class. Let's try to read the file using FileReader.
import java.io.FileReader;
class Main {
public static void main(String[] args) {
try {
// Creates a reader using the FileReader
FileReader input = new FileReader("input.txt");
// Reads characters
input.read(array); Output
System.out.println("Data in the file: "); The character encoding of input1: Cp1252
System.out.println(array); The character encoding of input2: UTF8
// Closes the reader In the above example, we have created 2 file reader
input.close(); named input1 and input2.
} input1 does not specify the character encoding. Hence
the getEncoding() method returns the default character
catch(Exception e) { encoding.
e.getStackTrace(); input2 specifies the character encoding, UTF8. Hence
} the getEncoding() method returns the specified
} character encoding.
} Note: We have used the Charset.forName() method to
specify the type of character encoding.
Output
Data in the file: close() Method
This is a line of text inside the file. To close the file reader, we can use the close() method.
Once the close() method is called, we cannot use the
In the above example, we have created a file reader reader to read the data.
named input. The file reader is linked with the
file input.txt. Other Methods of FileReader
Method Description
FileInputStream input = new ready() checks if the file reader is ready to be read
FileInputStream("input.txt"); mark() mark the position in file reader up to
which data has been read
To read data from the file, we have used reset() returns the control to the point in the
the read() method. reader where the mark was set
Note: The file input.txt should be present in the
current working directory.
Java FileWriter Class
getEncoding() Method
The getEncoding() method can be used to get the type The FileWriter class of the java.io package can be used
of encoding that is used to store data in the file. For to write data (in characters) to files.
example,
It extends the OutputStreamWriter class.
import java.io.FileReader;
import java.nio.charset.Charset;
class Main {
public static void main(String[] args) {
try {
// Creates a FileReader with default encoding
FileReader input1 = new FileReader("input.txt");
// Returns the character encoding of the file reader Before you learn more about FileWriter, make sure to
System.out.println("Character encoding of input1: know about Java File.
" + input1.getEncoding());
System.out.println("Character encoding of input2: Create a FileWriter
" + input2.getEncoding()); In order to create a file writer, we must import
the Java.io.FileWriter package first. Once we import
// Closes the reader the package, here is how we can create the file writer.
input1.close();
input2.close(); 1. Using the name of the file
} FileWriter output = new FileWriter(String name);
catch(Exception e) { Here, we have created a file writer that will be linked
e.getStackTrace(); to the file specified by the name.
}}}
This is a line of text inside the file.
2. Using an object of the file
FileWriter input = new FileWriter(File fileObj); getEncoding() Method
The getEncoding() method can be used to get the type
Here, we have created a file writer that will be linked of encoding that is used to write data. For example,
to the file specified by the object of the file.
import java.io.FileWriter;
In the above example, the data are stored using some import java.nio.charset.Charset;
default character encoding.
However, since Java 11 we can specify the type of class Main {
character encoding (UTF8 or UTF16) as well. public static void main(String[] args) {
FileWriter input = new FileWriter(String file, Charset
cs); String file = "output.txt";
try { Output
// Creates a FileWriter The character encoding of output1: Cp1252
FileWriter output = new FileWriter("output.txt"); The character encoding of output2: UTF8
// Writes the string to the file In the above example, we have created 2 file writer
output.write(data); named output1 and output2.
output1 does not specify the character encoding.
// Closes the writer Hence the getEncoding() method returns the default
output.close(); character encoding.
} output2 specifies the character encoding, UTF8.
Hence the getEncoding() method returns the specified
catch (Exception e) { character encoding.
e.getStackTrace(); Note: We have used the Charset.forName() method to
} specify the type of character encoding.
}
} close() Method
To close the file writer, we can use the close() method.
In the above example, we have created a file writer Once the close() method is called, we cannot use the
named output. The output reader is linked with writer to write the data.
the output.txt file.
Other methods of FileWriter
FileWriter output = new FileWriter("output.txt"); Method Description
flush() forces to write all the data present in the
To write data to the file, we have used writer to the corresponding destination
the write() method. append() inserts the specified character to the
Here when we run the program, the output.txt file is current writer
filled with the following content.
Java BufferedReader
read() Method
The BufferedReader class of the java.io package can read() - reads a single character from the internal
be used with other readers to read data (in characters) buffer of the reader
more efficiently. read(char[] array) - reads the characters from the
reader and stores in the specified array
It extends the abstract class Reader. read(char[] array, int start, int length) - reads the
number of characters equal to length from the reader
and stores in the specified array starting from the
position start
For example, suppose we have a file
named input.txt with the following content.
import java.io.FileReader;
import java.io.BufferedReader;
// Creates a BufferdReader with specified size internal In the above example, we have created a buffered
buffer reader named input. The buffered reader is linked with
BufferedReader buffer = new BufferedReader(file, int the input.txt file.
size); FileReader file = new FileReader("input.txt");
BufferedReader input = new BufferedReader(file);
The buffer will help to read characters from the files
more quickly. Here, we have used the read() method to read an array
of characters from the internal buffer of the buffered
Methods of BufferedReader reader.
The BufferedReader class provides implementations
for different methods present in Reader.
skip() Method data has been read
To discard and skip the specified number of reset() returns the control to the point in the
characters, we can use the skip() method. For reader where the mark was set
example,
public static void main(String args[]) { It extends the abstract class Writer.
In the above example, we have used the skip() method The buffer will help to write characters to the files
to skip 5 characters from the file reader. Hence, the more efficiently.
characters 'T', 'h', 'i', 's' and ' ' are skipped from the
original file. Methods of BufferedWriter
The BufferedWriter class provides implementations
close() Method for different methods present in Writer.
To close the buffered reader, we can use
the close() method. Once the close() method is called, write() Method
we cannot use the reader to read the data. write() - writes a single character to the internal buffer
of the writer
Other Methods of BufferedReader write(char[] array) - writes the characters from the
Method Description specified array to the writer
ready() checks if the file reader is ready to be read write(String data) - writes the specified string to the
mark() mark the position in reader up to which writer
Example: BufferedWriter to write data to a File
import java.io.FileWriter; // Flushes data to the destination
import java.io.BufferedWriter; output.flush();
System.out.println("Data is flushed to the file.");
public class Main {
output.close();
public static void main(String args[]) { }
flush() Method
To clear the internal buffer, we can use
the flush() method. This method forces the writer to
write all data present in the buffer to the destination
file.
For example, suppose we have an empty file
named output.txt.
import java.io.FileWriter;
import java.io.BufferedWriter;
Note: In StringReader, the specified string acts as a
public class Main { source from where characters are read individually.
public static void main(String[] args) {
Create a StringReader
String data = "This is a demo of the flush method"; In order to create a StringReader, we must import
the java.io.StringReader package first. Once we import
try { the package here is how we can create the string
// Creates a FileWriter reader.
FileWriter file = new FileWriter(" flush.txt");
// Creates a StringReader
// Creates a BufferedWriter StringReader input = new StringReader(String data);
BufferedWriter output = new BufferedWriter(file);
Here, we have created a StringReader that reads
// Writes data to the file characters from the specified string named data.
output.write(data);
Methods of StringReader String data = "This is the text read from
The StringReader class provides implementations for StringReader";
different methods present in the Reader class. System.out.println("Original data: " + data);
read() Method
read() - reads a single character from the string reader // Create a character array
read(char[] array) - reads the characters from the char[] array = new char[100];
reader and stores in the specified array
read(char[] array, int start, int length) - reads the try {
number of characters equal to length from the reader // Create a StringReader
and stores in the specified array starting from the StringReader input = new StringReader(data);
position start
// Use the skip() method
Example: Java StringReader input.skip(5);
import java.io.StringReader;
//Use the read method
public class Main { input.read(array);
public static void main(String[] args) { System.out.println("Data after skipping 5
characters:");
String data = "This is the text read from System.out.println(array);
StringReader.";
input.close();
// Create a character array }
char[] array = new char[100];
catch(Exception e) {
try { e.getStackTrace();
// Create a StringReader }
StringReader input = new StringReader(data); }
}
//Use the read method
input.read(array); Output
System.out.println("Data read from the string:"); Original data: This is the text read from the
System.out.println(array); StringReader
Data after skipping 5 characters:
input.close(); is the text read from the StringReader
} In the above example, we have used the skip() method
catch(Exception e) { to skip 5 characters from the string reader. Hence, the
e.getStackTrace(); characters 'T', 'h', 'i', 's' and ' ' are skipped from the
} original string reader.
}
} close() Method
To close the string reader, we can use
Output the close() method. Once the close() method is called,
Data read from the string: we cannot use the reader to read data from the string.
This is the text read from StringReader.
In the above example, we have created a string reader Other Methods of StringReader
named input. The string reader is linked to the Method Description
string data. ready() checks if the string reader is ready to be
String data = "This is a text in the string."; read
StringReader input = new StringReader(data); mark() marks the position in reader up to
which data has been read
To read data from the string, we have used reset() returns the control to the point in the
the read() method. reader where the mark was set
Here, the method reads an array of characters from the
reader and stores in the specified array.
Java StringWriter Class
skip() Method
To discard and skip the specified number of The StringWriter class of the java.io package can be
characters, we can use the skip() method. For used to write data (in characters) to the string buffer.
example,
import java.io.StringReader; It extends the abstract class Writer.
public class Main {
public static void main(String[] args) {
// Prints the string writer
System.out.println("Data in the StringWriter: " +
output);
output.close();
}
catch(Exception e) {
e.getStackTrace();
}
}
}
Note: In Java, string buffer is considered as a mutable
string. That is, we can modify the string buffer. To Output
convert from string buffer to string, we can use Data in the StringWriter: This is the text in the string.
the toString() method.
In the above example, we have created a string writer
Create a StringWriter named output.
In order to create a StringWriter, we must import
the java.io.StringWriter package first. Once we import StringWriter output = new StringWriter();
the package here is how we can create the string
writer. We then use the write() method to write the string data
to the string buffer.
// Creates a StringWriter
StringWriter output = new StringWriter(); Note: We have used the toString() method to get the
output data from string buffer in string form.
Here, we have created the string writer with default
string buffer capacity. However, we can specify the Access Data from StringBuffer
string buffer capacity as well. getBuffer() - returns the data present in the string
// Creates a StringWriter with specified string buffer buffer
capacity toString() - returns the data present in the string buffer
StringWriter output = new StringWriter(int size); as a string
For example,
Here, the size specifies the capacity of the string buffer.
import java.io.StringWriter;
Methods of StringWriter
The StringWriter class provides implementations for public class Main {
different methods present in the Writer class. public static void main(String[] args) {
String data = "This is the text in the string."; // Returns the string buffer in string form
String string = output.toString();
try { System.out.println("String: " + string);
// Create a StringWriter with default string buffer
capacity output.close();
StringWriter output = new StringWriter(); }
Here we have used the getBuffer() method to get the // Creates a PrintWriter
data present in the string buffer. And also the PrintWriter output = new PrintWriter(file, autoFlush);
method toString() returns the data present in the string
buffer as a string. Here,
we have created a print writer that will write data to
close() Method the file represented by the FileWriter
To close the string writer, we can use autoFlush is an optional parameter that specifies
the close() method. whether to perform auto flushing or not
However, the close() method has no effect in
the StringWriter class. We can use the methods of this 2. Using other output streams
class even after the close() method is called.
// Creates a FileOutputStream
Other methods of StringWriter FileOutputStream file = new
FileOutputStream("output.txt");
Method Description
flush() forces to write all the data present in the // Creates a PrintWriter
writer to the string buffer PrintWriter output = new PrintWriter(file, autoFlush);
append() inserts the specified character to the
current writer Here,
we have created a print writer that will write data to
the file represented by the FileOutputStream
Java PrintWriter Class the autoFlush is an optional parameter that specifies
whether to perform auto flushing or not
The PrintWriter class of the java.io package can be
used to write output data in a commonly readable 3. Using filename
form (text).
// Creates a PrintWriter
It extends the abstract class Writer. PrintWriter output = new PrintWriter(String file,
boolean autoFlush);
Here,
we have created a print writer that will write data to
the specified file
the autoFlush is an optional boolean parameter that
specifies whether to perform auto flushing or nor
Note: In all the above cases, the PrintWriter writes
data to the file using some default character encoding.
However, we can specify the character encoding
(UTF8 or UTF16) as well.
In the above example, we have created a print writer Other Methods Of PrintWriter
named output. This print writer is linked with the Method Description
file output.txt. close() closes the print writer
checkError() checks if there is an error
PrintWriter output = new PrintWriter("output.txt"); in the writer and returns a
boolean result
To print data to the file, we have used append() appends the specified data
the print() method. to the writer
Here when we run the program, the output.txt file is
filled with the following content.
Here are some invalid identifiers: The operator precedence of prefix ++ is higher than
- class that of - subtraction operator. Hence,
- float result = a-++c-++b;
- 1number
- highest Score is equivalent to
- @pple result = a-(++c)-(++b);
There are 7 operators to perform bit-level operations in Let's take a look at the bitwise AND operation of two
Java. integers 12 and 25.
// bitwise complement of 35
result = ~number;
System.out.println(result); // prints -36
}
}
Signed bit = 1
1's complement = 0111 As we can see the signed and unsigned right shift
operator returns different results for negative bits.
2's complement:
In the above example, we have used the next() method System.out.print("Enter a big decimal: ");
to read a string from the user.
Here, we have provided the full name. However, // reads the big decimal
the next() method only reads the first name. BigDecimal value2 = input.nextBigDecimal();
This is because the next() method reads input up to System.out.println("Using nextBigDecimal(): " +
the whitespace character. Once the whitespace is value2);
encountered, it returns the string (excluding the
whitespace). input.close();
}
Example 5: Java Scanner nextLine() }
import java.util.Scanner;
Output
class Main { Enter a big integer: 987654321
public static void main(String[] args) { Using nextBigInteger(): 987654321
Enter a big decimal: 9.55555
// creates an object of Scanner Using nextBigDecimal(): 9.55555
Scanner input = new Scanner(System.in);
System.out.print("Enter your name: "); In the above example, we have used
the java.math.BigInteger and java.math.BigDecimal p
// reads the entire line ackage to
String value = input.nextLine(); read BigInteger and BigDecimal respectively.
System.out.println("Using nextLine(): " + value);
Working of Java Scanner Narrowing Type Casting
The Scanner class reads an entire line and divides the In Narrowing Type Casting, we manually convert one
line into tokens. Tokens are small elements that have data type into another using the parenthesis.
some meaning to the Java compiler. For example, Example: Converting double into an int
Suppose there is an input string:
He is 22 class Main {
In this case, the scanner object will read the entire line public static void main(String[] args) {
and divides the string into tokens: "He", "is" and "22". // create double type variable
The object then iterates over each token and reads double num = 10.99;
each token using its different methods. System.out.println("The double value: " + num);
Note: By default, whitespace is used to divide tokens. // convert into int type
int data = (int)num;
System.out.println("The integer value: " + data);
Java Type Casting }
}
Type Casting
The process of converting the value of one data type Output
(int, float, double, etc.) to another data type is known The double value: 10.99
as typecasting. The integer value: 10
In Java, there are 13 types of type conversion.
However, in this tutorial, we will only focus on the In the above example, we are assigning
major 2 types. the double type variable named num to an int type
1. Widening Type Casting variable named data.
2. Narrowing Type Casting Notice the line,
int data = (int)num;
Widening Type Casting Here, the int keyword inside the parenthesis indicates
In Widening Type Casting, Java automatically that that the num variable is converted into
converts one data type to another data type. the int type.
In the case of Narrowing Type Casting, the higher
Example: Converting int to double data types (having larger size) are converted into lower
data types (having smaller size). Hence there is the loss
class Main { of data. This is why this type of conversion does not
public static void main(String[] args) { happen automatically.
// create int type variable
int num = 10; Note: This is also known as Explicit Type Casting.
System.out.println("The integer value: " + num);
Let's see some of the examples of other type
// convert into double type conversions in Java.
double data = num;
System.out.println("The double value: " + data); Example 1: Type conversion from int to String
}
} class Main {
public static void main(String[] args) {
Output // create int type variable
The integer value: 10 int num = 10;
The double value: 10.0 System.out.println("The integer value is: " + num);
In the above example, we are assigning the int type // converts int to string type
variable named num to a double type variable String data = String.valueOf(num);
named data. System.out.println("The string value is: " + data);
Here, the Java first converts the int type data into }
the double type. And then assign it to }
the double variable.
Output
In the case of Widening Type Casting, the lower data The integer value is: 10
type (having smaller size) is converted into the higher The string value is: 10
data type (having larger size). Hence there is no loss in
data. This is why this type of conversion happens In the above program, notice the line
automatically. String data = String.valueOf(num);
Here, we have used the valueOf() method of the Java
Note: This is also known as Implicit Type Casting. String class to convert the int type variable into a
string.
Example 2: Type conversion from String to int System.out.println("An object of Integer is
created.");
class Main { }
public static void main(String[] args) {
// create string type variable if(bObj instanceof Double) {
String data = "10"; System.out.println("An object of Double is
System.out.println("The string value is: " + data); created.");
}
// convert string variable to int }
int num = Integer.parseInt(data); }
System.out.println("The integer value is: " + num);
} Output
} An object of Integer is created.
But, before getting into lambdas, we first need to Introduction to lambda expressions
understand functional interfaces. Lambda expression is, essentially, an anonymous or
unnamed method. The lambda expression does not
What is Functional Interface? execute on its own. Instead, it is used to implement a
If a Java interface contains one and only one abstract method defined by a functional interface.
method then it is termed as functional interface. This
only one method specifies the intended purpose of the How to define lambda expression in Java?
interface. Here is how we can define lambda expression in Java.
For example, the Runnable interface from (parameter list) -> lambda body
package java.lang; is a functional interface because it The new operator (->) used is known as an arrow
constitutes only one method i.e. run(). operator or a lambda operator. The syntax might not
be clear at the moment. Let's explore some examples,
Example 1: Define a Functional Interface in java Suppose, we have a method like this:
import java.lang.FunctionalInterface; double getPiValue() {
@FunctionalInterface return 3.1415;
public interface MyInterface{ }
// the single abstract method We can write this method using lambda expression as:
double getValue(); () -> 3.1415
} Here, the method does not have any parameters.
In the above example, the interface MyInterface has Hence, the left side of the operator includes an empty
only one abstract method getValue(). Hence, it is a parameter. The right side is the lambda body that
functional interface. specifies the action of the lambda expression. In this
Here, we have used the case, it returns the value 3.1415.
annotation @FunctionalInterface. The annotation
forces the Java compiler to indicate that the interface Types of Lambda Body
is a functional interface. Hence, does not allow to have In Java, the lambda body is of two types.
more than one abstract method. However, it is not 1. A body with a single expression
compulsory though. () -> System.out.println("Lambdas are great");
In Java 7, functional interfaces were considered
as Single Abstract Methods or SAM type. SAMs were This type of lambda body is known as the expression
commonly implemented with Anonymous Classes in body.
Java 7.
2. A body that consists of a block of code.
Example 2: Implement SAM with anonymous () -> {
classes in java double pi = 3.1415;
return pi;
public class FunctionInterfaceTest { };
public static void main(String[] args) { This type of the lambda body is known as a block
body. The block body allows the lambda body to
// anonymous class include multiple statements. These statements are
new Thread(new Runnable() { enclosed inside the braces and you have to add a semi-
@Override colon after the braces.
public void run() {
Note: For the block body, you can have a return Lambda Expressions with parameters
statement if the body returns a value. However, the Till now we have created lambda expressions without
expression body does not require a return statement. any parameters. However, similar to methods, lambda
expressions can also have parameters. For example,
Example 3: Lambda Expression (n) -> (n%2)==0
Let's write a Java program that returns the value of Pi Here, the variable n inside the parenthesis is a
using the lambda expression. parameter passed to the lambda expression. The
As mentioned earlier, a lambda expression is not lambda body takes the parameter and checks if it is
executed on its own. Rather, it forms the even or odd.
implementation of the abstract method defined by the
functional interface. Example 4: Using lambda expression with
So, we need to define a functional interface first. parameters
import java.lang.FunctionalInterface; @FunctionalInterface
interface MyInterface {
// this is functional interface
@FunctionalInterface // abstract method
interface MyInterface{ String reverse(String n);
}
// abstract method
double getPiValue(); public class Main {
}
public static void main( String[] args ) {
public class Main {
// declare a reference to MyInterface
public static void main( String[] args ) { // assign a lambda expression to the reference
MyInterface ref = (str) -> {
// declare a reference to MyInterface
MyInterface ref; String result = "";
for (int i = str.length()-1; i >= 0 ; i--)
// lambda expression result += str.charAt(i);
ref = () -> 3.1415; return result;
};
System.out.println("Value of Pi = " +
ref.getPiValue()); // call the method of the interface
} System.out.println("Lambda reversed = " +
} ref.reverse("Lambda"));
}
Output:
Value of Pi = 3.1415 }
}
}