Core Java
Core Java
Table of Contents
Introduction: ................................................................................................................................................. 1
Java Development Kit (JDK): ..................................................................................................................... 1
Java Runtime Environment (JRE): ............................................................................................................. 1
Java Virtual Machine (JVM): ..................................................................................................................... 2
Just-In-Time (JIT) compiler: ....................................................................................................................... 2
Java Environment Setup: .............................................................................................................................. 3
Setup temporary path:.............................................................................................................................. 3
Setup permanent path: ............................................................................................................................. 3
Features of Java: ........................................................................................................................................... 4
Variables and Datatypes in Java.................................................................................................................... 7
Variables: .................................................................................................................................................. 7
Datatypes: ................................................................................................................................................. 7
byte: ...................................................................................................................................................... 9
short: ..................................................................................................................................................... 9
int: ......................................................................................................................................................... 9
long: ...................................................................................................................................................... 9
float: ...................................................................................................................................................... 9
double: ................................................................................................................................................ 10
boolean: .............................................................................................................................................. 10
char: .................................................................................................................................................... 10
String: .................................................................................................................................................. 11
Arrays: ................................................................................................................................................. 17
Identifiers: ............................................................................................................................................... 28
Modifiers: ................................................................................................................................................ 29
Operators: ................................................................................................................................................... 36
Assignment Operators: ........................................................................................................................... 37
Arithmetic Operators: ............................................................................................................................. 39
Relational Operators: .............................................................................................................................. 39
i
Page ii
Interface .................................................................................................................................................. 85
Marker Interfaces: .............................................................................................................................. 89
Abstract Class vs Interface .................................................................................................................. 89
Abstraction: ......................................................................................................................................... 90
Marker Interfaces: .............................................................................................................................. 97
Exception Handling: .................................................................................................................................... 98
Exception Handling Keywords................................................................................................................. 99
Improvement Exception handling in Java 7 .......................................................................................... 106
Exception Handling Best Practices ........................................................................................................ 107
Enumerations ............................................................................................................................................ 110
Collection Framework ............................................................................................................................... 114
Benefits of the Java Collections Framework ......................................................................................... 114
ArrayList: ........................................................................................................................................... 119
LinkedList .......................................................................................................................................... 121
Set: ........................................................................................................................................................ 123
Map ....................................................................................................................................................... 125
Java IO Operations .................................................................................................................................... 136
Standard Streams .................................................................................................................................. 136
Byte Stream Classe................................................................................................................................ 137
FileInputStream................................................................................................................................. 140
FileOutputStream.............................................................................................................................. 141
Character Stream Classes...................................................................................................................... 143
Serialization........................................................................................................................................... 147
Threads ..................................................................................................................................................... 151
Thread Life Cycle ................................................................................................................................... 151
Thread Priority ...................................................................................................................................... 152
Thread creation ..................................................................................................................................... 152
Creation of Thread by implementing Runnable interface ................................................................ 152
Creation of Thread by extending Thread class ..................................................................................... 155
Core Java | JPA Solutions
Page iii
Page iv
Introduction:
Java Development Kit (JDK): The Java Development Kit (JDK) is a software development
environment used for developing Java applications and applets. It includes the Java Runtime Environment
(JRE), an interpreter/loader (java), a compiler (javac), an archiver (jar), a documentation generator
(javadoc) and other tools needed in Java development.
Java developers are initially presented with two JDK tools, java and javac. Both are run from the
command prompt. Java source files are simple text files saved with an extension of .java. After writing
and saving Java source code, the javac compiler is invoked to create .class files. Once the .class files are
created, the 'java' command can be used to run the java program.
There are different JDKs for various platforms. The supported platforms include Windows, Linux and
Solaris. Mac users need a different software development kit, which includes adaptations of some tools
found in the JDK.
Java Runtime Environment (JRE): Java Runtime Environment contains JVM, class
libraries, and other supporting files. It does not contain any development tools such as compiler,
debugger, etc. Actually JVM runs the program, and it uses the class libraries, and other supporting
files provided in JRE. If you want to run any java program, you need to have JRE installed in the
system.
Core Java | JPA Solutions
Page 1
Java Virtual Machine (JVM): The Java Virtual Machine provides a platform-independent
way of executable code. Programmers can concentrate on writing software, without having to be
concerned with how or where it will run. But, note that JVM itself not a platform independent. It
only helps Java to be executed on the platform-independent way. When JVM has to interpret the
byte codes to machine language, then it has to use some native or operating system specific
language to interact with the system. One has to be very clear on platform independent concept.
Even there are many JVMs written on Java, however they too have little bit of code specific to
the operating systems.
As we all aware when we compile a Java file, output is a .class file and it consists of Java byte
codes which are understandable by JVM. Java Virtual Machine interprets the byte code into the
machine code depending upon the underlying operating system and hardware combination. It is
responsible for all the things like garbage collection, array bounds checking, etc. JVM is platform
dependent.
In brief, JVM performs following operations:
Loads code
Verifies code
Executes code
Just-In-Time (JIT) compiler: A just-in-time (JIT) compiler is a program that turns Java
bytecode (a program that contains instructions that must be interpreted) into instructions that can
be sent directly to the processor. After you've written a Java program, the source language
statements are compiled by the Java compiler into bytecode rather than into code that contains
instructions that match a particular hardware platform's processor (for example, an Intel Pentium
microprocessor or an IBM System/390 processor). The bytecode is platform-independent code
that can be sent to any platform and run on that platform.
Source
Code
Prg.java
Bytecode
JRE
JVM
JRE
Compiler
Prg.class
OS
JIT
Page 2
CPU
A compiler is a program that reads a high-level program and translates it all at once, before running any
of the commands. Often you compile the program as a separate step, and then run the compiled code
later. In this case, the high-level program is called the source code, and the translated program is called
the object code or the executable.
1. Java Source Code (Written by Developer) (Machine Neutral)
2. Compiled Code / Byte Code (Compiled by javac) . (Machine Neutral)
3. Byte Code executed (Executed by JVM) (Machine Specific)
In step 2, javac (Java Compiler) convert java code to byte code. Which can be moved to any
machine(Windows / Linux) where it will be executed by JVM. Which in turn read bytecode and generate
machine specific code. In order to generate machine specific code JVM needs to be machine specific. So
every type of Machine (Windows / Linux / Mac) has specific JVM, which needs to be installed in order to
run Java Application. So in this way Coder doesnt need to bother about writing code and generating byte
code. It is JVM which takes care of portability. So the final answer is Java is Portable but JVM is Machine
Specific.
Page 3
Features of Java:
A program is a sequence of instructions that species how to perform a computation.
There is given many features of java. They are also known as java buzzwords. The Java Features given
below are simple and easy to understand.
1. Simple
2. Object-Oriented
3. Platform independent
4. Secured
5. Robust
6. Architecture neutral
7. Portable
8. Dynamic
9. Interpreted
10. High Performance
11. Multithreaded
12. Distributed
1) Simple
Java is a simple language because of its various features, Java Doesnt Support Pointers , Operator
Overloading etc. It doesnt require unreferenced object because java support automatic garbage
collection.
Java provides bug free system due to the strong memory management.
2) Object-Oriented
Object-Oriented Programming Language (OOPs) is the methodology which provide software
development and maintenance by using object state, behavior, and properties.
Object Oriented Programming Language must have the following characteristics.
Encapsulation
Polymorphism
Inheritance
Abstraction
Page 4
As the languages like Objective C, C++ fulfills the above four characteristics yet they are not fully object
oriented languages because they are structured as well as object oriented languages.
In java everything is an Object. Java can be easily extended since it is based on the Object model.
3) Secure
Java is Secure Language because of its many features it enables to develop virus-free, tamper-free
systems. Authentication techniques are based on public-key encryption. Java does not support pointer
explicitly for the memory.
4) Robust
Java was created as a strongly typed language. Data type issues and problems are resolved at compiletime, and implicit casts of a variable from one type to another are not allowed.
Memory management has been simplified java in two ways. First Java does not support direct pointer
manipulation or arithmetic. This make it possible for a java program to overwrite memory or corrupt
data.
Second , Java uses runtime garbage collection instead of instead of freeing of memory. In languages like
c++, it Is necessary to delete or free memory once the program has finished with it.
5) Platform-independent
Java Language is platform-independent due to its hardware and software environment. Java code can be
run on multiple platforms e.g. windows, Linux, sun Solaris, Mac/Os etc. Java code is compiled by the
compiler and converted into byte code. This byte code is a platform independent code because it can be
run on multiple platforms i.e. Write Once and Run Anywhere(WORA).
6) Architecture neutral
It is not easy to write an application that can be used on Windows , UNIX and a Macintosh. And its getting
more complicated with the move of windows to non-Intel CPU architectures.
Java takes a different approach. Because the Java compiler creates byte code instructions that are
subsequently interpreted by the java interpreter, architecture neutrality is achieved in the
implementation of the java interpreter for each new architecture.
7) Portable
Java code is portable. It was an important design goal of Java that it be portable so that as new
Page 5
architectures (due to hardware, operating system, or both) are developed, the java environment could be
ported to them.
In java, all primitive types (integers, longs, floats, doubles, and so on) are of defined sizes, regardless of
the machine or operating system on which the program is run. This is in direct contrast to languages like
C and C++ that leave the sized of primitive types up to the compiler and developer.
Additionally, Java is portable because the compiler itself is written in Java.
8) Dynamic
Because it is interpreted , Java is an extremely dynamic language, At runtime, the java environment can
extends itself by linking in classes that may be located on remote servers on a network(for example, the
internet)
At runtime, the java interpreter performs name resolution while linking in the necessary classes. The Java
interpreter is also responsible for determining the placement of object in memory. These two features of
the Java interpreter solve the problem of changing the definition of a class used by other classes.
9) Interpreted
We all know that Java is an interpreted language as well. With an interpreted language such as Java,
programs run directly from the source code.
The interpreter program reads the source code and translates it on the fly into computations. Thus, Java
as an interpreted language depends on an interpreter program.
The versatility of being platform independent makes Java to outshine from other languages. The source
code to be written and distributed is platform independent.
Another advantage of Java as an interpreted language is its error debugging quality. Due to this any error
occurring in the program gets traced. This is how it is different to work with Java.
10) High performance
For all but the simplest or most infrequently used applications, performance is always a consideration for
most applications, including graphics-intensive ones such as are commonly found on the world wide web,
the performance of java is more than adequate.
11) Multithreaded
Writing a computer program that only does a single thing at a time is an artificial constraint that we?ve
lived with in most programming languages. With java, we no longer have to live with this limitation.
Page 6
Support for multiple, synchronized threads is built directly into the Java language and runtime
environment.
Synchronized threads are extremely useful in creating distributed, network-aware applications. Such as
application may be communicating with a remote server in one thread while interacting with a user in a
different thread.
12) Distributed
Java facilitates the building of distributed application by a collection of classes for use in networked
applications. By using javas URL (Uniform Resource Locator) class, an application can easily access a
remote server. Classes also are provided for establishing socket-level connections.
Datatypes:
In Java, there are two types of datatypes.
Primitive datatypes:
o
Boolean
boolean
Numeric
Page 7
Character
char
Integral
Integer
o
byte
short
int
long
Floating point
o
Float
double
Non-primitive datatype:
o
String
Array
Data Type
Default Value
Default Size
Range
Boolean
False
1 bit
true / false
Byte
1 byte
Char
\u0000'
2 byte
0 to 65,535 (unsigned)
Short
2 byte
Int
4 byte
Long
0L
8 byte
Float
0.0f
4 byte
negative)
4.94065645841246544e-324d to
1.79769313486231570e+308d (positive or
Double
0.0d
8 byte
negative).
Page 8
byte: The smallest integer type is byte. It has a minimum value of -128 and a maximum value of 127
(inclusive). The byte data type can be useful for saving memory in large arrays, where the memory
savings actually matters. Byte variables are declared by use of the byte keyword.
For example, the following declares and initialize byte variables called b:
byte b =100;
short: The short data type is a 16-bit signed two's complement integer. It has a minimum value of 32,768 and a maximum value of 32,767 (inclusive). As with byte, the same guidelines apply: you can use a
short to save memory in large arrays, in situations where the memory savings actually matters. Following
example declares and initializes short variable:
short s =123;
int: The most commonly used integer type is int. It is a signed 32-bit type that has a range from
2,147,483,648 to 2,147,483,647. In addition to other uses, variables of type int are commonly employed
to control loops and to index arrays. This data type will most likely be large enough for the numbers your
program will use, but if you need a wider range of values, use long instead.
int v = 123543;
int calc = -9876345;
long: long is a signed 64-bit type and is useful for those occasions where an int type is not large enough
to hold the desired value. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value
of 9,223,372,036,854,775,807 (inclusive). Use of this data type might be in banking application when
large amount is to be calculated and stored.
long amountVal = 1234567891;
float: Floating-point numbers, also known as real numbers, are used when evaluating expressions that
require fractional precision. For example interest rate calculation or calculating square root. The float
data type is a single-precision 32-bit IEEE 754 floating point. As with the recommendations for byte and
short, use a float (instead of double) if you need to save memory in large arrays of floating point
numbers. The type float specifies a single-precision value that uses 32 bits of storage. Single precision is
Page 9
faster on some processors and takes half as much space as double precision. The declaration and
initialization syntax for float variables given below, please note f after value initialization.
float intrestRate = 12.25f;
double: Double precision, as denoted by the double keyword, uses 64 bits to store a value. Double
precision is actually faster than single precision on some modern processors that have been optimized for
high-speed mathematical calculations. All transcendental math functions, such as sin( ), cos( ), and sqrt( ),
return double values. The declaration and initialization syntax for double variables given below, please
note d after value initialization.
double sineVal = 12345.234d;
boolean: The boolean data type has only two possible values: true and false. Use this data type for simple
flags that track true/false conditions. This is the type returned by all relational operators, as in the case of
a < b. boolean is also the type required by the conditional expressions that govern the control statements
such as if or while.
boolean
flag = true;
booleanval
= false;
char: In Java, the data type used to store characters is char. The char data type is a single 16-bit Unicode
character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive).
There are no negative chars.
ch2 = 'Y';
Page 10
Output:
byte Value = 100
short Value = 123
int Value = 123543
int second Value = -9876345
long Value = 1234567891
float Value = 12.25
double Value = 12345.234
boolean Value = true
boolean Value = false
char Value = X
char Value = Y
String: A string is one or more characters considered as a single value. Everything entered in a program,
requested from the user, or displayed as a series of characters is primarily a string. To support strings,
Java is equipped with the String class. To declare a variable that would hold a string, use the String data
type. In Java, strings are objects and not primitive datatype. Strings can be declared two ways.
1. By using double quotes
2. By creating object of String class.
String s1 = abc;
String s2 = new String(abc);
Page 11
Note: Except String, no other data type cannot initialize directly without using new operator.
String demoString = This is a sample string;
T h
0 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15 16 17 18
19
20
21
22
In the above table, first row specifies character sequence and the second row specifies index of the
corresponding character.
Methods of String class:
Illustrating the usage of String methods by using above stringDemo object.
Char
charAt(int index)
Returns the char value at the specified index.
demoString.charAt(5) = i
Int
codePointAt(int index)
Returns the character (Unicode code point) at the specified index.
demoString.codePointAt(5) = 105
Int
codePointBefore(int index)
Returns the character (Unicode code point) before the specified index.
demoString.codePointBefore (5) = 32. codePoint for space = 32.
int
Int
compareTo(String anotherString)
Compares two strings lexicographically.
Int
compareToIgnoreCase(String str)
Compares two strings lexicographically, ignoring case differences.
String
concat(String str)
Concatenates the specified string to the end of this string.
Boolean
contains(CharSequence s)
Page 12
Returns true if and only if this string contains the specified sequence of char values.
Boolean
contentEquals(CharSequence cs)
Compares this string to the specified CharSequence.
Boolean
contentEquals(StringBuffer sb)
Compares this string to the specified StringBuffer.
static String
copyValueOf(char[] data)
Returns a String that represents the character sequence in the array specified.
static String
copyValueOf(char[] data,
int offset,
int count)
Returns a String that represents the character sequence in the array specified.
Boolean
endsWith(String suffix)
Tests if this string ends with the specified suffix.
Boolean
equals(Object anObject)
Compares this string to the specified object.
Boolean
equalsIgnoreCase(String anotherString)
Compares this String to another String, ignoring case considerations.
static String
static String
byte[]
getBytes()
Encodes this String into a sequence of bytes using the platform's default charset,
storing the result into a new byte array.
byte[]
getBytes(Charset charset)
Encodes this String into a sequence of bytes using the given charset, storing the
result into a new byte array.
Void
Page 13
getBytes(String charsetName)
Encodes this String into a sequence of bytes using the named charset, storing the
result into a new byte array.
Void
Int
hashCode()
Returns a hash code for this string.
Int
indexOf(int ch)
Returns the index within this string of the first occurrence of the specified
character.
Int
Int
indexOf(String str)
Returns the index within this string of the first occurrence of the specified
substring.
int
String
intern()
Returns a canonical representation for the string object.
Boolean
isEmpty()
Returns true if, and only if, length() is 0.
Int
lastIndexOf(int ch)
Returns the index within this string of the last occurrence of the specified
character.
Int
Page 14
lastIndexOf(String str)
Returns the index within this string of the rightmost occurrence of the specified
substring.
Int
Int
length()
Returns the length of this string.
Boolean
matches(String regex)
Tells whether or not this string matches the given regular expression.
Int
Boolean
regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
Tests if two string regions are equal.
Boolean
String
String
String
String
Page 15
split(String regex)
Splits this string around matches of the given regular expression.
String[]
Boolean
startsWith(String prefix)
Tests if this string starts with the specified prefix.
Boolean
substring(int beginIndex)
Returns a new string that is a substring of this string.
String
char[]
toCharArray()
Converts this string to a new character array.
String
toLowerCase()
Converts all of the characters in this String to lower case using the rules of the
default locale.
String
toLowerCase(Locale locale)
Converts all of the characters in this String to lower case using the rules of the given
Locale.
String
toString()
This object (which is already a string!) is itself returned.
String
toUpperCase()
Converts all of the characters in this String to upper case using the rules of the
Page 16
default locale.
String
toUpperCase(Locale locale)
Converts all of the characters in this String to upper case using the rules of the
given Locale.
String
trim()
Returns a copy of the string, with leading and trailing whitespace omitted.
static String
valueOf(boolean b)
Returns the string representation of the boolean argument.
static String
valueOf(char c)
Returns the string representation of the char argument.
static String
valueOf(char[] data)
Returns the string representation of the char array argument.
static String
static String
valueOf(double d)
Returns the string representation of the double argument.
static String
valueOf(float f)
Returns the string representation of the float argument.
static String
valueOf(int i)
Returns the string representation of the int argument.
static String
valueOf(long l)
Returns the string representation of the long argument.
static String
valueOf(Object obj)
Returns the string representation of the Object argument.
Arrays:
An array is a collection of similar data types. Array is a container object that hold values of homogenous
type. It is also known as static data structure because size of an array must be specified at the time of its
Page 17
declaration. An array can be either primitive or reference type. It gets memory in heap area. Index of an
array starts from zero to (array size-1).
The values stored in an array are called elements. The individual elements are accessed using an integer
index.
Array Declaration syntax:
datatype[] identifier;
(or)
datatype identifier[];
Array initialization syntax:
int[] arr = new int[10];
or
int[] arr = {10,20,30,40,50};
Accessing an element:
<array variable>[<integer expression>]
Arrays are linear collections of elements. They do not automatically resize. They have fixed lengths. This
makes them harder to use but faster. We can find utility/helper methods available in java.util.Arrays
class.
static int
Searches the specified array of bytes for the specified value using the binary search
algorithm.
binarySearch(byte[] a, int fromIndex, int toIndex, byte key)
static int
Searches a range of the specified array of bytes for the specified value using the
binary search algorithm.
static int
Page 18
Searches the specified array of chars for the specified value using the binary search
algorithm.
binarySearch(char[] a, int fromIndex, int toIndex, char key)
static int
Searches a range of the specified array of chars for the specified value using the
binary search algorithm.
binarySearch(double[] a, double key)
static int
Searches the specified array of doubles for the specified value using the binary
search algorithm.
binarySearch(double[] a, int fromIndex, int toIndex,
double key)
static int
Searches a range of the specified array of doubles for the specified value using the
binary search algorithm.
binarySearch(float[] a, float key)
static int
Searches the specified array of floats for the specified value using the binary search
algorithm.
binarySearch(float[] a, int fromIndex, int toIndex, float key)
static int
Searches a range of the specified array of floats for the specified value using the
binary search algorithm.
binarySearch(int[] a, int key)
static int
Searches the specified array of ints for the specified value using the binary search
algorithm.
binarySearch(int[] a, int fromIndex, int toIndex, int key)
static int
Searches a range of the specified array of ints for the specified value using the binary
search algorithm.
binarySearch(long[] a, int fromIndex, int toIndex, long key)
static int
Searches a range of the specified array of longs for the specified value using the
binary search algorithm.
static int
Page 19
Searches the specified array of longs for the specified value using the binary search
algorithm.
binarySearch(Object[] a, int fromIndex, int toIndex,
Object key)
static int
Searches a range of the specified array for the specified object using the binary
search algorithm.
binarySearch(Object[] a, Object key)
static int
Searches the specified array for the specified object using the binary search
algorithm.
binarySearch(short[] a, int fromIndex, int toIndex, short key)
static int
Searches a range of the specified array of shorts for the specified value using the
binary search algorithm.
binarySearch(short[] a, short key)
static int
Searches the specified array of shorts for the specified value using the binary search
algorithm.
binarySearch(T[] a, int fromIndex, int toIndex, T key,
Comparator<? super T> c)
Searches a range of the specified array for the specified object using the binary
search algorithm.
binarySearch(T[] a, T key, Comparator<? super T> c)
static <T> int Searches the specified array for the specified object using the binary search
algorithm.
copyOf(boolean[] original, int newLength)
static
boolean[]
Copies the specified array, truncating or padding with false (if necessary) so the
copy has the specified length.
copyOf(byte[] original, int newLength)
static byte[]
Copies the specified array, truncating or padding with zeros (if necessary) so the
copy has the specified length.
static char[]
Page 20
Copies the specified array, truncating or padding with null characters (if necessary)
so the copy has the specified length.
copyOf(double[] original, int newLength)
static
double[]
Copies the specified array, truncating or padding with zeros (if necessary) so the
copy has the specified length.
copyOf(float[] original, int newLength)
static float[] Copies the specified array, truncating or padding with zeros (if necessary) so the
Copies the specified array, truncating or padding with zeros (if necessary) so the
copy has the specified length.
copyOf(long[] original, int newLength)
static long[]
Copies the specified array, truncating or padding with zeros (if necessary) so the
copy has the specified length.
copyOf(short[] original, int newLength)
static short[] Copies the specified array, truncating or padding with zeros (if necessary) so the
static
<T,U> T[]
static
boolean[]
Copies the specified array, truncating or padding with nulls (if necessary) so the copy
has the specified length.
copyOfRange(boolean[] original, int from, int to)
Copies the specified range of the specified array into a new array.
copyOfRange(byte[] original, int from, int to)
static byte[]
Copies the specified range of the specified array into a new array.
Page 21
Copies the specified range of the specified array into a new array.
static
double[]
Copies the specified range of the specified array into a new array.
copyOfRange(float[] original, int from, int to)
static float[]
Copies the specified range of the specified array into a new array.
copyOfRange(int[] original, int from, int to)
static int[]
Copies the specified range of the specified array into a new array.
copyOfRange(long[] original, int from, int to)
static long[]
Copies the specified range of the specified array into a new array.
copyOfRange(short[] original, int from, int to)
static short[]
Copies the specified range of the specified array into a new array.
copyOfRange(T[] original, int from, int to)
static <T> T[]
Copies the specified range of the specified array into a new array.
static
<T,U> T[]
Copies the specified range of the specified array into a new array.
deepEquals(Object[] a1, Object[] a2)
static boolean
Returns true if the two specified arrays are deeply equal to one another.
deepHashCode(Object[] a)
static int
Returns a hash code based on the "deep contents" of the specified array.
deepToString(Object[] a)
static String
Page 22
Returns true if the two specified arrays of booleans are equal to one another.
equals(byte[] a, byte[] a2)
static boolean
Returns true if the two specified arrays of bytes are equal to one another.
equals(char[] a, char[] a2)
static boolean
Returns true if the two specified arrays of chars are equal to one another.
equals(double[] a, double[] a2)
static boolean
Returns true if the two specified arrays of doubles are equal to one another.
equals(float[] a, float[] a2)
static boolean
Returns true if the two specified arrays of floats are equal to one another.
equals(int[] a, int[] a2)
static boolean
Returns true if the two specified arrays of ints are equal to one another.
equals(long[] a, long[] a2)
static boolean
Returns true if the two specified arrays of longs are equal to one another.
equals(Object[] a, Object[] a2)
static boolean
Returns true if the two specified arrays of Objects are equal to one another.
equals(short[] a, short[] a2)
static boolean
Returns true if the two specified arrays of shorts are equal to one another.
fill(boolean[] a, boolean val)
static void
Assigns the specified boolean value to each element of the specified array of
booleans.
fill(boolean[] a, int fromIndex, int toIndex, boolean val)
static void
Assigns the specified boolean value to each element of the specified range of the
specified array of booleans.
fill(byte[] a, byte val)
static void
Assigns the specified byte value to each element of the specified array of bytes.
Core Java | JPA Solutions
Page 23
Assigns the specified byte value to each element of the specified range of the
specified array of bytes.
fill(char[] a, char val)
static void
Assigns the specified char value to each element of the specified array of chars.
fill(char[] a, int fromIndex, int toIndex, char val)
static void
Assigns the specified char value to each element of the specified range of the
specified array of chars.
fill(double[] a, double val)
static void
Assigns the specified double value to each element of the specified array of doubles.
fill(double[] a, int fromIndex, int toIndex, double val)
static void
Assigns the specified double value to each element of the specified range of the
specified array of doubles.
fill(float[] a, float val)
static void
Assigns the specified float value to each element of the specified array of floats.
fill(float[] a, int fromIndex, int toIndex, float val)
static void
Assigns the specified float value to each element of the specified range of the
specified array of floats.
fill(int[] a, int val)
static void
Assigns the specified int value to each element of the specified array of ints.
fill(int[] a, int fromIndex, int toIndex, int val)
static void
Assigns the specified int value to each element of the specified range of the specified
array of ints.
fill(long[] a, int fromIndex, int toIndex, long val)
static void
Assigns the specified long value to each element of the specified range of the
specified array of longs.
Page 24
Assigns the specified long value to each element of the specified array of longs.
fill(Object[] a, int fromIndex, int toIndex, Object val)
static void
Assigns the specified Object reference to each element of the specified range of the
specified array of Objects.
fill(Object[] a, Object val)
static void
Assigns the specified Object reference to each element of the specified array of
Objects.
fill(short[] a, int fromIndex, int toIndex, short val)
static void
Assigns the specified short value to each element of the specified range of the
specified array of shorts.
fill(short[] a, short val)
static void
Assigns the specified short value to each element of the specified array of shorts.
hashCode(boolean[] a)
static int
Page 25
hashCode(long[] a)
static int
Page 26
Sorts the specified array of objects into ascending order, according to the natural
ordering of its elements.
sort(Object[] a, int fromIndex, int toIndex)
static void
Sorts the specified range of the specified array of objects into ascending order,
according to the natural ordering of its elements.
sort(short[] a)
static void
static
<T> void
Sorts the specified array of objects according to the order induced by the specified
comparator.
sort(T[] a, int fromIndex, int toIndex, Comparator<? super
T> c)
Sorts the specified range of the specified array of objects according to the order
induced by the specified comparator.
toString(boolean[] a)
static String
toString(byte[] a)
Page 27
Identifiers:
All Java components require names. Name used for classes, methods, interfaces and variables are called
Identifier. Identifier must follow some rules. Here are the rules:
All identifiers must start with either a letter (a to z or A to Z) or currency character ($) or an
underscore.
After the first character, an identifier can have any combination of characters.
Identifiers in Java are case sensitive; foo and Foo are two different identifiers.
Declaring a variable:
<access_modifies> <non_access_modifier> <datatype> <variable_name>;
Core Java | JPA Solutions
Page 28
Modifiers:
There are two types of modifiers in java: access modifiers and non-access modifiers.
Access Modifiers
Non-access Modifiers
public
static
protected
final
default
abstract
private
syncronized
native
transient
volatile
strictp
Access Modifiers:
The access modifiers in java specify accessibility (scope) of a data member, method, constructor or class.
Public
Private
Protected
Default
Page 29
The below table illustrates what are the access modifiers applicable for classes, methods and variables.
Access Modifier
Class
Methods
Variable
Public
Yes
Yes
Yes
Private
No
Yes
Yes
Protected
No
Yes
Yes
Default
Yes
Yes
Yes
Access Modifier within class within package outside package by subclass outside package
private
default
protected
public
Page 30
public
private
protected
default
Yes
Yes
Yes
Yes
No
Yes
Yes
No
Yes
Yes
No
Yes(Only
same package
From any sub class Yes
from same package
From any sub class Yes
from
different
by No
inheritance)
package
From any non-sub Yes
No
No
No
public
private
protected
default
Yes
Yes
Yes
Yes
No
Yes
Yes
No
Yes
Yes
No
Yes(Only
same package
From any sub class Yes
from same package
From any sub class Yes
from
different
by No
inheritance)
package
From any non-sub Yes
No
No
No
Page 31
Page 32
When you try to access a non-static variable from a static context like main method, java compiler
throws a message like "a non-static variable cannot be referenced from a static context". This is because
non-static variables are related with instance of class (object) and they get created when instance of a
class is created by using new operator. So if you try to access a non-static variable without any instance
compiler will complain because those variables are not yet created and they don't have any existence
until an instance is created and associated with it.
2. final modifier: final is a keyword or reserved word in java and can be applied to member
variables, methods, class and local variables in Java. Once you make a reference final you are not
allowed to change that reference and compiler will verify this and raise compilation error if you try
to re-initialized final variables in java.
2.1. final variable: Any variable either member variable or local variable (declared inside method or
block) modified by final keyword is called final variable. Final variables are often declare with static
keyword in java and treated as constant.
public static final String LOAN = "loan";
LOAN = new String("loan") //invalid compilation error
Note: Final variables are by default read-only.
2.2. final method: Final keyword in java can also be applied to methods. A java method with final
keyword is called final method and it can not be overridden in sub-class. You should make a method
final in java if you think its complete and its behavior should remain constant in sub-classes. Final
methods are faster than non-final methods because they are not required to be resolved during runtime and they are bonded on compile time.
class PersonalLoan {
public final String getName() {
return "personal loan";
}
}
class CheapPersonalLoan extends PersonalLoan {
@Override
public final String getName() {
return "cheap personal loan"; // compilation error: overridden
//method is final
// final
}
}
Page 33
2.3. final class: final keyword helps to write immutable class. Immutable classes are the one which cannot
be modified once it gets created and String is primary example of immutable and final class.
Immutable classes offer several benefits one of them is that they are effectively read-only and can be
safely shared in between multiple threads without any synchronization overhead. You cannot make a
class immutable without making it final and hence final keyword is required to make a class
immutable in java.
3. abstract: The abstract keyword can be used on classes and methods. A class declared with the
abstract keyword cannot be instantiated, and that is the only thing the abstract keyword does.
4. synchronized: The "synchronized" keyword prevents concurrent access to a block of code or object
by multiple Threads. The synchronized keyword causes a thread to obtain a lock when entering the
method, so that only one thread can execute the method at the same time.
5. native: The native keyword is used to declare a method which is implemented in platformdependent code such as C or C++. When a method is marked as native, it cannot have a body and
must ends with a semicolon instead. The Java Native Interface (JNI)specification governs rules and
guidelines for implementing native methods, such as data type conversion between Java and the
native application.
6. transient: The keyword transient in Java used to indicate that the variable should not be serialized.
By default all the variables in the object is converted to persistent state. In some cases, you may want
to avoid persisting some variables because you dont have the necessity to transfer across the
network. So, you can declare those variables as transient. If the variable is declared as transient, then
it will not be persisted. It is the main purpose of the transient keyword.
Page 34
7. volatile: When multiple threads using the same variable, each thread will have its own copy of the
local cache for that variable. So, when its updating the value, it is actually updated in the local cache
not in the main variable memory. The other thread which is using the same variable doesnt know
anything about the values changed by the other thread. To avoid this problem, if you declare a
variable as volatile, then it will not be stored in the local cache. Whenever threads are updating the
values, it is updated to the main memory. So, other threads can access the updated value.
8. strictfp: The strictfp means strict floating point, ensures that you get exactly the same results from
your floating point calculations on every platform and it forces the precision of floating point
calculations (float or double) in Java conform to IEEEs 754 standard, explicitly. Without using strictfp
keyword, the floating point precision depends on target platforms hardware, i.e. CPUs floating point
processing capability. In other words, using strictfp ensures result of floating point computations is
always same on all platforms.
The strictfp keyword can be applied for classes, interfaces and methods.
In class level strictfp all the methods inside class also get modified with strictfp keyword
automatically.
Page 35
}
strictfp abstract void showSpeed();//CAN NOT apply on abstract methods
public strictfp void startCar(){ //CAN apply on abstract methods
}
}
Operators:
Operator in java is a symbol that is used to perform operations. Operators in java fall into 8 different
categories.
Assignment Operators
Arithmetic operators
Relational operators
Logical operators
Bitwise operators
Page 36
Assignment Operators:
The assignment operator (=) is a way of copying a value on the right-hand side (rvalue), to a variable on
the left-hand side (lvalue). The rvalue can be any constant, variable, or any expression that produces a
value, while the lvalue must be a distinctly named variable that possesses the capacity to hold to a value.
There are following assignment operators supported by Java language:
Operator
=
Description
Example
+=
C += A is equivalent to C = C + A
operand
Subtract AND assignment operator, It subtracts right
-=
C -= A is equivalent to C = C - A
to left operand
Multiply AND assignment operator, It multiplies right
*=
operand with the left operand and assign the result to C *= A is equivalent to C = C * A
left operand
Divide AND assignment operator, It divides left
/=
C /= A is equivalent to C = C / A
to left operand
Modulus AND assignment operator, It takes modulus
%=
C %= A is equivalent to C = C % A
operand
<<=
>>=
&=
^=
C ^= 2 is same as C = C ^ 2
|=
C |= 2 is same as C = C | 2
When we assign primitives, its actually copy a value from one place to another. This is because primitives
hold actual values as opposed to objects that hold references. With the assignment of objects, one must
become
properly
acquainted
with
the
phenomenon
known
as
aliasing.
Page 37
Aliasing can be observed in the behavior of object references that are copied and that point to the same
object. Consider the following example:
Program:
class Level {
int spaces;
}
public class CarPark {
public static void main(String[] args) {
Level l1 = new Level();
Level l2 = new Level();
l1.spaces = 10;
l2.spaces = 3;
System.out.println("1: l1.spaces: " + l1.spaces + ", l2.spaces: " +
l2.spaces);
l2 = l1;
System.out.println("2: l1.spaces: " + l1.spaces + ", l2.spaces: " +
l2.spaces);
l2.spaces = 0;
System.out.println("3: l1.spaces: " + l1.spaces + ", l2.spaces: " +
l2.spaces);
}
}
Output:
1: l1.spaces: 10, l2.spaces: 3
2: l1.spaces: 10, l2.spaces: 10
3: l1.spaces: 0, l2.spaces: 0
The CarPark class illustrates the logic of a car park spread over many levels. In this instance, the
class creates two Level instances (l1 and l2) in the main() and both objects are assigned different
field values that denote the number of empty spaces on each level. We can observe the aliasing
phenomenon at the point where l1 is assigned to l2 and how, subsequently assigning a different
value to l2 appears to change l1 as well, when you would intuitively expect that both objects were
completely independent of one and the other. Not quite so, I'm afraid. This is because at the point
where l1 is assigned to l2, both now contain the same reference that point to the same object and
Core Java | JPA Solutions
Page 38
changes to the one is bound to affect the other. This is fundamentally how Java works with
objects and demonstrates the aliasing effect.
To retain two independent objects in this particular instance, we would make the assignment call
to the object member explicit, like this: l2.spaces = l1.spaces;
This way we can avoid the idiosyncratic behavior of the aliasing phenomenon, which we must
add, is not limited to field assignments alone, but can also occur when you pass an object into a
method, where it can appear to change the value of an object or field that exists completely
outside of the method scope.
Arithmetic Operators:
Arithmetic operators are used in mathematical expressions in the same way that they are used in
algebra. The following table lists the arithmetic operators:
Operator
Description
Example
A + B will give 30
B / A will give 2
Modulus - Divides left hand operand by right hand operand and returns
remainder
B % A will give 0
++
B++ gives 21
--
B-- gives 19
Relational Operators:
Relational operators evaluate the relationship between the values of two operands and produce a
boolean result i.e., true or false. They include less than (<), greater than (>), less than or equal to
(<=), greater than or equal to (>=), equivalence (==), and nonequivalence (!=). With the exception of the
equivalence and nonequivalence operators, all other relational operators work with all primitives except
boolean.
Operator
Description
Example
Page 39
Checks if the value of two operands are equal or not, if yes then
==
!=
>
<
>=
<=
(A == B) is not true.
(A != B) is true.
(A < B) is true.
(A <= B) is true.
The equivalence and nonequivalence operators, in addition to working with all primitives, also work with
objects; but here, one must be mindful to note that they actually compare object references and not the
actual content of objects themselves. For instance, if you were to try to compare two Double objects:
Program:
public class CompareDouble {
public static void main(String[] args) {
Double d1 = new Double(3.2);
Double d2 = new Double(3.2);
System.out.println(d2 != d1);
System.out.println(d2 == d1);
}
}
Output:
true
false
The output can be a bit confusing, returning a false result when both objects are tested for equivalence,
and a true result when tested for nonequivalence. This is of course not what you might expect given that
both objects are the same or to put it another way, both references point to the same object in memory.
The reason for what might seem an unusual result is because the == and != operators in fact compare
object references as opposed to the actual content of objects themselves.
Page 40
To make the comparison of the actual content of objects, we may use the special equals() method that
exist for all objects like so:
Program:
public class CompareDouble {
public static void main(String[] args) {
Double d1 = new Double(3.2);
Double d2 = new Double(3.2);
System.out.println(d2.equals(d1));
}
}
Output:
true
false
Bitwise Operators:
These operators provide you with a way to manipulate individual bits in an integral primitive data type.
Integral data types are data types which store a finite subset of integers. Bitwise operators are said to
perform Boolean algebra on the corresponding bits in two arguments.
Java defines several bitwise operators which can be applied to the integer types, long, int, short, char, and
byte.
^
~
Description
Binary AND Operator copies a bit to the result if it exists
in both operands.
Binary OR Operator copies a bit if it exists in either
operand.
Binary XOR Operator copies the bit if it is set in one
operand but not both.
Binary Ones Complement Operator is unary and has
Example
(A & B) will give 12 which is 0000 1100
Page 41
operand.
Binary Right Shift Operator. The left operands value is
>>
moved right by the number of bits specified by the right A >> 2 will give 15 which is 1111
operand.
Shift right zero fill operator. The left operands value is
>>>
moved right by the number of bits specified by the right A >>>2 will give 15 which is 0000 1111
operand and shifted values are filled up with zeros.
Logical Operators:
The Conditional or logical operators AND (&&) and OR (||) also produce a boolean result of true or false
based on the logical relationship of its arguments. They are known to exhibit a phenomenon known as
short-circuiting, which means that the expression is evaluated only to the extent that the truth or falsehood
of the it can be clearly determined. This is to say sometimes only a part of the expression need be
evaluated in order to determine its truth or falsehood. Below provides a demonstration on the use of
conditional operators:
Assume boolean variables A holds true and variable B holds false then:
Operator
&&
||
Description
Called Logical AND operator. If both the operands are non-zero then
then condition becomes true.
Called Logical OR Operator. If any of the two operands are non-zero
then then condition becomes true.
Example
(A && B) is false.
(A || B) is true.
Called Logical NOT Operator. Use to reverses the logical state of its
!
false.
Conditional Operator ( ? : ):
Conditional operator is also known as the ternary operator. This operator consists of three operands and
is used to evaluate boolean expressions. The goal of the operator is to decide which value should be
assigned to the variable. The operator is written as :
variable x = (expression) ? value if true : value if false
Core Java | JPA Solutions
Page 42
Casting:
Casting is a way to convert from one type to another, for instance from a float to a double. With a
widening-conversion (i.e. going from a type that holds less information to one that holds much more),
you will find this to be a safe operation and as there is no risk of losing information, Java is able to
perform these sorts of casts automatically; however with a narrowing-conversion, the compiler will
always force you to use an explicit cast. To perform a cast, you simply put the desired type between
parenthesis and to the left of any value you wish to cast. Check out the following example:
Program:
public class Cast {
public static void main(String[] args) {
double d = 5.2;
int i = (int) d;// narrowing conversion cast required
long l = i;// widening conversion automatic cast
byte b = (byte) l;// narrowing conversion cast required
System.out.println(d);
System.out.println(i);
System.out.println(l);
System.out.println(b);
}
}
Output:
5.2
5
5
5
It is also good practice to be aware that when performing mathematical operations in Java, the larger or
largest data type determines the size of the result of that expression; for instance if you were to multiply
an int by say a double primitive data type, the result will almost certainly be double, likewise if you
were to perform an operation with of any of the smaller data types i.e. byte, char or short with an
int, the resulting value will be of type int. An explicit cast will be necessary to assign any resulting value
Page 43
Order of operators:
Java has well-defined rules for specifying the order in which the operators in an expression are
evaluated when the expression has several operators. For example, multiplication and division
have a higher precedence than addition and subtraction. Precedence rules can be overridden by
explicit parentheses.
Precedence order:
When two operators share an operand the operator with the higher precedence goes first. For example, 1
+ 2 * 3 is treated as 1 + (2 * 3), whereas 1 * 2 + 3 is treated as (1 * 2) + 3 since multiplication has a higher
precedence than addition.
Associativity:
When an expression has two operators with the same precedence, the expression is evaluated according
to its associativity. For example x = y = z = 17 is treated as x = (y = (z = 17)), leaving all three
variables with the value 17, since the = operator has right-to-left associativity (and an assignment
statement evaluates to the value on the right hand side). On the other hand, 72 / 2 / 3 is treated as
(72 / 2) / 3 since the / operator has left-to-right associativity.
15
Priority
14
13
Operator
Type
()
Parentheses
[]
Array subscript
Member selection
++
Unary post-increment
--
Unary post-decrement
++
Unary pre-increment
--
Unary pre-decrement
Associativity
Left to Right
Right to left
Right to left
Page 44
Unary plus
Unary minus
( type )
12
11
Multiplication
Division
Modulus
Addition
Subtraction
Left to right
Left to right
10
<<
>>
extension
>>>
Left to right
extension
<
<=
>
>=
Left to right
Relational is equal to
!=
&
Bitwise AND
Left to right
10
Bitwise exclusive OR
Left to right
11
Bitwise inclusive OR
Left to right
12
&&
Logical AND
Left to right
13
||
Logical OR
Left to right
14
?:
Ternary conditional
Right to left
15
Assignment
Right to left
Left to right
Page 45
+=
Addition assignment
-=
Subtraction assignment
*=
Multiplication assignment
/=
Division assignment
%=
Modulus assignment
There is no explicit operator precedence table in the Java Language Specification and different
tables on the web and in textbooks disagree in some minor ways.
Order of evaluation of subexpressions:
Associativity and precedence determine in which order Java applies operators to subexpressions but they
do not determine in which order the subexpressions are evaluated. In Java, subexpressions are evaluated
from left to right (when there is a choice). So, for example in the expression A() + B() * C(D(),
E()), the subexpressions are evaluated in the order A(), B(), D(), E(), and C(). Although, C()
appears to the left of both D() and E(), we need the results of both D() and E() to evaluate C(). It is
considered poor style to write code that relies upon this behavior (and different programming languages
may use different rules).
Short circuiting:
When using the conditional and and or operators (&& and ||), Java does not evaluate the second
operand unless it is necessary to resolve the result. This allows statements like if (s != null
&& s.length() < 10)
Page 46
was established in Microsoft Excel 2.0, it could not easily be changed without breaking backward
compatibility.
Output:
1 + 2 = 12
1 + 2 = 3
If either (or both) of the operands of the + operator is a string, the other is automatically cast to a string.
String concatenation and addition have the same precedence. Since they are left-associative, the
operators are evaluated left-to-right. The parentheses in the second statement ensures that the second +
operator performs addition instead of string concatenation.
Que: Add parentheses to the following expression to make the order of evaluation more clear.
year % 4 == 0 && year % 100 != 0 || year % 400 == 0
Ans:
((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)
Output:
3abc
abc12
Page 47
1. Selection statements:
1.1. if,
1.2. if-else
1.3. switch.
2. Loop statements:
2.1. while,
2.2. do-while
2.3. for.
3. Transfer statements:
3.1. break,
3.2. continue,
3.3. return,
3.4. try-catch-finally
3.5. assert.
Selection Statements:
The if statement:
The if statement executes a block of code only if the specified expression is true. If the value is false, then
the if block is skipped and execution continues with the rest of the program. You can either have a single
statement or a block of code within an if statement. Note that the conditional expression must be a
Boolean expression.
The simple if statement has the following syntax:
if (<conditional expression>) {
Page 48
<statement(s)>
}
Example:
public class IfStatementDemo {
public static void main(String[] args) {
int a = 10, b = 20;
if (a > b)
System.out.println("a > b");
if (a < b)
System.out.println("b > a");
}
}
Output:
b>a
The if-else Statement:
The if/else statement is an extension of the if statement. If the statements in the if statement fails,
the statements in the else block are executed. You can either have a single statement or a block of code
within if-else blocks. Note that the conditional expression must be a Boolean expression.
The if-else statement has the following syntax:
if (<conditional expression>) {
<statement action>
} else {
<statement action>
}
Below is an example that demonstrates conditional execution based on if else statement condition.
public class IfElseStatementDemo {
public static void main(String[] args) {
int a = 10, b = 20;
if (a > b) {
System.out.println("a > b");
} else {
System.out.println("b < a");
}
}
}
Page 49
case
case
default:
<statement>
} // end switch
When executing a switch statement, the program falls through to the next case. Therefore, if you want to
exit in the middle of the switch statement code block, you must insert a break statement, which causes
the program to continue executing after the current code block.
Below is a java example that demonstrates conditional execution based on nested if else statement
condition to find the greatest of 3 numbers.
public class SwitchCaseStatementDemo {
public static void main(String[] args) {
int a = 10, b = 20, c = 30;
int status = -1;
if (a > b && a > c) {
status = 1;
} else if (b > c) {
status = 2;
} else {
status = 3;
}
switch (status) {
case 1:
Page 50
Output:
c is the greatest
Iteration Statements:
The while Loop:
The while statement is a looping construct control statement that executes a block of code while a
condition is true. You can either have a single statement or a block of code within the while loop. The
loop will never be executed if the testing expression evaluates to false. The loop condition must be a
boolean expression.
The syntax of the while loop is:
while (<loop_condition>) {
<statements>
}
Test: a Boolean test of should be true before each iteration. Or put another way, the test is the
"green light" condition that says that each iteration can go ahead. (The phrase "green light" is a good
mnemonic for what the test does.) Eventually, the test should become false and the loop can exit.
Think about the precondition that describes the state before each iteration runs -- how are things
arranged, what is true? (Also known as an "invariant".) In the above example, the test (count < 100)
means that each iteration can proceed, so long as (count < 100) is true.
Work: Code in the body that does something for each iteration such as printing or drawing
something. Some loops do not have any identifiable work in the body. In the above example, the
work is the println() that prints something out for each iteration.
Page 51
Increment: Code in the body that advances things so we are closer to making the test false. At the
end of the body, the code will loop around to the top of the body. Sometimes, some cleanup is
required at the end of the body to set things up for the next iteration. In the above example, the line
"count = count + 1;" accomplishes the increment. That can also be written as "count++;".
Below is an example that demonstrates the looping construct namely while loop used to print numbers
from 1 to 10.
public class WhileLoopDemo {
public static void main(String[] args) {
int count = 1;
System.out.println("Printing Numbers from 1 to 10");
while (count <= 10) {
System.out.println(count++);
}
}
}
Do-while Loop
The do-while loop is similar to the while loop, except that the test is performed at the end of the
loop instead of at the beginning. This ensures that the loop will be executed at least once. A dowhile loop begins with the keyword do, followed by the statements that make up the body of the
loop. Finally, the keyword while and the test expression completes the do-while loop. When the
loop condition becomes false, the loop is terminated and execution continues with the statement
immediately following the loop. You can either have a single statement or a block of code within
the do-while loop.
The syntax of the do-while loop is:
do {
<loop_body>
} while (condition)
Below is an example that demonstrates the looping construct namely do-while loop used to print
numbers from 1 to 10.
public class DoWhileLoopDemo {
public static void main(String[] args) {
int count = 1;
System.out.println("Printing Numbers from 1 to 10");
do {
Page 52
System.out.println(count++);
} while (count <= 10);
}
}
Output
Printing Numbers from 1 to 10
1
2
3
4
5
6
7
8
9
10
Fibonacci sequence: The logic to generate next number in Fibonacci series is sum of previous
two numbers. The below table illustrate, how to generate Fibonacci series.
0
0+1
1+1
1+2
2+3
3+5
5+8
8+13
13+21
13
21
34
Page 53
Output
Printing Limited set of Fibonacci Sequence
0.0
1.0
1.0
2.0
3.0
5.0
8.0
13.0
21.0
34.0
55.0
89.0
144.0
233.0
377.0
610.0
987.0
1597.0
2584.0
4181.0
6765.0
For Loops
The for loop is a looping construct which can execute a set of instructions a specified number of
times. Its a counter controlled loop.
The syntax of the loop is as follows:
for (<initialization>; <loop condition>; <arithmetic_operation>) {
<loop body>
Page 54
Page 55
All the sections in the for-header are optional. Any one of them can be left empty, but the two
semicolons are mandatory. So, we can write for loop as below:
for (
; ){
Output
Printing Numbers from 1 to 10
1
2
3
4
5
6
7
8
9
10
Page 56
Transfer Statements
Continue Statement:
A continue statement stops the iteration of a loop (while, do or for) and causes execution to
resume at the top of the nearest enclosing loop. You use a continue statement when you do not
want to execute the remaining statements in the loop, but you do not want to exit the loop itself.
The syntax of the continue statement is
continue; // the unlabeled form
continue <label>; // the labeled form
You can also provide a loop with a label and then use the label in your continue statement. The
label name is optional, and is usually only used when you wish to return to the outermost loop in
a series of nested loops.
Below is a program to demonstrate the use of continue statement to print Odd Numbers between
1 to 10.
public class ContinueExample {
public static void main(String[] args) {
System.out.println("Odd Numbers");
for (int i = 1; i <= 10; ++i) {
if (i % 2 == 0)
continue;
// Rest of loop body skipped when i is even
System.out.println(i + "\t");
}
}
}
Output
Odd Numbers
1
3
5
7
9
Page 57
Break Statement
The break statement transfers control out of the enclosing loop ( for, while, do or switch
statement). You use a break statement when you want to jump immediately to the statement
following the enclosing control structure. You can also provide a loop with a label, and then use
the label in your break statement. The label name is optional, and is usually only used when you
wish to terminate the outermost loop in a series of nested loops.
The Syntax for break statement is as shown below;
break; // the unlabeled form
break <label>; // the labeled form
Below is a program to demonstrate the use of break statement to print numbers Numbers 1 to 10.
public class BreakExample {
public static void main(String[] args) {
System.out.println("Numbers 1 - 10");
for (int i = 1;; ++i) {
if (i == 11)
break;
// Rest of loop body skipped when i is even
System.out.println(i + "\t");
}
}
}
Output
Numbers 1 10
1
2
3
4
5
6
7
8
Page 58
9
10
/**
* Simple Java program which demonstrate use of break and continue statements in
* Java with lables, break and continue can be used alongside label and loop.
*
* @author Paramesh
*/
/**
* It performs how brak & continue statements works in java
*/
public static void performLabelDemo() {
int[] numbers = new int[] { 100, 18, 21, 30 };
Page 59
break OUTER;
}
}
}
}
Output:
Odd number: 0, current number: 100 continue from OUTER label
Even number: 1, , current number: 100 break
break keyword transfers control to next statement outside loop while continue keyword transfers
control to beginning of loop, ignoring rest of lines in loop.
break can also be used inside CASE statement of switch construct.
An optional label can be provided after break and continue which cause to apply break and continue
on specified loop.
Problem statement: Print all prime numbers from 1 20 by using for loop.
package com.sample;
public class ClassDemo {
public static String printPrimeNumber() {
StringBuilder primes = new StringBuilder("1, 2");
for (int x = 3; x <= 20; x+=2) {
boolean flag = true;
for (int y = 3; y <= (x / 2); y++) {
if (x % y == 0) {
flag = false;
break;
}
}
Core Java | JPA Solutions
Page 60
if (flag) {
primes = primes.append(", ").append(x);
}
}
return primes.toString();
}
public static void main(String[] args) {
String s = printPrimeNumber();
System.out.println(String.format("Prime Numbers from [1 20] : %s ", s));
}
}
Output:
Prime Numbers from [1 - 20] : 1, 2, 3, 5, 7, 11, 13, 17, 19
Problem statement: Write the prime numbers b/w 1 20 by using continue, break and label statements.
package com.sample;
public class ForLoopDemo {
public static String printPrimeNumber(int upto) {
StringBuilder primeNumbers = new StringBuilder("1, 2");
OUTER:
for(int x = 3; x <= upto; x+=2) {
for(int y=2; y <= x/2; y ++) {
if(x%y == 0) {
continue OUTER;
}
}
primeNumbers.append(", ").append(x);
}
return primeNumbers.toString();
}
public static void main(String[] args) {
String primes = printPrimeNumber(20);
System.out.println("Prime numbers for [1 - 20] : " + primes);
}
}
Output:
Prime Numbers from [1 - 20] : 1, 2, 3, 5, 7, 11, 13, 17, 19
Page 61
Problem statement: Write a program to sort given integer array in descending order by using while and
for loops:
Array : {30, 50, 10, 80, 90, 20, 5, 6}
Solution:
Iteration/Index
Is Swapped
Actual array
30
50
10
80
90
20
(Y / N)
Iteration #1
50
30
80
90
20
10
Iteration #2
50
80
90
30
20
10
Iteration #3
80
90
50
30
20
10
Iteration #4
90
80
50
30
20
10
Iteration #5
90
80
50
30
20
10
Iteration #1:
1. In the very first iteration, compare first element (30) & second element (50). So 30 > 50, produces
false. Hence, swap the positions.
Result array is: {50, 30, 10, 80, 90, 20, 5, 6}
2. So far we swapped first and second elements. Now again compare 2nd element with 3rd element in
the above modified array. So 30 > 10, produces true. Hence, swapping not required.
Result array is: {50, 30, 10, 80, 90, 20, 5, 6}
3. Compare 3rd element & 4th element. So 10 > 80. So swap them. Result array will be as follows:
{50, 30, 80, 10, 90, 20, 5, 6}
4. Compare 4th element with 5th element. So, 10 > 90, produces false. Swap them and the result array
will be as follows;
{50, 30, 80, 90, 10, 20, 5, 6}
5. Compare 5th element & 6th element. So, 10 > 20, produces false. Swap them and result array will be
as follows:
{50, 30, 80, 90, 20, 10, 5, 6}
6. Compare 5th and 6th elements (5 > 6), produces false. Hence swap them and the result array will be as
follows:
{50, 30, 80, 90, 20, 10, 6, 6}
Now, we have completed one iteration and found that, the highlighted elements in the table are
saturated in their positions.
Core Java | JPA Solutions
Page 62
Follow the same procedure for each iteration until all the array elements saturated in their positions.
Before swapping
After swapper
X = 30
X = 50
Y = 50
Y = 30
While condition will iterate loop till condition met false. Here, we can use flag isSwapped. Till its value
become false, we can proceed through required number of iterations and perform descending order on
sorting array.
Program:
package com.sample;
public class SortingTechniques {
public static void sortDescending(int[] num) {
// set isSwapped flag to true to begin first irteration
boolean isSwapped = true;
while (isSwapped) {
isSwapped = false; // set flag to false awaiting a possible swap
for (int index = 0; index < num.length - 1; index++) {
if (num[index] < num[index + 1]) {
// change to > for ascending sort
int temp = num[index]; // swap elements
num[index] = num[index + 1];
num[index + 1] = temp;
isSwapped = true; // shows a swap occurred
}
}
}
}
public static void main(String[] args) {
int[] arr = {30, 50, 10, 80, 90, 20, 5, 6};
sorDescending(arr);
System.out.println("Order of array :");
for(int element : arr) {
Page 63
System.out.println(element);
}
}
}
Output:
Order of array :
90
80
50
30
20
10
6
5
Problem statement: Write a program which shows menu options to the user and prompt to input to
choose option from menu. The below are the menu options.
1. Generate sum of given numbers
2. Generate multiplication of given numbers
3. Generate Fibonacci series upto the given numbers.
4. Exit from menu
Solution:
1. To show the menu options irrespective of any condition, we can use do while statement.
2. Since options are from 1 4. This can be considered as expression producing a certain range of value.
Hence, we use switch statement to best suited for this scenario.
3. To accept many number of arguments for both sum and multiplication, we can use var args concept.
Program:
package com.sample;
import java.util.Scanner;
public class WhileLoopDemo {
public static int summation(String... numbers) {
int sum = 0;
for (String str : numbers) {
sum += Integer.parseInt(str);
}
return sum;
}
Page 64
Page 65
default:
System.out.println("No choice met, hence executing default
statement");
break;
}
} while (choice < 4);
sc.close();
}
}
Output:
Choose option from [1 - 4] : 1
Input numbers separated with comma to calculate sum : 1,2,3,4,5,6,7,8,9
summation : 45
Choose option from [1 - 4] : 2
Input numbers separated with comma to calculate multiplication : 20,30,40,50
multiplication : 1200000
Choose option from [1 - 4] : 3
Please enter number to get generate fibonacci series : 500
fibonacci : 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377
Choose option from [1 - 4] : 4
No choice met, hence executing default statement
Page 66
Constructor
Constructor is a block of code, which runs when you use new keyword in order to instantiate an
object. It looks like a method, however it is not a method. Methods have return type but constructors
dont have any return type.
There are basically two rules defined for the constructor.
1. Constructor name must be same as its class name
2. Constructor must have no explicit return type
No-args Constructor: The constructor, which doesnt any parameters is called No-argument
constructor. This constructor initializes default values to instance variables.
package com.sample;
public class ConstructorDemo {
boolean bool;
byte by;
char ch;
short sh;
int i;
long l;
float f;
double d;
String str;
ConstructorDemo() {
}
public static void main(String[] args) {
ConstructorDemo demo = new ConstructorDemo();
System.out.println("boolean : " + demo.bool);
System.out.println("byte : " + demo.by);
System.out.println("character : " + demo.ch);
System.out.println("short : " + demo.sh);
System.out.println("int : " + demo.i);
System.out.println("long : " + demo.l);
System.out.println("float : " + demo.f);
System.out.println("double : " + demo.d);
System.out.println("string : " + demo.str);
}
Page 67
Output:
boolean : false
byte : 0
character :
short : 0
int : 0
long : 0
float : 0.0
double : 0.0
string : null
Default Constructor: When there is no constructor provided by programmer, then JVM provides a Noargs constructor to the class, the constructor provided by JVM in the absence of programmer provided
constructor is called default constructor. Default constructor and No-argument constructor both look
similar. But No-argument constructor can have many statements inside it, whereas compiler provided
constructor has one statement to call its super class constructor.
Parameterized Constructor: A constructor, which accept one or more arguments is called parameterized
constructor. If we define only parameterized constructors, then we cannot create an object with default
constructor. This is because compiler will not create default constructor. We need to create default
constructor explicitly if required.
While creation of object if it required to initialize instance variables with other than default values, we
can prefer parameterized constructor.
Suppose if it required to provide initial values as follows:
Int i = 10;
char ch = M;
We need to modify the constructor as follows:
package com.sample;
public class ConstructorDemo {
boolean bool;
byte by;
char ch;
Page 68
short sh;
int i;
long l;
float f;
double d;
String str;
ConstructorDemo(int i, char ch) {
this.i = i;
this.ch = ch;
}
public static void main(String[] args) {
ConstructorDemo demo = new ConstructorDemo(10, 'M');
System.out.println("boolean : " + demo.bool);
System.out.println("byte : " + demo.by);
System.out.println("character : " + demo.ch);
System.out.println("short : " + demo.sh);
System.out.println("int : " + demo.i);
System.out.println("long : " + demo.l);
System.out.println("float : " + demo.f);
System.out.println("double : " + demo.d);
System.out.println("string : " + demo.str);
}
}
boolean : false
byte : 0
character : M
short : 0
int : 10
long : 0
float : 0.0
double : 0.0
string : null
Constructor Overloading: We can define more than one constructor in a single class.
Private Constructor:
If a method is private, it means that it cannot be accessed from any class other than itself. This is the
access control mechanism provided by Java. When it is used appropriately, it can produce security and
functionality. Constructors, like regular methods, can also be declared as private. It may very curious to
know why we need a private constructor since it is only accessible from its own class. When a class needs
to prevent the caller from creating objects. Private constructors are suitable. Objects can be constructed
only internally. In the case of a singleton, the policy is that only one object of that class is supposed to
exist. Creation of multiple objects of that class is forbidden.
Core Java | JPA Solutions
Page 69
package com.sample;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.lang.reflect.Constructor;
import java.io.Serializable;
private SingletonObject() {
}
Constructor Rules
Summary of Constructors:
1. Every class has a constructor whether its normal one or an abstract class.
2. As stated above, constructor is not methods and it doesnt have any return type.
Core Java | JPA Solutions
Page 70
Page 71
int variable = 5;
vh.method(20);
vh.method();
}
void method() {
int variable = 40;
System.out.println("Value of variable :" + variable);
}
}
Output:
Value of variable :10
Value of variable :40
Page 72
As we can Instance Variable is hiding here and value getting displayed is the value of Local Variable (or
Method Parameter) and not Instance Variable. To solve this problem this keyword can be used with field
to point Instance Variable instead of Local Variable.
int variable = 5;
vh.method(20);
vh.method();
}
void method() {
int variable = 40;
System.out.println("Value of Instance variable :" + this.variable);
System.out.println("Value of variable :" + variable);
}
}
Output:
Value of Instance variable :5
Value of Local variable :10
Value of Instance variable :5
Value of Local variable :40
Page 73
Inheritance:
Inheritance is one of the key features of Object Oriented Programming. Inheritance provided mechanism
that allowed a class to inherit property of another class. When a Class extends another class it inherits all
non-private members including fields and methods. Inheritance in Java can be best understood in terms
of Parent and Child relationship, also known as Super class(Parent) and Sub class(child) in Java language.
Java Inheritance defines an is-a relationship between a superclass and its subclasses. This means that an
object of a subclass can be used wherever an object of the superclass can be used.
Purpose of Inheritance
1. To promote code reuse.
2. To use Polymorphism.
Types of Inheritance
1. Single Inheritance
2. Multilevel Inheritance
3. Hierarchical Inheritance
Page 74
To reduce the complexity and simplify the language, multiple inheritance is not supported in java.
Consider a scenario where A, B and C are three classes. The C class inherits A and B classes. If A and B
classes have same method and we call it from child class object, there will be ambiguity to call method of
A or B class.
super keyword:
In Java, super keyword is used to refer to immediate parent class of a class. In other
words super keyword is used by a subclass whenever it requires to refer to its immediate super class.
Page 75
Example of Child class referring Parent class property using super keyword
class Parent {
String name;
Page 76
Example of Child class refering Parent class methods using super keyword
class Parent {
String name;
Example of Child class calling Parent class constructor using super keyword
class Parent {
String name;
public Parent(String n) {
name = n;
}
Page 77
Abstract Class:
The keyword abstract means incomplete. Abstract classes are used in java to create a class with some
default method implementation for subclasses. An abstract class can have abstract method without body
and it can have methods with implementation also. abstract keyword is used to create a abstract class.
Abstract classes cant be instantiated and mostly used to provide base for sub-classes to extend and
implement the abstract methods and override or use the implemented methods in abstract class.
Moreover, an abstract class may contain methods without any implementation, called abstract methods.
The declaration of an abstract method starts with the abstract keyword and ends with a semicolon,
instead of the methods body. If a class contains an abstract method, either declared or inherited, it must
be declared as an abstract class.
A class that extends an abstract class must implement all its abstract methods (if any). Otherwise, the
sub-class must be declared as abstract as well. Finally, any implementation of an abstract method can be
overridden by additional sub-classes.
Last things to mention are that abstract classes can also implement methods, despite providing just their
signature and that an abstract class may have static fields and static methods.
Core Java | JPA Solutions
Page 78
The purpose of an abstract class is to specify the default functionality of an object and let its sub-classes
to explicitly implement that functionality. Thus, it stands as an abstraction layer that must be extended
and implemented by the corresponding sub-classes.
Syntax:
<access_specifier> abstract class ClassName { }
Abstract method
Method that is declared without any body within an abstract class is known as abstract method. The
method body will be defined by its subclass. Abstract method can never be final and static. Any class that
extends an abstract class must implement all the abstract methods declared by the super class. If we
want a class to contain a particular method but you want the actual implementation of that method to be
determined by child classes, you can declare the method in the parent class as abstract.
abstract return_type function_name ();
// No definition
The class must also be declared abstract. If a class contains an abstract method, the class must be
abstract as well.
Any child class must either override the abstract method or declare itself abstract.
A child class that inherits an abstract method must override it. If they do not, they must be
abstract and any of their children must override it.
Eventually, a descendant class has to implement the abstract method; otherwise, you would have
a hierarchy of abstract classes that cannot be instantiated.
Abstract class having constructor, data member, methods etc
An abstract class can have data member, abstract method, method body, constructor and even main()
method.
Page 79
Note:
We can use abstract keyword to create an abstract method, an abstract method doesnt have body.
If a class has abstract methods, then the class also needs to be made abstract using abstract keyword,
else it will not compile.
Page 80
If abstract class doesnt have any method implementation, its better to use interface because java
doesnt support multiple class inheritance.
The subclass of abstract class must implement all the abstract methods unless the subclass is also an
abstract class.
All the methods in an interface are implicitly abstract unless the interface methods are static or
default. Static methods and default methods in interfaces are added in Java 8, for more details read
Java 8 interface changes.
Abstract classes can implement interfaces without even providing the implementation of interface
methods.
Abstract classes are used to provide common method implementation to all the subclasses or to
provide default implementation.
We can run abstract class like any other class if it has main() method.
Polymorphism:
Polymorphism is the capability of a method to do different things based on the object that it is acting
upon. In other words, polymorphism allows you define one interface and have multiple implementations.
In more simple words, polymorphism is the ability by which, we can create functions or reference
variables which behaves differently in different programmatic context.
Page 81
1.1. Parameter type: Type of method parameters can be different. e.g. java.util.Math.max() function
comes with following versions:
public static double Math.max(double a, double b){}
public static float Math.max(float a, float b){}
public static int Math.max(int a, int b){}
public static long Math.max(long a, long b){}
The actual method to be called is decided on compile time based on parameters passed to function in
program.
Parameter count: Functions accepting different number of parameters.
Let's say a dog makes a woof sound, but if the dog is injured, the dog might make a whimper noise
instead. How can we use makeSound() to produce both sounds? Take a look at this code snippet:
public class Dog extends Animal {
public void makeSound() {
System.out.println("Woof");
}
We can see here that depending on the number of parameters we pass to makeSound(), the dog will
make a different sound.
2. Method Overriding:
Suppose if we take real time example; Car, Bus, Auto are comes under Vehicle category. Whenever we
can find Vehicle, can be replace with any one from its category.
By means of that, we can say:
Car is-a Vehicle,
Bus is-a Vehicle,
Auto is-a Vehicle.
In Java, parent and child class process IS-A relationship. It means that, we can assign child class object to
its parent class reference. Non-private method of a parent class can be overridden by all its child classes.
Core Java | JPA Solutions
Page 82
Hence, the overridden method behavior will change the based on the object we are going to assign at run
time to the parent class reference.
Ex:
Country.java
package com.sample.child;
public class Country {
public String getCurrencyCode() {
return "USD";
}
}
India.java
package com.sample.child;
public class India extends Country {
@Override
public String getCurrencyCode() {
return "INR";
}
}
Japan.java:
Core Java | JPA Solutions
Page 83
package com.sample.child;
public class Japan extends Country {
@Override
public String getCurrencyCode() {
return "YEN";
}
}
MethodOverridingDemo.java:
package com.sample.child;
public class MethodOverridingDemo {
static Country country = new Country();
public static void main(String[] args) {
System.out.println("Currency Code for base class object : " +
country.getCurrencyCode());
country = new India();
System.out.println("Currency Code for India class object : " +
country.getCurrencyCode());
country = new Japan();
System.out.println("Currency Code for Japan class object : " +
country.getCurrencyCode());
}
}
Output:
Currency Code for base class object : USD
Currency Code for India class object : INR
Currency Code for Japan class object : YEN
As we can have multiple subtype implementations for a super type, Java virtual machine
determines the proper type to be invoked at the runtime. Here, all the three times we just
invoked method as country.getCurrencyCode()), but produces three different outputs based on the
object acting on it.
Page 84
Interface
Its business rule documentation or it defines the contract between different parties that needs to be
obeyed. It is a promise to provide certain behaviour and all classes which implement the interface
guarantee to also implement those behaviour. To define the expected behavior, the interface contains a
number of method signatures. Any class which uses the interface can rely on those methods being
implemented in the runtime class which implements the interface. This allows anyone using the interface
to know what functionality will be provided without having to worry about how that functionality will
actually be achieved.
An Interface contains:
All public abstract methods
All public static final variables.
Core Java | JPA Solutions
Page 85
Syntax:
public interface <InterfaceName> {
public static final <data_type> var_name1 = <constant>;
public static final <data_type> var_name2 = <constant>;
.
.
.
Ex:
package com.sample;
/**
*
* @author Paramesh
*
*
This interface is useful for few arithmatic operations like sum,
*
multiplication, abstract, devide, reminder
*
*/
public interface ArithmaticInterface {
/**
* Calculate the sum of all given inputs
*
* @param x
*
first input
* @param y
*
second input
* @return (x+y)
*/
public abstract int summation(int x, int y);
/**
* Multiply both given input and provide result back
Page 86
*
* @param x
* @param y
* @return (x*y)
*/
public abstract int multiplication(int x, int y);
/**
* Substract second input from first one and provide the result back
*
* @param x
* @param y
* @return (x - y)
*/
public abstract long sbutract(long x, long y);
/**
* It devides fist input with second and provide the result back
*
* @param x
* @param y
* @return (x / y)
*/
public abstract float devide(float x, float y);
/**
* It devides first input with second one and provide their reminder
*
* @param x
* @param y
* @return (x % y)
*/
public abstract double reminder(double x, double y);
}
Note: Its always recommended to write enough comments at both interface level and method level to
provide better understanding to client to use.
In the above interface, none of the methods have body. Each method has its own parameters and return
types. All implementer classes of this interface should follow the same signature (contract).
Interfaces are mainly used for:
1. Loose coupling
2. To achieve fully abstraction
Interfaces can declare only Constants and variables inside interface are implicitly public static
final.
Core Java | JPA Solutions
Page 87
Implementing an Interface:
If we want to create a class which will provide implementation for all the behaviours of the above
interface, we can use implements key word to convey to the compiler as going to provide definition for
the incomplete (abstract) methods.
package com.sample;
public class ArithmaticImplementer implements ArithmaticInterface {
@Override
public int summation(int x, int y) {
return (x + y);
}
@Override
public int multiplication(int x, int y) {
return (x * y);
}
@Override
public int sbutract(int x, int y) {
return (x - y);
}
@Override
public int devide(int x, int y) {
return (x / y);
}
@Override
public int reminder(int x, int y) {
return (x % y);
}
}
If we fail to provide implementation for any method, class file cannot be compiled.
Page 88
Marker Interfaces:
Marker interface is used as a tag to inform a message to the Java compiler so that it can add special
behaviour to the class implementing it. Java marker interface has no fields or methods in it.
Hence, an empty interface in java is called a marker interface. Marker interface is also called tag
interface. In java we have the following major marker interfaces as under:
Searilizable interface
Cloneable interface
The marker interface can be described as a design pattern which is used by many languages to
provide run-time type information about the objects. The marker interface provides a way to
associate metadata with the class where the language support is not available.
A normal interface specifies functionality which an implementing class must implement. But a
marker interface does not follow that pattern. On the other side, the implementing class defines
the behavior. There are some hybrid interfaces which act as a marker interface along with some
methods. But this type of design is confusing if not handled carefully.
From java 1.5, the need for marker interface is eliminated by the introduction of the java annotation
feature. So, it is wise to use java annotations than the marker interface. It has more feature and
advantages than the java marker interface.
Page 89
All methods in an interface are implicitly abstract. On the other hand, an abstract class may contain
both abstract and non-abstract methods.
A class may implement a number of Interfaces, but can extend only one abstract class.
In order for a class to implement an interface, it must implement all its declared methods. However,
a class may not implement all declared methods of an abstract class. Though, in this case, the subclass must also be declared as abstract.
Abstract classes can implement interfaces without even providing the implementation of interface
methods.
Variables declared in a Java interface is by default public static final. An abstract class may contain
non-final variables.
Members of a Java interface are public by default. A member of an abstract class can either be
private, protected or public.
An interface is absolutely abstract and cannot be instantiated. An abstract class also cannot be
instantiated, but can be invoked if it contains a main method.
Abstraction:
In Object Oriented Programming Language, Abstraction is a way to segregate implementation. In
general, Abstraction is a concept of exposing only the required essential characteristics and behavior
with respect to a context.
The process of creating a complex system by hiding all the implementation details from outside worlds
and expose only meaningful operations to interact with it is called as Abstraction.
Example: mobile or cell phone. The main purpose of both is to make call and here the voice of other
person. Both allow us to make call through key pad and never exposes how internally connects with
other mobile/cell and send/receive voice signals from other end.
In Java, abstraction can be achieved through abstract classes and interfaces.
Use case:
Build a payment system for a company that has two kinds of employees (say Contract & Permanent
employees). Permanent employees will receive payment through salary, whereas contract employees will
receive payment through commission. The manager of the company expecting that, system may be
changed later to accommodate different types of entities which will receive payments.
Page 90
Solution:
1. The two types of employees will receive the payment on either commission basis or fixed pay basis. So,
however both are liable to receive the payment at the end of the month. Hence, we can consider both
kinds of employees as Payee.
2. To deposit money to employees account, bank expects
Employee name
Amount to be deposit
So, we can create a Payee interface as follows:
package com.emp.payroll;
public interface Payee {
String name();
Double grossPayment();
String bankAccount();
}
Note: All the methods of an interface, implicitly public and abstract. So no need to use public & abstract
modifiers again.
Hence, the above interface has ability to provide employee name, payment amount & account to be
deposited.
3. Since the organization can have many number of employees and they need to pick each and every
employee. Calculate the payment and request to bank to deposit the money to corresponding account.
Cycle through all employees and follow the same.
package com.emp.payroll;
import java.util.ArrayList;
import java.util.List;
public class PaymentSystem {
private List<Payee> payees;
/**
* Initiate Payee list
*/
public PaymentSystem() {
payees = new ArrayList<Payee>();
Page 91
}
/**
* Add a new Payee, when new employee joined with organization
*
* @param payee {@link Payee}
*/
public void addPayee(Payee payee) {
if (!payees.contains(payee)) {
payees.add(payee);
}
}
/**
* Remove Payee, when he resigned from his responsibilities
*
* @param payee {@link Payee}
*/
public void removePayee(Payee payee) {
if (payees.contains(payee)) {
payees.remove(payee);
}
}
/**
* Cycle through all the {@link Payee}(s) and perform deposit money to
* their
* account
*/
public void processPayments() {
for (Payee payee : payees) {
Double grossPayment = payee.grossPayment();
System.out.println("=======================================");
System.out.println("Paying to employee " + payee.name());
System.out.println("\tAmount deposited :" + grossPayment);
System.out.println("\tTransferred to Account : " +
payee.bankAccount());
}
}
}
4. Since the organization has two kinds of employees called Contract & Permanent. So, we need to create
two kinds of classes to represent them. Since, Payment system needs to recognize these two types, we
can define PermanentEmployee and ContractEmployee classes by implementing Payee interface.
PermanentEmployee.java:
package com.emp.payroll;
public class PermanentEmployee implements Payee {
Page 92
ContractEmployee.java:
package com.emp.payroll;
public class ContractEmployee implements Payee {
private String name;
private String bankAccount;
protected Double grossWage;
public ContractEmployee(String name, String bankAccount, Double grossWage) {
this.name = name;
this.bankAccount = bankAccount;
this.grossWage = grossWage;
}
public String bankAccount() {
return bankAccount;
}
public String name() {
return name;
}
public Double grossPayment() {
return (grossWage * 30 ) / 100;
}
}
Page 93
From above two classes, we can observe that, only behaviour grossPayment() differs in each object. So,
to build similar kind of objects Abstract class is the best suitable rather than implementing common
features in each and every object.
Hence, introduce Employee abstract class as follows:
package com.emp.payroll;
public abstract class Employee implements Payee {
private String name;
private String bankAccount;
protected Double grossWage;
public Employee(String name, String bankAccount, Double grossWage) {
this.name = name;
this.bankAccount = bankAccount;
this.grossWage = grossWage;
}
public String name() {
return name;
Page 94
}
public String bankAccount() {
return bankAccount;
}
}
ContractEmployee.java: Extend this with Employee class to reuse default implementation instead
implementing all the methods from Payee interface.
package com.emp.payroll;
public class ContractEmployee extends Employee {
public ContractEmployee(String name, String bankAccount, Double grossWage) {
super(name, bankAccount, grossWage);
}
public Double grossPayment() {
return (grossWage * 30 ) / 100;
}
}
PermanentEmployee.java: Extend this with Employee class to reuse default implementation instead
implementing all the methods from Payee interface.
package com.emp.payroll;
public class PermanentEmployee extends Employee {
public PermanentEmployee(String name, String bankAccount, Double grossWage) {
super(name, bankAccount, grossWage);
}
public Double grossPayment() {
return grossWage;
}
}
ProcesspaymentApplication.java:
package com.emp.payroll;
public class ProcessPaymentApplication {
public static void main(final String... args) {
// Initialization
PaymentSystem paymentSystem = new PaymentSystem();
ContractEmployee contEmp1 = new ContractEmployee("Contract Employee 1",
"1111", 300.0);
paymentSystem.addPayee(contEmp1);
Page 95
Output:
===================================================
Paying to employee Contract Employee 1
Amount deposited :90.0
Transferred to Account : 1111
===================================================
Paying to employee Contract Employee 2
Amount deposited :105.0
Transferred to Account : 2222
===================================================
Paying to employee Contract Employee 3
Amount deposited :500.0
Transferred to Account : 3333
===================================================
Paying to employee Contract Employee 4
Amount deposited :470.0
Transferred to Account : 4444
Page 96
Marker Interfaces:
Page 97
Exception Handling:
An exception is an event that occurs during the execution of a program that disrupts the normal flow of
instructions. In Java, all exceptions are objects.
When an error occurs within a method, the method creates an object and hands it off to the runtime
system. The object, called an exception object, contains information about the error, including its type
and the state of the program when the error occurred. Creating an exception object and handing it to the
runtime system is called throwing an exception.
After a method throws an exception, the runtime system attempts to find something to handle it. The set
of possible "somethings" to handle the exception is the ordered list of methods that had been called to
get to the method where the error occurred. The list of methods is known as the call stack (see the next
figure).
The runtime system searches the call stack for a method that contains a block of code that can handle the
exception. This block of code is called an exception handler. The search begins with the method in which
the error occurred and proceeds through the call stack in the reverse order in which the methods were
called. When an appropriate handler is found, the runtime system passes the exception to the handler.
An exception handler is considered appropriate if the type of the exception object thrown matches the
type that can be handled by the handler.
The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches
all the methods on the call stack without finding an appropriate exception handler, as shown in the next
figure, the runtime system (and, consequently, the program) terminates.
Page 98
Page 99
2. Checked Exceptions: Checked Exceptions are exceptional scenarios that we can anticipate in a
program and try to recover from it, for example FileNotFoundException. We should catch this
exception and provide useful message to user and log it properly for debugging purpose.
Exception is the parent class of all Checked Exceptions and if we are throwing a checked
exception, we must catch it in the same method or we have to propagate it to the caller using
throws keyword.
Ex:
ClassNotFoundException
InterruptedException
NoSuchMethodException
IOException
EOFException
FileNotFoundException
MalformedURLException
UnknownHostException
3. Runtime Exception: Runtime Exceptions are cause by bad programming, for example trying to
retrieve an element from the Array. We should check the length of array first before trying to
retrieve the element otherwise it might throw ArrayIndexOutOfBoundException at runtime.
RuntimeException is the parent class of all runtime exceptions. If we are throwing any runtime
exception in a method, its not required to specify them in the method signature throws clause.
Runtime exceptions can be avoided with better programming.
Ex:
ArithmeticException
ClassCastException
IllegalArgumentException
o NumberFormatException
IndexOutOfBoundsException
o ArrayIndexOutOfBoundsException
o StringIndexOutOfBoundsException
NegativeArraySizeException
NullPointerException
NoSuchElementException
Page 100
Page 101
Exception and all of its subclasses doesnt provide any specific methods and all of the methods are
defined in the base class Throwable. The exception classes are created to specify different kind of
exception scenarios so that we can easily identify the root cause and handle the exception according to
its type. Throwable class implements Serializable interface for interoperability.
Some of the useful methods of Throwable class are;
1. public String getMessage() This method returns the message String of Throwable and the
message can be provided while creating the exception through its constructor.
2. public String getLocalizedMessage() This method is provided so that subclasses can override it to
provide locale specific message to the calling program. Throwable class implementation of this
method simply use getMessage() method to return the exception message.
3. public synchronized Throwable getCause() This method returns the cause of the exception or
null id the cause is unknown.
4. public String toString() This method returns the information about Throwable in String format,
the returned String contains the name of Throwable class and localized message.
Page 102
5. public void printStackTrace() This method prints the stack trace information to the standard error
stream, this method is overloaded and we can pass PrintStream or PrintWriter as argument to write
the stack trace information to the file or stream.
Exception Handling Mechanism:
1. Using try and catch: Try is used to guard a block of code in which exception may occur. This block of
code is called guarded region. A catch statement involves declaring the type of exception you are
trying to catch. If an exception occurs in guarded code, the catch block that follows the try is checked,
if the type of exception that occurred is listed in the catch block then the exception is handed over to
the catch block which then handles it.
Program:
class Excp {
public static void main(String args[]) {
int a, b, c;
try {
a = 0;
b = 10;
c = b / a;
System.out.println("This line will not be executed");
} catch (ArithmeticException e) {
System.out.println("Divided by zero");
}
System.out.println("After exception is handled");
}
}
Output:
output:
Divided by zero
After exception is handled
Explanation:
An exception will thrown by this program as we are trying to divide a number by zero
inside try block. The program control is transfered outside try block. Thus the line "This line will
not be executed" is never parsed by the compiler. The exception thrown is handle in catch block.
Once the exception is handled the program controls continue with the next line in the program.
Thus the line "After exception is handled" is printed.
Page 103
2. Multiple catch blocks: A try block can be followed by multiple catch blocks. You can have any number
of catch blocks after a single try block.If an exception occurs in the guarded code the exception is
passed to the first catch block in the list. If the exception type of exception, matches with the first
catch block it gets caught, if not the exception is passed down to the next catch block. This continues
until the exception is caught or falls through all catches.
class Excep {
public static void main(String[] args) {
try {
int arr[] = { 1, 2 };
arr[2] = 3 / 0;
} catch (ArithmeticException ae) {
System.out.println("divide by zero");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("array index out of bound exception");
}
}
}
Output:
divide by zero
3. Creating Custom Exception Classes: Java provides a lot of exception classes for us to use but
sometimes we may need to create our own custom exception classes to notify the caller about
specific type of exception with appropriate message and any custom fields we want to introduce for
tracking, such as error codes. For example, lets say we write a method to process only text files, so
we can provide caller with appropriate error code when some other type of file is sent as input.
Page 104
CustomExceptionExample.java:
import
import
import
import
java.io.FileInputStream;
java.io.FileNotFoundException;
java.io.IOException;
java.io.InputStream;
Page 105
we can catch multiple exceptions in a single catch block. If you are catching multiple exceptions and
they have similar code, then using this feature will reduce code duplication. Lets understand this with
an example.
Prior to Java 7:
catch (IOException ex) {
logger.error(ex);
throw new MyException(ex.getMessage());
} catch (SQLException ex) {
logger.error(ex);
throw new MyException(ex.getMessage());
} catch (Exception ex) {
logger.error(ex);
throw new MyException(ex.getMessage());
}
In Java 7, we can catch all these exceptions in a single catch block as:
catch(IOException | SQLException | Exception ex){
logger.error(ex);
throw new MyException(ex.getMessage());
}
If a catch block handles multiple exception, you can separate them using a pipe (|) and in this case
exception parameter (ex) is final, so you cant change it. The byte code generated by this feature is
smaller and reduces code redundancy.
2. Automatic resource management: Resources such as Connections, Files, Input/OutStreams, etc.
should be closed manually by the developer by writing bog-standard code. Usually we use a try-finally
block to close the respective resources. See the current practice of creating a resource, using it and finally
closing it:
Prior Java 7: Resource Handling
package com.sample;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ResourceHandling {
Page 106
Page 107
Then the exception stack trace will be like below that clearly shows where the exception has
occurred with clear message.
com.journaldev.exceptions.MyException: File name can't be null
at
com.journaldev.exceptions.CustomExceptionExample.processFile(CustomExcepti
onExample.java:37)
at
com.journaldev.exceptions.CustomExceptionExample.main(CustomExceptionExamp
le.java:12)
3. Catch Late Since java enforces to either handle the checked exception or to declare it in method
signature, sometimes developers tend to catch the exception and log the error. But this practice is
harmful because the caller program doesnt get any notification for the exception. We should catch
exception only when we can handle it appropriately. For example, in above method I am throwing
exception back to the caller method to handle it. The same method could be used by other applications
that might want to process exception in a different manner. While implementing any feature, we
should always throw exceptions back to the caller and let them decide how to handle it.
4. Closing Resources Since exceptions halt the processing of program, we should close all the
resources in finally block or use Java 7 try-with-resources enhancement to let java runtime close it for
you.
5. Logging Exceptions We should always log exception messages and while throwing exception
provide clear message so that caller will know easily why the exception occurred. We should always
Page 108
avoid empty catch block that just consumes the exception and doesnt provide any meaningful details
of exception for debugging.
6. Single catch block for multiple exceptions Most of the times we log exception details and
provide message to the user, in this case we should use java 7 feature for handling multiple exceptions
in a single catch block. This approach will reduce our code size and it will look cleaner too.
7. Using Custom Exceptions Its always better to define exception handling strategy at the design
time and rather than throwing and catching multiple exceptions, we can create a custom exception with
error code and caller program can handle these error codes. Its also a good idea to create a utility
method to process different error codes and use it.
8. Naming Conventions and Packaging When you create your custom exception, make sure it ends
with Exception so that it will be clear from name itself that its an exception. Also make sure to package
them like its done in JDK, for example IOException is the base exception for all IO operations.
9. Use Exceptions Judiciously Exceptions are costly and sometimes its not required to throw
exception at all and we can return a boolean variable to the caller program to indicate whether an
operation was successful or not. This is helpful where the operation is optional and you dont want your
program to get stuck because it fails. For example, while updating the stock quotes in database from a
third party webservice, we may want to avoid throwing exception if the connection fails.
10. Document the Exceptions Thrown Use javadoc @throws to clearly specify the exceptions
thrown by the method, its very helpful when you are providing an interface to other applications to use.
Page 109
Enumerations
Enumerations (in general) are generally a set of related constants. Enumerations were added to Java
language in JDK5. An Enumeration can have constructors, methods and instance variables. It is created
using enum keyword. Each enumeration constant is public, static and final by default. Even though
enumeration defines a class type and have constructors, we cannot instantiate an enum using new.
Enumeration variables are used and declared in much a same way as we do a primitive variable.
Enumeration in java is supported by keyword enum. enums are a special type of class that always
extends java.lang.Enum. Since its already extending Enum class, cannot extend any other classes, since
java doesnt support multiple inheritances.
This clearly means that enums are comparable and serializable implicitly. Also, all enum types in java
are singleton by default. So, you can compare enum types using == operator also.
How to Define and Use an Enumeration
public enum Day {
MONDAY,
TEUSDAY,
WEDNESSDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY;
}
Identifiers SUNDAY, MONDAY, TEUSDAY, WEDNESSDAY, THURSDAY, FRIDAY & SATURDAY are called
enumeration constants. These are public, static final by default.
We should always use enums when a variable (especially a method parameter) can only take
one out of a small set of possible values.
Enum in switch statement:
Enum in Java are type-safe.
public class EnumSwitch {
public static void dayDetails(Day day) {
switch (day) {
case MONDAY:
System.out.println("First day in a week.");
break;
case TEUSDAY:
System.out.println("Second day in a week.");
break;
case WEDNESSDAY:
System.out.println("Third day in a week.");
break;
case THURSDAY:
Page 110
Output:
First day in a week.
Second day in a week.
Third day in a week.
Fourth day in a week.
Fifth day in a week.
Sixth day in a week.
Iterate an enum:
We can iterate an enum by using values() method as follows:
public class EnumIterate {
public static void main(String[] args) {
iterateEnum();
}
public static void iterateEnum() {
for(Day currentDay : Day.values()) {
System.out.println(currentDay);
}
}
}
Page 111
Output:
MONDAY
TEUSDAY
WEDNESSDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
Constructor in Enum:
public enum Day {
MONDAY(false),
TEUSDAY(false),
WEDNESSDAY(false),
THURSDAY(false),
FRIDAY(false),
SATURDAY(true),
SUNDAY(true);
private boolean isWeekend;
private Day(boolean isWeekend) {
this.isWeekend = isWeekend;
}
public static boolean isWeeken(Day day) {
return day.isWeekend;
}
}
Notes:
Page 112
Constructors for an enum type should be declared as private. The compiler allows non private
declares for constructors, but this seems misleading to the reader, since new can never be used
with enum types.
Since these enumeration instances are all effectively singletons, they can be compared for
equality using identity (==).
Page 113
Collection Framework
The Java language supports arrays to store several objects. An array is initialized with an predefined size
during instantiation. To support more flexible data structures the core Java library provides
the collection framework. A collection is a data structure which contains and processes a set of data. The
data stored in the collection is encapsulated and the access to the data is only possible via predefined
methods. For example the developer can add elements to an collection via a method. Collections use
internally arrays for their storage but hide the complexity of managing the dynamic size from the
developer.
Type information with generics: Java collections should get parameterized with a type declaration. This
enables the Java compiler to check if you try to use the collection with the correct type of
objects. Generics allow a type or method to operate on objects of various types while providing compiletime type safety. Before generics, it needs to cast every object we read from a collection and if we
inserted an object of the wrong type into a collection you would create a runtime exception.
Interfaces: These are abstract data types that represent collections. Interfaces allow
collections to be manipulated independently of the details of their representation. In objectoriented languages, interfaces generally form a hierarchy.
Algorithms: These are the methods that perform useful computations, such as searching and
sorting, on objects that implement collection interfaces. The algorithms are said to be
polymorphic: that is, the same method can be used on many different implementations of the
appropriate collection interface. In essence, algorithms are reusable functionality.
Page 114
Reduces programming effort: By providing useful data structures and algorithms, the
Collections Framework frees you to concentrate on the important parts of your program rather
than on the low-level "plumbing" required to make it work. By facilitating interoperability
among unrelated APIs, the Java Collections Framework frees you from writing adapter
objects or conversion code to connect APIs.
Increases program speed and quality: This Collections Framework provides highperformance, high-quality implementations of useful data structures and algorithms. The
various implementations of each interface are interchangeable, so programs can be easily
tuned by switching collection implementations. Because you're freed from the drudgery of
writing your own data structures, you'll have more time to devote to improving programs'
quality and performance.
Allows interoperability among unrelated APIs: The collection interfaces are the vernacular
by which APIs pass collections back and forth. If my network administration API furnishes a
collection of node names and if your GUI toolkit expects a collection of column headings, our
APIs will interoperate seamlessly, even though they were written independently.
Reduces effort to learn and to use new APIs: Many APIs naturally take collections on input
and furnish them as output. In the past, each such API had a small sub-API devoted to
manipulating its collections. There was little consistency among these ad hoc collections subAPIs, so you had to learn each one from scratch, and it was easy to make mistakes when using
them. With the advent of standard collection interfaces, the problem went away.
Reduces effort to design new APIs: This is the flip side of the previous advantage. Designers
and implementers don't have to reinvent the wheel each time they create an API that relies on
collections; instead, they can use standard collection interfaces.
Fosters software reuse: New data structures that conform to the standard collection
interfaces are by nature reusable. The same goes for new algorithms that operate on objects
that implement these interfaces.
Page 115
Map
Set
List
Collection Class
name
Hashtable
HashMap
TreeMap
LinkedHashMap
HashSet
TreeSet
LinkedHashSet
ArrayList
Vector
LinkedList
Priority queue
Ordered
No
No
Sorted
By insertion order or last access order
No
Sorted
By insertion order
Indexed
Indexed
Indexed
Sorted
Sorted
No
No
By natural order or custom order
No
No
By natural order or custom order
No
No
No
No
By to-do order
Collection the root of the collection hierarchy. A collection represents a group of objects
known as its elements. The Collection interface is the least common denominator that all
Page 116
collections implement and is used to pass collections around and to manipulate them when
maximum generality is desired. Some types of collections allow duplicate elements, and others do
not. Some are ordered and others are unordered. The Java platform doesn't provide any direct
implementations of this interface but provides implementations of more specific subinterfaces, such
as Set and List. Also see The Collection Interface section.
Set a collection that cannot contain duplicate elements. This interface models the mathematical
set abstraction and is used to represent sets, such as the cards comprising a poker hand, the courses
making up a student's schedule, or the processes running on a machine. See also The Set Interface
section.
List an ordered collection (sometimes called a sequence). Lists can contain duplicate elements.
The user of a List generally has precise control over where in the list each element is inserted and
can access elements by their integer index (position). If you've used Vector, you're familiar with the
general flavor of List. Also see The List Interface section.
Queue a collection used to hold multiple elements prior to processing. Besides basic Collection
operations, a Queue provides additional insertion, extraction, and inspection operations.
Queues typically, but do not necessarily, order elements in a FIFO (first-in, first-out) manner.
Among the exceptions are priority queues, which order elements according to a supplied
comparator or the elements' natural ordering. Whatever the ordering used, the head of the
queue is the element that would be removed by a call to remove or poll. In a FIFO queue, all
new elements are inserted at the tail of the queue. Other kinds of queues may use different
placement rules. Every Queue implementation must specify its ordering properties. Also see
The Queue Interface section.
Deque a collection used to hold multiple elements prior to processing. Besides basic Collection
operations, a Deque provides additional insertion, extraction, and inspection operations.
Deques can be used both as FIFO (first-in, first-out) and LIFO (last-in, first-out). In a deque
all new elements can be inserted, retrieved and removed at both ends. Also see The Deque
Interface section.
Map an object that maps keys to values. A Map cannot contain duplicate keys; each key can map to
at most one value. If you've used Hashtable, you're already familiar with the basics of Map. Also see
The last two core collection interfaces are merely sorted versions of Set and Map:
SortedSet a Set that maintains its elements in ascending order. Several additional operations
are provided to take advantage of the ordering. Sorted sets are used for naturally ordered sets, such
as word lists and membership rolls. Also see The SortedSet Interface section.
SortedMap a Map that maintains its mappings in ascending key order. This is the Map analog of
SortedSet. Sorted maps are used for naturally ordered collections of key/value pairs, such as
dictionaries and telephone directories. Also see The SortedMap Interface section.
Page 117
Boolean
Ensures that this collection contains the specified element (optional operation).
addAll(Collection<? extends E> c)
Boolean
Adds all of the elements in the specified collection to this collection (optional
operation).
clear()
Void
Returns true if this collection contains all of the elements in the specified
collection.
equals(Object o)
Boolean
Page 118
isEmpty()
Boolean
Boolean
Removes all of this collection's elements that are also contained in the specified
collection (optional operation).
retainAll(Collection<?> c)
Boolean
Retains only the elements in this collection that are contained in the specified
collection (optional operation).
size()
Int
Returns an array containing all of the elements in this collection; the runtime type
of the returned array is that of the specified array.
ArrayList:
In addition to the Arrays class, Java provides an ArrayList class which can be used to create
containers that store lists of objects. ArrayList can be considered as a growable array. It gives us
fast iteration and fast random access. ArrayList implements the new RandomAccess interfacea
marker interface (meaning it has no methods) that says, "This list supports fast (generally constant
time) random access".
Page 119
Earlier versions of Java have one legacy collection class called Vector which is very much similar
to ArrayList. Vector implements a dynamic array. A Vector is basically the same as an ArrayList,
but Vector methods are synchronized for thread safety. You'll normally want to use ArrayList
instead of Vector because the synchronized methods add a performance hit you might not need. In
this tutorial we will discuss about ArrayList only considering all is applicable to Vector as well.
The java.util.ArrayList class is one of the most commonly used of all the classes in the
Collections Framework.An ArrayList is dynamically resizable, meaning that its size can change
during program execution. This means that:
You can add an item at any point in an ArrayList container and the array size expands
automatically to accommodate the new item.
You can remove an item at any point in an ArrayList container and the array size contracts
automatically.
To state the obvious: Arraylist is an ordered collection (by index), but not sorted.
To use the ArrayList class, you must use the following import statement:
import java.util.ArrayList;
Then, to declare an ArrayList, you can use the default constructor, as in the following example:
ArrayList names = new ArrayList();
The default constructor creates an ArrayList with a capacity of 10 items. The capacity of an ArrayList is
the number of items it can hold without having to increase its size. Other constructors of ArrayList as
follows,
ArrayList names = new ArrayList(int size);
You can also specify a capacity/size of initial ArrayList as well as create ArrayList from other
collection types.
Some of the advantages ArrayList has over arrays are
Methods of ArrayList:
Core Java | JPA Solutions
Page 120
Method
public void add(Object)
public void add(int,
Object)
public void remove(int)
public void set(int,
Object)
Object get(int)
public int size()
Purpose
Adds an item to an ArrayList. The default version adds an item at the next
available location; an overloaded version allows you to specify a position at
which to add the item
Removes an item from an ArrayList at a specified location
Alters an item at a specified ArrayList location
Retrieves an item from a specified location in an ArrayList
Returns the current ArrayList size
LinkedList
A LinkedList is ordered by index position, like ArrayList, except that the elements are doublylinked to one another. This linkage gives you new methods (beyond what you get from the List
interface) for adding and removing from the beginning or end, which makes it an easy choice for
implementing a stack or queue. Linked list has concept of nodes and data. Here Node is storing
values of next node while data stores the value it is holding. Below diagram shows how
LinkedList storing values. There are three elements in LinkedList A, B and C. We are removing
element B from middle of the LinkedList which will just change node value of element As node
to point to node C.
Keep in mind that a LinkedList may iterate more slowly than an ArrayList, but it's a good choice
when you need fast insertion and deletion.
LinkedList has the two constructors shown here:
LinkedList( )
LinkedList(Collection<? extends E> c)
The first constructor builds an empty linked list. The second constructor builds a linked list that is
initialized with the elements of the collection c.
Description
Page 121
addFirst() or offerFirst( )
getFirst( ) or peekFirst( )
getLast( ) or peekLast( )
removeLast( ) or pollLast( )
Ex:
package com.sample;
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<String> myLinkedList = new LinkedList<String>();
myLinkedList.addFirst("A");
myLinkedList.add("B");
myLinkedList.add("C");
myLinkedList.add("D");
myLinkedList.add(2, "X");// This will add C at index 2
myLinkedList.addLast("Z");
System.out.println("Original List before deleting elements");
System.out.println(myLinkedList);
myLinkedList.remove();
myLinkedList.removeLast();
myLinkedList.remove("C");
System.out.println("Original List After deleting first and last
object");
System.out.println(myLinkedList);
System.out.println("First object in linked list: " +
myLinkedList.getFirst());
System.out.println("Last object in linked list: " +
myLinkedList.peekLast());
}
}
Page 122
Set:
A Set is a Collection that cannot contain duplicate elements. There are three main
implementations of Set interface: HashSet, TreeSet, and LinkedHashSet. HashSet, which stores
its elements in a hash table, is the best-performing implementation; however it makes no
guarantees concerning the order of iteration. TreeSet, which stores its elements in a red-black tree,
orders its elements based on their values; it is substantially slower than HashSet. LinkedHashSet,
which is implemented as a hash table with a linked list running through it, orders its elements
based on the order in which they were inserted into the set (insertion-order).
HashSet:
This class implements the Set interface, backed by a hash table (actually a HashMap instance). It
makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the
order will remain constant over time. This class permits the null element. This class is not
synchronized.
Notes:
1. HashSet doesnt maintain any order, the elements would be returned in any random order.
2. HashSet doesnt allow duplicates. If you try to add a duplicate element in HashSet, the old value
would be overwritten.
3. HashSet allows null values however if you insert more than one nulls it would still return only one
null value.
4. HashSet is non-synchronized. We need to synchronize explicitly as follows:
Set s = Collections.synchronizedSet(new HashSet(...));
5. The iterator returned by this class is fail-fast which means iterator would
throw ConcurrentModificationException if HashSet has been modified after creation of iterator, by
any means except iterators own remove method.
Methods:
1. boolean add(Element e): It adds the element e to the list.
2. void clear(): It removes all the elements from the list.
3. Object clone(): This method returns a shallow copy of the HashSet.
4. boolean contains(Object o): It checks whether the specified Object o is present in the list or not.
If the object has been found it returns true else false.
Core Java | JPA Solutions
Page 123
Output:
[null, Mango, Grapes, Apple, Orange, Fig]
As we can see there all the duplicate values are not present in the output including the duplicate null value.
TreeSet:
TreeSet is similar to HashSet except that it sorts the elements in the ascending order while HashSet
doesnt maintain any order. HashSet allow null, but TreeSet wont allow.
TreeSet can be synchronized as follows:
SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));
Ex:
Page 124
import java.util.TreeSet;
public class TreeSetExample {
public static void main(String args[]) {
// TreeSet of String Type
TreeSet<String> tset = new TreeSet<String>();
// Adding elements to TreeSet<String>
tset.add("ABC");
tset.add("String");
tset.add("Test");
tset.add("Pen");
tset.add("Ink");
tset.add("Jack");
// Displaying TreeSet
System.out.println(tset);
// TreeSet of Integer Type
TreeSet<Integer> tset2 = new TreeSet<Integer>();
// Adding elements to TreeSet<Integer>
tset2.add(88);
tset2.add(7);
tset2.add(101);
tset2.add(0);
tset2.add(3);
tset2.add(222);
System.out.println(tset2);
}
}
Output:
[ABC, Ink, Jack, Pen, String, Test]
[0, 3, 7, 88, 101, 222]
Map
A Map is an object that maps keys to values. A map cannot contain duplicate keys.
There are three main implementations of Map interfaces: HashMap, TreeMap, and LinkedHashMap. There
are 4 commonly used implementations of Map in Java SE - HashMap, TreeMap, Hashtable and
LinkedHashMap. If we use only one sentence to describe each implementation, it would be the following:
Page 125
Hashtable: Hash table is a data structure to store key value pairs for all situations. So it is like a table
with each entry has a key and a value corresponding to it. So, it is an efficient way of mapping and
accessing data.
HashMap: it makes no guarantees concerning the order of iteration
TreeMap: It stores its elements in a red-black tree, orders its elements based on their values; it is
substantially slower than HashMap.
LinkedHashMap: It orders its elements based on the order in which they were inserted into the set
(insertion-order).
Hashtable:
A Hashtable is an array of list. Each list is known as a bucket. The position of bucket is identified by
calling the hashcode() method. A Hashtable contains values based on the key. It implements the Map
interface and extends Dictionary class.
It is synchronized.
Constructor Summary:
Constructor and Description
Hashtable()
Constructs a new, empty hashtable with a default initial capacity (11) and load factor (0.75).
Hashtable(int initialCapacity)
Page 126
Constructs a new, empty hashtable with the specified initial capacity and default load factor (0.75).
Hashtable(int initialCapacity, float loadFactor)
Constructs a new, empty hashtable with the specified initial capacity and the specified load factor.
Hashtable(Map<? extends K,? extends V> t)
Constructs a new hashtable with the same mappings as the given Map.
Method Summary:
Modifier and Type
Void
Tests if some key maps into the specified value in this hashtable.
containsKey(Object key)
Boolean
Returns true if this hashtable maps one or more keys to this value.
elements()
Enumeration<V>
Compares the specified Object with this Map for equality, as per the definition
in the Map interface.
Page 127
get(Object key)
V
Returns the value to which the specified key is mapped, or null if this map
contains no mapping for the key.
hashCode()
Int
Returns the hash code value for this Map as per the definition in the Map
interface.
isEmpty()
Boolean
Copies all of the mappings from the specified map to this hashtable.
rehash()
protected void
Removes the key (and its corresponding value) from this hashtable.
size()
Int
Example:
import java.util.Enumeration;
import java.util.Hashtable;
public class HashtableDemo {
public static void main(String[] args) {
Page 129
Output:
Hashtable in Java :
----------------------Adding items to the Hashtable
Items in the Hashtable : {4=HTML, 3=Javascript, 2=.NET, 1=Java}
----------------------4: HTML
3: Javascript
2: .NET
1: Java
HashMap:
The HashMap class does not guarantee that the order will remain constant over time.
This implementation provides constant-time performance for the basic operations (get and put),
assuming the hash function disperses the elements properly among the buckets.
Page 130
The HashMap implementation is not synchronized. If multiple threads access this map concurrently,
and at least one of the threads modifies the map structurally, it must be synchronized externally.
Ex:
import java.util.Set;
import java.util.TreeSet;
import java.util.Iterator;
public class TreeSetExample {
public static void main(String[] args) {
Set<Integer> treeSet = new TreeSet();
// the treeset stores Integer objects into the TreeSet
for (int i = 0; i < 5; i++) {
treeSet.add(new Integer(i));
}
// Since its a Integer Object Set adding any other elements in the Same
// set will produce a
// ClassCastException exception at runtime.
// treeSet.add("a string");
System.out.print("The elements of the TreeSet are : ");
Iterator<Integer> i = treeSet.iterator();
while (i.hasNext()) {
System.out.print(i.next() + "\t");
}
}
}
Output:
The elements of the TreeSet are : 0
TreeMap:
A TreeMap is a Map implementation which provides total ordering on its elements. The elements are
ordered using their natural ordering, or by a Comparator typically provided at sorted map creation time.
A TreeMap is a Red-Black tree based NavigableMap implementation which insures log(n) time cost for
the basic operations (add, remove and contains).
A TreeMap is typically used when, in a map, we want to keep the elements sorted all times. The elements
are sorted by the keys in a map. The keys could also be custom objects defined with
comparable/comparator to decide the attribute responsible for sorting.
Core Java | JPA Solutions
Page 131
Important thing to note is that the ordering maintained by a TreeMap must be consistent with equals if this
sorted map is to correctly implement the Map interface.
Output:
{1=ABC, 2=PQR, 3=XXX, 4=YYY}
Page 132
Now lets see how to use TreeMap to get the inserted elements sorted on the basis of firstName.
public class JavaTreeMapExample {
public static void main(String[] args) {
// Natural ordering of User
Map<User, String> userMap = new TreeMap<>();
populateUserMap(userMap);
System.out.println(userMap.toString());
diplayMap(userMap);
}
private static void diplayMap(Map<User, String> userMap) {
Set<User> keySet = userMap.keySet();
for (User user : keySet) {
System.out.println(user.toString());
}
}
private static void
userMap.put(new
userMap.put(new
userMap.put(new
Page 133
Output:
{Ani Bha 12=My Name1, CalYYY 15=My Name2, SSS TER 1=My Name4, XYZ WER 22=My
Name3}
Ani Bha 12
Cal YYY 15
SSS TER 1
XYZ WER 22
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class JavaTreeMapExample {
public static void main(String[] args) {
// Ordering based on Comparator on salary
Map userSalaryMap = new TreeMap(new UserSalaryComparator());
populateUserMap(userSalaryMap);
System.out.println(" *** BASED ON SALARY ***");
diplayMap(userSalaryMap);
}
Page 134
populateUserMap(Map userMap) {
User("Ani", "Bha", 12), "My Name1");
User("Cal", "YYY", 15), "My Name2");
User("XYZ", "WER", 22), "My Name3");
User("SSS", "TER", 1), "My Name4");
Output:
***
SSS
Ani
Cal
XYZ
Page 135
Java IO Operations
Java.io package provides classes for system input and output through data streams, serialization and the
file system.
Standard Streams
All the programming languages provide support for standard I/O where user's program can take input
from a keyboard and then produce output on the computer screen. Java provides the following three
standard streams.
Standard Input: This is used to feed the data to user's program and usually a keyboard is used as
standard input stream and represented as System.in.
Standard Output: This is used to output the data produced by the user's program and usually a
computer screen is used to standard output stream and represented as System.out.
Standard Error: This is used to output the error data produced by the user's program and usually a
computer screen is used to standard error stream and represented as System.err.
1. System.out.println("simple message");
2. System.err.println("error message");
Example code to get input from console:
Page 136
A stream can be defined as a sequence of data. There are two kinds of Streams.
InputStream: The InputStream is used to read data from a source and it is an abstract class. Source
may be a file, an array, peripheral device or socket.
OutputStream: the OutputStream is used for writing data to a destination and it is an abstract class.
An output stream accepts output bytes and sends them to some sink.
Page 137
Method
Description
Method
public abstract int read()throws
IOException:
public int available()throws
IOException:
public void close()throws
IOException:
Description
reads the next byte of data from the input stream.It returns
-1 at the end of file.
returns an estimate of the number of bytes that can be read
from the current input stream.
is used to close the current input stream.
Page 138
These classes define several key methods. Two most important are:
1. read() : reads byte of data.
2. write() : Writes byte of data.
Java byte streams are used to perform input and output of 8-bit bytes. Though there are many classes
related to byte streams but the most frequently used classes are , FileInputStream and
FileOutputStream.
Description of the byte-oriented stream classes:
1. OutputStream and InputStream are abstract classes.
2. ByteArrayOutputStream objects are used to create a buffer in memory. All the data that you send to
the stream is placed in this buffer.
3. FileOutputStream objects are used for sending data to a file.
4. ObjectOutputStream objects are used for serializing (saving) objects to various streams (See the
serialization topic).
5. PipedOutputStream objects are used to implement the write portion of the "piping" concept.
Core Java | JPA Solutions
Page 139
6. FilterOutputStream objects are used to process stream output so that it can be buffered and written
as blocks of useful data instead of as one byte at a time.
7. All the FilterOutputStream contructors require another OutputStream object as an argument.
8. BufferedOutputStream is a FilterOutputStream class used to buffer data in a stream before writing it.
flush() is used to write the data to the stream.
9. DataOutputStream is a FilterOutputStream class used to write primitives (int, char, long, etc) to a
stream.
10. PrintStream is a FilterOutputStream class used for producing formatted output. (DataOutputStream
handles the storage of data, PrintStream handles the display of data.)
11. ByteArrayInputStream objects allow a buffer in memory to be used as an InputStream.
12. FileInputStream objects are used for reading data from a file.
13. ObjectInputStream objects are used for deserializing (reading) objects from various streams (See the
serialization topic).
14. PipedInputStream objects are used to implement the read portion of the "piping" concept (We will
defer the discussion of this stream to the multithreading topics).
15. SequenceInputStream are used to convert two or more InputStream objects into a single
InputStream object.
16. StringBufferInputStream objects are used to convert a String object into an InputSteam.
17. FilterInputStream objects are used to process stream input so that it can be read as blocks of useful
data instead of as one byte at a time.
18. All the FilterInputStream contructors require another InputStream object as an argument.
19. BufferedInputStream is a FilterInputStream class used to buffer data in a stream before reading it.
20. DataInputStream is a FilterInputStream class used to read primitives (int, char, long, etc) from a
stream.
21. LineNumberInputStream is a FilterInputStream class used to keep track of line numbers in the input
stream (getLineNumber(); setLineNumber(int)).
22. PushbackInputStream is a FilterInputStream class that has a one byte push-back buffer so you can
push back the last character read.
FileInputStream
This class is used for reading data from the files.
Core Java | JPA Solutions
Page 140
Following constructor takes a file object to create an input stream object to read the file. First we create
a file object using File() method as follows:
File f = new File("hello.txt");
InputStream f = new FileInputStream(f);
Description
This method closes the file output stream. Releases any system
resources associated with the file. Throws an IOException.
This method cleans up the connection to the file. Ensures that
the close method of this file output stream is called when there
are no more references to this stream. Throws an IOException.
This method reads the specified byte of data from the
InputStream. Returns an int. Returns the next byte of data and 1 will be returned if it's end of file
This method reads r.length bytes from the input stream into an
array. Returns the total number of bytes read. If end of file -1
will be returned.
Gives the number of bytes that can be read from this file input
stream. Returns an int.
FileOutputStream
FileOutputStream is used to create a file and write data into it. The stream would create a file, if it
doesn't already exist, before opening it for output.
Here are two constructors which can be used to create a FileOutputStream object.
Following constructor takes a file name as a string to create an input stream object to write the file:
OutputStream f = new FileOutputStream("C:/java/hello");
Following constructor takes a file object to create an output stream object to write the file. First, we
create a file object using File() method as follows:
File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);
Description
Page 141
Sample program:
package com.sample.file;
import
import
import
import
import
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.IOException;
java.io.InputStream;
java.io.OutputStream;
");
}
}
Page 142
These two abstract classes have several concrete classes that handle unicode character.
Page 143
Stream class
BufferedReader
BufferedWriter
FileReader
FileWriter
InputStreamReader
OutputStreamReader
PrintWriter
Reader
Writer
Description
Handles buffered input stream.
Handles buffered output stream.
Input stream that reads from file.
Output stream that writes to file.
Input stream that translate byte to character
Output stream that translate character to byte.
Output Stream that contain print() and println() method.
Abstract class that define character stream input
Abstract class that define character stream output
Page 144
Reading Characters:
read() method is used with BufferedReader object to read characters. As this function returns integer
type value has we need to use typecasting to convert it into char type.
int read() throws IOException
Page 145
java.io.BufferedReader;
java.io.File;
java.io.FileReader;
java.io.IOException;
Page 146
Serialization
The concept of transmitting objects from one place to another place is called Serialization.
The process of converting an object to network understandable data is called Serialzation.
The concept of persisting the state of an object (in a file, disk, DB) is called Serialization.
Serialization is a process in which current state of Object will be saved in stream of bytes. As byte stream
create is platform neutral hence once objects created in one system can be deserialized in other
platform.
In Java, if any object needs to be persist, we need to implements java.io.Serializable interface.
Serializable is a marker interface, which doesnot have any abstract methods to implement by its
implementor classes.
Marshalling: The process of converting object to network understandable data is called Marshalling.
Unmarshalling: The process of converting network understandable data to object is called
Unmarshalling.
Classes ObjectInputStream and ObjectOutputStream are high-level streams that contain the methods
for serializing and deserializing an object.
The ObjectOutputStream class contains many write methods for writing various data types, but one
method in particular stands out:
public final void writeObject(Object x) throws IOException
The above method serializes an Object and sends it to the output stream. Similarly, the
ObjectInputStream class contains the following method for deserializing an object:
public final Object readObject() throws IOException,
ClassNotFoundException
This method retrieves the next Object out of the stream and deserializes it. The return value is Object, so
you will need to cast it to its appropriate data type.
Need of Serialization:
Serialization is usually used when the need arises to send your data over network or stored in files. By
data I mean objects and not text. Now the problem is your Network infrastructure and your Hard disk are
hardware components that understand bits and bytes but not Java objects. Serialization is the translation
Core Java | JPA Solutions
Page 147
of your Java objects values/states to bytes to send it over network or save it.On other hand,
Deserialization is conversion of byte code to corresponding java objects.
Concept of serialVersionUID :
SerialVersionUID is used to ensure that same object(That was used during Serialization) is loaded during
Deserialization.serialVersionUID is used for version control of object.
Employee.java:
import java.io.Serializable;
public class Employee implements Serializable {
/**
*
Page 148
*/
private static final long serialVersionUID = 1L;
int employeeId;
String employeeName;
String department;
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}
Steps to deserialize:
Page 149
DeserializeDemo.java:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializeDemo {
public static void main(String[] args) {
Employee emp = null;
try {
FileInputStream fileIn = new FileInputStream("employee.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
emp = (Employee) in.readObject();
in.close();
fileIn.close();
} catch (IOException ioe) {
ioe.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Emp id: " + emp.getEmployeeId());
System.out.println("Name: " + emp.getEmployeeName());
System.out.println("Department: " + emp.getDepartment());
}
}
Notes:
Page 150
Threads
A Thread is a light weight process that executes some task simultaneously with other part of the
program. Threads are two types.
1. User threads
2. System Threads (Daemon Threads)
Every java program/application has at least one thread in it. Per example main() is a user thread, that will
be created as and when a java program starts execution. There will be many other threads running in
background like memory management, system management, signal processing etc. All these threads are
System threads or Daemon threads.
Multithreading refers to two or more threads executing concurrently in a single program. A computer
single core processor can execute only one thread at a time and time slicing is the OS feature to share
processor time between different processes and threads.
New: A thread begins its life cycle in the new state. It remains in this state until the program starts the
thread. It is also referred to as a born thread.
Runnable: After a newly born thread is started, the thread becomes runnable. A thread in this state is
considered to be executing its task.
Page 151
Waiting: Sometimes, a thread transitions to the waiting state while the thread waits for another thread to
perform a task.A thread transitions back to the runnable state only when another thread signals the waiting
thread to continue executing.
Timed waiting: A runnable thread can enter the timed waiting state for a specified interval of time. A
thread in this state transitions back to the runnable state when that time interval expires or when the event it
is waiting for occurs.
Terminated (Dead): A runnable thread enters the terminated state when it completes its task or otherwise
terminates.
Thread Priority
Thread priority helps operating system to determine in scheduling the Threads. Every thread has its own
priority. Thread priorities are in the range between 1 10. Thread has three constants.
MAX_PRIORITY = 10
MIN_PRIORITY = 1
NORM_PRIORITY = 5
Operating system will schedule the threads based on their priority. Heigher priority has more important
and lower priority has less importance. NORM_PRIORITY is the default priority of a thread. However, if
there are two threads with the same priority, cannot guarantee the order in which threads execute and
very much platform dependent.
Thread creation
Thread can be created in two ways.
1. By implementing the Runnable interface.
2. By extending the Thread class.
Creation of Thread by implementing Runnable interface
Step #1: Runnable interface has an abstract method called run(). This method provides entry point for
thread and we need to provide the completeness for this method. In other way, we need to put business
logic in run() method.
Syntax of run():
public void run( )
Step #2: We need to instantiate the Thread class object by using any one the following constructors.
Constructor with Runnable interface:
Thread(Runnable threadObj);
Core Java | JPA Solutions
Page 152
Here, threadObj is an instance of a class that implements the Runnable interface and threadName is the
name given to the new thread.
Step #3: Once Thread object is created, we need to make a call to start() method to start the execution of
run() method.
void start( );
Description
Starts the thread in a separate path of execution, then invokes the run()
method on this Thread object.
If this Thread object was instantiated using a separate Runnable target, the
run() method is invoked on that Runnable object.
Changes the name of the Thread object. There is also a getName() method
for retrieving the name.
Sets the priority of this Thread object. The possible values are between 1
and 10.
The current thread invokes this method on a second thread, causing the
current thread to block until the second thread terminates or the specified
number of milliseconds passes.
Returns true if the thread is alive, which is any time after the thread has
been started but before it runs to completion.
Page 153
Methods
Description
Returns true if the current thread holds the lock on the given
Object.
Prints the stack trace for the currently running thread, which is
useful when debugging a multithreaded application.
RunnableThread.java:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class RunnableThread implements Runnable {
private String threadName;
Thread thread;
RunnableThread(String threadName) {
this.threadName = threadName;
}
@Override
public void run() {
System.out.println("Running thread name : " + threadName);
try (BufferedReader br = new BufferedReader(
new FileReader("D:\\ JPA\\FILES\\thread_file.txt"));) {
String str;
Core Java | JPA Solutions
Page 154
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ExtendingThread extends Thread {
Core Java | JPA Solutions
Page 155
Synchronization:
Core Java | JPA Solutions
Page 156
There are many situations in which multiple threads must share access to common objects.
The keyword synchronize prevents multiple threads access the same object/resource simultaneously.
Thread communication:
Threads can be communicate with each other by using wait(), notify() & notifyAll(). These are the final
methods implemented in Object class. All three methods can be called only from within
a synchronized context.
ChatApplication.java:
package com.sample.threads;
public class ChatApplication {
boolean flag = false;
public synchronized void question(String que) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(que);
flag = true;
notify();
}
public synchronized void answer(String ans) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(ans);
flag = false;
notify();
}
}
Page 157
CustomerThread.java:
CustomerCareThread.java:
Page 158
ThreadCommunicationDemo.java:
public class ThreadCommunicationDemo {
public static void main(String[] args) {
ChatApplication ca = new ChatApplication();
new CustomerThread(ca);
new CustomerCareThread(ca);
}
}
Output:
Customer : Hi
CustomerCare: How may I help you?
Customer : I have a problem in my system
CustomerCare: Sure, please give us 24 hours to solve the problem
Customer : Thank You...
CustomerCare: Welcome
Page 159
Reflection
Java Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime, without
knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new
objects, invoke methods and get/set field values using reflection.
In Java, it is possible to inspect fields, classes, methods, annotations, interfaces, etc. at runtime. Its not
require to know how classes or methods are called, neither the parameters that are needed, all of that
can be retrieved at runtime using reflection. It is also possible to instantiate new classes, to create new
instances and to execute their methods, all of it using reflection.
Reflection API is the mechanism used to fetch information about a class. This mechanism is built into the
class named Class. The special class Class is the universal type for the meta information that describes
objects within the Java system. Class loaders in the Java system return objects of type Class.
Class: The Class contains all the reflection related methods that can be applied to classes and objects
like the ones that allow a programmer to retrieve the class name, to retrieve the public methods of a
class, etc.
The most important methods of Class are:
forName(): Loads class of a given name, using the current class loader.
Syntax:
public static Class<?> forName(String className)
throws ClassNotFoundException
getName(): Returns the name of the class as a String object, which was useful for identifying object
references by their class name.
newInstance(): Invokes the no-args constructor on the class (if it exists) and return you an object
instance of that class of object.
Syntax:
public T newInstance()
throws InstantiationException,
IllegalAccessException
getConstructor(): Returns a Constructor object that reflects the specified public constructor of the
class represented by this Class object.
Syntax:
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
Page 160
getConstructors(): Returns an array containing Constructor objects reflecting all the public
constructors of the class represented by this Class object.
Syntax:
public Constructor<?>[] getConstructors()throws SecurityException
getMethod(): Returns a Method object that reflects the specified public member method of the class
or interface represented by this Class object.
Syntax:
public Method getMethod(String name,Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
getMethods(): Returns an array containing Method objects reflecting all the public methods of the
class or interface represented by this Class object, including those declared by the class or interface
and those inherited from superclasses and superinterfaces.
Syntax:
public Method[] getMethods() throws SecurityException
getDeclaredMethods(): Returns an array containing Method objects reflecting all the declared
methods of the class or interface represented by this Class object, including public, protected, default
(package) access, and private methods, but excluding inherited methods.
Syntax:
public Method[] getDeclaredMethods() throws SecurityException
Page 161
getField(): Returns a Field object that reflects the specified public member field of the class or
interface represented by this Class object.
Syntax:
public Field getField(String name)
throws NoSuchFieldException, SecurityException
getFields(): Returns an array containing Field objects reflecting all the accessible public fields of the
class or interface represented by this Class object.
Syntax:
public Field[] getFields() throws SecurityException
getDeclaredFields(): Returns an array of Field objects reflecting all the fields declared by the class or
interface represented by this Class object.
Syntax:
public Field[] getDeclaredFields()throws SecurityException
getSuperclass(): Returns the Class representing the superclass of the entity (class, interface, primitive
type or void) represented by this Class.
Syntax:
public Class<? super T> getSuperclass()
getInterfaces(): Determines the interfaces implemented by the class or interface represented by this
object.
Syntax:
public Class<?>[] getInterfaces()
Page 162
Employee.java:
package com.sample.reflection;
public class Employee {
int id;
String name;
String email;
private Employee(int id, String name) {
this.id = id;
this.name = name;
}
public Employee(int id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return new StringBuilder("Employee [id=").append(id)
.append(", name=").append(name)
.append(", email=").append(email)
.append("]").toString();
}
}
RefelectionDemo.java:
package com.sample.reflection;
import java.lang.reflect.Constructor;
Core Java | JPA Solutions
Page 163
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectionDemo {
public static void main(String[] args) {
try {
// Possibility to throw ClassNotFoundException
Class<?> clazz = Class.forName("com.sample.reflection.Employee");
try {
// Way to get all constructors of a class (public, protected, default &
private)
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
System.out.println("=========== Constructors demonstration started
=========");
for (Constructor<?> constructor : constructors) {
System.out.println("\nConstructor Name : " +
constructor.getName());
// Each Parameter is a class in java, so parameters can be
received in Class array
Class<?>[] params = constructor.getParameterTypes();
for (Class<?> param : params) {
System.out.println("Paramter : " + param.getName());
}
}
System.out.println("=========== Constructors demonstration ended
=========");
System.out.println("\nCalling a private constructor through reflection");
// Possibility to throw NoSuchMethodException & SecurityException
Constructor<?> constructor = clazz.getDeclaredConstructor(int.class,
String.class);
// Way to invoke private constructor
constructor.setAccessible(true);
Employee employee = (Employee) constructor.newInstance(10,
"Harish");
System.out.println("Employee : " + employee);
// Invoke non-static method of a class
System.out.println("\nCalling a non-static method and updating the
existing object");
Method method = clazz.getMethod("setEmail", String.class);
method.invoke(employee, "rahul@gmail.com");
System.out.println("Employee After invoked setEmail() : " + employee);
} catch (InstantiationException | IllegalAccessException |
IllegalArgumentException
| InvocationTargetException e) {
Core Java | JPA Solutions
Page 164
e.printStackTrace();
}
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
}
Output:
=========== Constructors demonstration started =========
Constructor Name : com.sample.reflection.Employee
Paramter : int
Paramter : java.lang.String
Constructor Name : com.sample.reflection.Employee
Paramter : int
Paramter : java.lang.String
Paramter : java.lang.String
=========== Constructors demonstration ended =========
Calling a private constructor through reflection
Employee : Employee [id=10, name=Harish, email=null]
Calling a non-static method and updating the existing object
Employee After invoked setEmail() : Employee [id=10, name=Harish,
email=rahul@gmail.com]
Page 165
JDBC Architecture
Page 166
b. Click on Add External JARs.. Browse and select JDBC driver jar Click Open
Page 167
Java application calls the JDBC library. JDBC loads a driver which talks to the database In general, to
process any SQL statement with JDBC, you follow these steps:
1.
2.
3.
4.
5.
Establish a connection.
Create a statement.
Execute the query.
Process the ResultSet object.
Close the connection
Establishing a Connection
In this step of the jdbc connection process, we load the driver class by calling Class.forName() with the
Driver class name as an argument. Once loaded, the Driver class creates an instance of itself.
String driverName = "oracle.jdbc.driver.OracleDriver"; // for Oracle
// String driverName = com.mysql.jdbc.Driver; //for MySql
try {
// Load the JDBC driver
Class.forName(driverName);
} catch (ClassNotFoundException e) {
// Could not find the database driver
System.out.println("ClassNotFoundException : " + e.getMessage());
}
Page 168
The JDBC DriverManager class defines objects which can connect Java applications to a JDBC driver.
DriverManager is considered the backbone of JDBC architecture. DriverManager class manages the JDBC
drivers that are installed on the system. Its getConnection() method is used to establish a connection to a
database. It uses a username, password, and a jdbc url to establish a connection to the database and
returns a connection object. A jdbc Connection represents a session/connection with a specific database.
Within the context of a Connection, SQL, PL/SQL statements are executed and results are returned. An
application can have one or more connections with a single database, or it can have many connections
with different databases.
Example for JDBC connection:
String serverName = "linux.grace.umd.edu";
String portNumber = "1521";
String instanceId = "XE";
String url = "jdbc:oracle:thin:@" + serverName + ":" +
portNumber + ":" + instanceId; // for Oracle
//uri =jdbc:mysql://server ip or address:port/database name; //for Mysql
try {
// Create a connection to the database
connection = DriverManager.getConnection(url, username, password);
catch (SQLException e) {
// Could not connect to the database
System.out.println(e.getMessage());
}
Page 169
Page 170
To execute a query, call an execute method from Statement such as the following:
execute: Returns true if the first object that the query returns is a ResultSet object. Use this method if
the query could return one or moreResultSet objects. Retrieve the ResultSet objects returned from the
query by repeatedly calling Statement.getResutSet.
executeUpdate: Returns an integer representing the number of rows affected by the SQL statement.
Use this method if you are using INSERT,DELETE, or UPDATE SQL statements.
Example of executeQuery:
String country = "D";
Statement stmt = null;
String query = " SELECT * FROM CITY WHERE country='" + country + "'";
try {
stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String name = rs.getString(1); // or rs.getString("NAME");
String coun = rs.getString(2);
String province = rs.getString(3);
int population = rs.getInt(4);
}
stmt.close();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
Page 171
Page 172
Before executing the above program, its mandatory to create table and its sequence as follows:
CREATE TABLE EMPLOYEE
(
Page 173