20ES3102B Java Programming SRP
20ES3102B Java Programming SRP
1. Course Handout 1
2. Micro-Level Syllabus 11
Course Description:
Java Programming is a programme core course offered for second year B. Tech – Computer Science and
Engineering students. This course is aimed at students who wish to learn how to develop applications in
Java. This course will also provide an overview of Object-Oriented Programming concepts using Java and
builds data-driven Java's unique architecture that enables programmers to develop a single application that
can run across multiple platforms seamlessly and reliably. Students gain extensive experience with Java
and its object-oriented features. Students learn to create robust console applications.
Upon successful completion of the course, the student will be able to:
CO No. Course Outcomes (CO) PO/PSO BTL
PO1, PO2, 2
CO 1 Understand the basic concepts of object-oriented programming
PSO1, PSO2
PO1, PO2, PO3, 3
CO 2 Apply multiple inheritance through interfaces for a given application
PSO1, PSO2
Apply exceptions, thread capabilities and handling files on a given PO1, PO2, PO3, 3
CO 3 application PSO1, PSO2
Apply functional programming and collections framework for a given PO2, PO3, PO5, 3
CO 4 PSO1, PSO2
application
Contribution of Course Outcomes towards Achievement of Program Outcomes
(1 – Low, 2 - Medium, 3 – High)
PO1 PO2 PO3 PO4 PO5 PO6 PO7 PO8 PO9 PO10 PO11 PO12 PSO1 PSO2
CO1 2 3 1 1
CO2 2 2 3 2 2
CO3 2 2 3 2 2
CO4 2 3 2 2 2
1
ACADEMIC YEAR: 2023-2024
PO2: Problem analysis: Identify, formulate, review research literature, and analyze complex
engineering problems reaching substantiated conclusions using first principles of
mathematics, natural sciences, and engineering sciences.
PO3: Design/development of solutions: Design solutions for complex engineering problems and
design system components or processes that meet the specified needs with appropriate
consideration for the public health and safety, and the cultural, societal, and environmental
considerations.
PO4: Conduct investigations of complex problems: Use research-based knowledge and research
methods including design of experiments, analysis and interpretation of data, and synthesis
of the information to provide valid conclusions.
PO5: Modern tool usage: Create, select, and apply appropriate techniques, resources, and modern
engineering and IT tools including prediction and modeling to complex engineering activities
with an understanding of the limitations.
PO6: The engineer and society: Apply reasoning informed by the contextual knowledge to assess
societal, health, safety, legal and cultural issues, and the consequent responsibilities relevant
to the professional engineering practice.
PO7: Environment and sustainability: Understand the impact of the professional engineering
solutions in societal and environmental contexts, and demonstrate the knowledge of, and
need for sustainable development.
PO8: Ethics: Apply ethical principles and commit to professional ethics and responsibilities and
norms of the engineering practice.
PO9: Individual and teamwork: Function effectively as an individual, and as a member or leader
in diverse teams, and in multi-disciplinary settings.
PO12: Lifelong learning: Recognize the need for and have the preparation and ability to engage in
independent and life-long learning in the broadest context of technological change.
2
ACADEMIC YEAR: 2023-2024
COURSE CONTENT:
UNIT I:
Introduction, The History and Evolution of Java: Java history and evolution, Java features, Java’s
Magic: Byte Code, How Java differs from C and C++.
An Overview of Java: Object Oriented Programming: Two paradigms, Principles of OOP, A First simple
Program and Control statements.
Data Types, Variables and Arrays: Java keywords, Primitive types, Integers, Floating-Point Types,
Characters, Booleans, Variables, Operators, Type Conversion, Casting and Arrays.
Introducing Classes and Objects: Class fundamentals, declaring objects, assigning object reference
variables, introducing methods, constructors, this keyword, Garbage collection, overloading methods, using
objects as parameters, returning objects, static and final keywords, nested and inner classes.
UNIT II:
String Handling: The String Constructors, String Buffer Class, String Tokenizer class.
Inheritance: Inheritance basics, using super, multilevel hierarchy, method overriding, dynamic method
dispatch, using abstract classes, final with inheritance.
Packages & Interfaces: Defining a package, finding package and CLASSPATH. Access protection,
importing packages, defining an interface, implementing interfaces, nested interfaces, applying interfaces,
variables in interfaces.
UNIT III:
Exception handling: Exception handling fundamentals, exception types, uncaught exceptions, using try
and catch, multiple catch clauses, throw, throws, finally, creating your own exception subclasses.
I/O streams: Byte Streams- InputStream, OutputStream, FileInputStream, FileOutputStream, Character
Streams- Reader, Writer, FileReader, FileWriter.
Multithread Programming: The Java Thread Model, creating a thread: Implementing Runnable,
Extending Thread, creating multiple threads, Thread Priorities, Synchronization: Using Synchronized
methods, The synchronized Statement.
UNIT IV:
Pragmatic Functional Programming using Lambdas: Introduction to Functional programming,
Functional Programming concepts and terminology, Functional Interfaces, Working with Lambda
Expressions and Method References.
Collections Framework: Collections overview, Collection interfaces: Collection, List, and Set. Collection
Classes: ArrayList, LinkedList, HashSet. Map Classes: HashMap, TreeMap.
The Stream API: Stream basics, Reduction operations, Using parallel streams, Mapping, Collecting,
Iterators and Streams.
TEXTBOOKS:
[1] Herbert Schildt. (2019), “Java the Complete Reference”, Eleventh Edition, Oracle
3
ACADEMIC YEAR: 2023-2024
REFERENCE BOOKS:
[1] Herbert Schildt, Dale Skrien. (2017), ”Java Fundamentals A Comprehension Introduction”, Special
Indian Edition, McGraw-Hill Education India Pvt. Ltd.
[2] E Balaguruswamy. (2020), ”Programming with Java”, 4th Edition, Mc Graw Hill.
[3] Paul J. Dietel and Dr.Harvey M. Deitel. (2018), ”Java How to Program”, Eleventh Edition, Deitel
Associates, Inc.
[4] Timothy Budd. (2013), “Understanding Object Oriented Programming with Java”, Updated edition,
Pearson Education.
[5] Kathy Sierra Bert Bates, ”Head First Java”, 2nd Edition, Oreilly.
4
ACADEMIC YEAR: 2023-2024
3 1 1 Features, Java's Magic: Byte Code T1 [1] [9-13] PPT CT1, S1, HA, SE
4 1 1 How Java Differs from C and C++, OOP, A First Simple Program T1 [2] [17-24] PPT CT1, S1, HA, SE
T1 [2] [33-34]
5 1 1 Java Keywords, Primitive Types, Variables PPT CT1, S1, HA, SE
T1 [3] [35-47]
6 1 1 Type Conversion and Casting T1 [3] [48-50] PPT CT1, S1, HA, SE
T1[3] [51-58]
7 1 1 Arrays, Class Fundamentals PPT CT1, S1, HA, SE
T1[6] [109-113]
10 1 2 Garbage Collection, Overloading Methods T1 [7] [129-132] PPT CT1, S1, HA, SE
12 1 2 Returning Objects, Recursion, Static and Final Keywords T1 [7] [138-147] PPT CT1, S1, HA, SE
13 1 2 Nested and Inner Classes T1 [7] [149-152] PPT Quiz CT1, S1, HA, SE
5
ACADEMIC YEAR: 2023-2024
T1 [16] [414-416]
14 2 2 The String Constructors, String Buffer Class PPT CT1, S1, HA, SE
T1 [16] [432-439]
T1 [19] [579-580]
15 2 2 String Tokenizer class, Inheritance Basics PPT S1, HA, SE
T1 [8] 161-166]
16 2 2 Using Super, Creating a Multilevel Hierarchy T1 [8] [167-173] PPT S1, HA, SE
17 2 3 Method Overriding, Dynamic Method Dispatch T1 [8] 175-180] PPT S1, HA, SE
18 2 3 Using Abstract Classes, Using final with Inheritance T1 [8] [181-185] PPT S1, HA, SE
19 2 3 Packages, Access Protection, Importing Packages T1 [9] [187-196] PPT S1, HA, SE
23 3 2 Exception-Handling Fundamentals, Exception Types T1 [10] [213-215] PPT CT2, S2, HA, SE
24 3 2 Uncaught Exceptions, Using try and catch T1 [10] [215-218] PPT CT2, S2, HA, SE
25 3 2 Multiple catch Clauses, throw, throws, finally T1 [10] [218-226] PPT CT2, S2, HA, SE
26 3 2 Creating Your Own Exception Subclasses T1 [10] [227-230] PPT CT2, S2, HA, SE
6
ACADEMIC YEAR: 2023-2024
30 3 3 Character Stream, Reader, Writer, FileReader, FileWriter T1 [20] [670-674] PPT CT2, S2, HA, SE
31 3 3 BufferedReader and Writer, StringReader and Writer, PrintWriter T1 [20] [676-679] PPT Quiz CT2, S2, HA, SE
32 3 3 The Java Thread Model, Creating a Thread T1 [11] [234-242] PPT CT2, S2, HA, SE
36 4 2 Introduction, Functional Programming concepts and terminology T1 [15] [381-383] PPT S2, HA, SE
40 4 3 Collection Overview and Interfaces: List, Set and Map T1 [18] [501-504] PPT S2, HA, SE
44 4 3 Stream basics, Reduction operations, Using parallel streams T1 [29] [965-977] PPT S2, HA, SE
7
ACADEMIC YEAR: 2023-2024
PRACTICAL COMPONENT:
List of the experiments supposed to be finished in Lab Sessions:
Lab Session
Title of Lab Session
No.
1 Apply fundamentals of Java Data types, Variables, Operators, and Control Statements
2 Apply the concepts of Classes and Objects
3 Apply the concepts of Arrays
4 Apply the concepts of String and String Tokenizer classes
5 Apply the concepts of Inheritance and types of Inheritance
6 Apply the concepts of Method Overloading and Method Overriding
7 Apply the concepts of Packages
8 Apply the concepts of Interfaces
9 Apply the concepts of Exception Handling
10 Develop a Java application to copy content from one file to another file using I/O Streams
11 Apply the concepts of Threads and Multithread
12 Apply the concepts of Lambda Expressions, Collections Framework and Stream API
COURSE TIMETABLE:
Course Conduct
REMEDIAL CLASSES:
Supplement course handout, which may perhaps include special lectures and discussions that would be
planned, and schedule notified accordingly.
SELF-LEARNING:
Assignments to promote self-learning, survey of contents from multiple sources.
S.No Topics CO ALM References/MOOCS
1. Varargs: Variable- 1 - T1 [7] [155-159]
Length Arguments
2. Default Interface 2 - T1 [9] [207-211]
Methods
3. Enumerations 3 - T1 [12] [263-272]
4. Constructor References 4 - T1 [15] [404-408]
8
ACADEMIC YEAR: 2023-2024
9
ACADEMIC YEAR: 2023-2024
PLAGIARISM POLICY
Use of unfair means in any of the evaluation components will be dealt with strictly, and the case will be
reported to the examination committee.
Each instructor will specify his / her chamber consultation hours during which the student can contact
him / her in his / her chamber for consultation.
Chamber
Chamber Signature
Chamber Consultation
S.No. Name of Faculty Consultation of Course
Consultation Day (s) Timings for
Room No: faculty
each day
1 Mr. U. Prabu Working days 9.00 am to 5.00 pm C143
GENERAL INSTRUCTIONS
• Students should come prepared for classes and carry the textbook(s) or material(s) as prescribed by the
Course Faculty to the class.
• Students should submit the given home assignment before the due date.
NOTICES
• All notices will be communicated through the institution email.
• All notices concerning the course will be displayed on the respective Notice Boards.
Approved by:
HEAD OF DEPARTMENT
(Sign with Office Seal)
10
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE::VIJAYAWADA
(AUTONOMOUS)
DEPARTMENT OF CSE
MICRO LEVEL SYLLABUS
11
FileWriter
The Java Thread Model, Creating a thread 11 237-250
Implementing Runnable, Extending Thread, creating
multiple threads, Thread Priorities
Synchronization, Using Synchronized methods, The 11 251-253
synchronized Statement
Unit Pragmatic Functional Programming using [T1] 15 379-387
IV Lambdas: Introduction to Functional Programming,
Functional Programming concepts and terminology
Functional Interfaces, Working with Lambda 15 387-395
Expressions, Method References
Collections Framework ,Collections overview 19 527-535
Collection interfaces, Collection , List ,Set,
Collection Classes,ArrayList, LinkedList, HashSet 19 540-546
Map Classees,HashMap, TreeMap
The Stream API: Stream basics, Reduction 29 955-976
operations, Using parallel streams, Mapping,
Collecting, Iterators and Streams
Text Books:
[1] Herbert Schildt, “Java The Complete Reference”, Eleventh Edition, Oracle Press, 2019.
Reference Books:
[1] Herbert Schildt, Dale Skrien, “Java Fundamentals A Comprehension Introduction”,
Special Indian Edition, McGraw-Hill Education India Pvt. Ltd, 2017.
[2] E Balaguruswamy, "Programming with Java", 4th Edition, Mc Graw Hill , 2020.
[3] Paul J. Dietel and Dr.Harvey M. Deitel, “Java How to Program”, Eleventh Edition, Deitel
& Associates, Inc.l , 2018.
[4] Timothy Budd, “Understanding Object Oriented Programming with Java “, Updated
edition,Pearson Education, 2013.
[5] Kathy Sierra & Bert Bates, "Head First Java", 2nd Edition, Oreilly.
E-resources and other digital material
[1] Prof. Debasis Samanta. (14th,July, 2021), Department of Computer Science &
Engineering, I.I.T.,Kharagpur, Swayam, NPTEL.
https://onlinecourses.nptel.ac.in/noc21_cs03/preview.
[2] Evan Jones, Adam Marcus,Eugene Wu "Introduction to Programming in Java", MIT
OpenCourseWare, Massachusetts Institute of Technology, May 28, 2021.
https://ocw.mit.edu › courses
[3] Prof. Owen Astrachan, "Object Oriented Programming in Java", Duke University, 21st
May 2021. coursera.org
https://www.coursera.org/specializations/object-oriented-programming
12
MODEL QUESTION PAPER
VELAGAPUDI RAMAKRISHNA SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
II/IV B. Tech (SEMESTER III)
JAVA PROGRAMMING
20ES3102B
Time: 3 Hours Max. Marks 70
PART-A
PART-B
UNIT-I
Marks BL CO PI
CODE
2. a) Discuss in detail the basic principles of Object Oriented 7 K2 1 2.7.1
Programming
b) Explain the features of Java programming in detail? 8 K2 1 1.7.1
[OR]
3. a) Write a program to perform the following operations using 8 K3 1 1.7.1
classes, objects where essential.
i. Get as input of marks of 5 students in 5 subjects
ii. Calculate the total and average
iii. Print the formatted result on the screen
b) Explain the concept of method overloading with an example. 7 K2 1 2.5.2
13
UNIT-II
Marks BL CO PI CODE
4. a) Describe Dynamic dispatch method in java with suitable example 7 K2 2 2.7.1
UNIT-III
Marks BL CO PI CODE
6. a) Write briefly about the following terms 8 K2 3 2.7.1
i) Multiple catch clauses ii) Thread synchronization
b) Define multithreading? What are the methods available in Java 7 K3 3 2.7.1
for inter-thread communication? Discuss with an example.
[OR]
7. a) What is meant by a stream? Compare different types of stream 7 K2 3 2.6.4
classes and illustrate with a suitable example.
b) Illustrate the concept of creating your own exception sub class with 8 K3 3 2.7.1
an example.
UNIT-IV
Marks BL CO PI CODE
8. a) What is the lambda expression in Java and How does a lambda 8 K2 4 2.7.1
expression relate to a functional interface? Explain with an
example
b) Define default method. Why is it required justify with a suitable 7 K3 4 3.6.2
example
[OR]
9. a) Define a set. Why we use Set interface? Describe the main classes 7 K2 4 2.6.4
implementing Set interface with an relevant example.
14
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
10. Anything declared as ________ (access modifier) can be accessed from anywhere.
Down
16
Solving the Puzzle – Answers:
17
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
1. A Java exception is __________that describes an exceptional (that is, error) condition that has
occurred in a piece of code
a) condition b) method c) an object d) statement
Ans:
3. Any exception that is not caught by your program will ultimately be processed by the default
handler.
a) True b) False
6. Java’s stream based I/O is built upon four abstract classes: InputStream, OutputStream, Reader,
and Writer.
a) True b) False
8. The FileInputStream class creates an InputStream that you can use to read _______
from a file.
a) streams b) bytes c) characters d) None of the above
6. The TreeMap class extends AbstractMap and implements the ________ interface.
Down
19
Solving the Puzzle – Answers:
20
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
21
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
Unit 3
1. Byte Streams
2. Character Streams
22
20ES3102B – JAVA PROGRAMMING
20ES3102B – JAVA PROGRAMMING UNIT 1:
Introduction, History, Introduction, The History and Evolution of Java: Java history and evolution,
Evolution Java features, Java’s Magic: Byte Code, How java differs from C and C++.
UNIT 1 An Overview of Java: Object Oriented Programming: Two paradigms,
Overview Principles of OOP, A First simple Program and Control statements.
Lecture By,
Data Types, Variables and Arrays: Java keywords, Primitive types, Integers,
Prabu.U
Assistant Professor,
CO 1 Datatypes, Variables, Floating-Point Types, Characters, Booleans, Variables, Operators, Type
Conversion, Casting and Arrays.
Department of Computer Science and Engineering. Arrays
Introducing Classes and objects: Class fundamentals, declaring objects,
Classes and Objects assigning object reference variables, introducing methods, constructors, this
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING, keyword, Garbage collection, overloading methods, using objects as
parameters, returning objects, static and final keywords, nested and inner
V R Siddhartha Engineering College. classes.
1 2 3
Evolution of Java From C, Java derives its syntax. Many of Java’s object-oriented
3. Java’s Magic: Byte Code features were influenced by C++.
4 5 6
What is Java? Java is also known for being more strict than C++, meaning variables
and functions must be explicitly defined.
1. Java History and Evolution
Java is a high-level programming language developed by Sun Java was conceived by James Gosling, Patrick Naughton, Chris Warth,
This means Java source code may produce errors or "exceptions" more
Microsystems. Ed Frank, and Mike Sheridan at Sun Microsystems, Inc. in 1991.
easily than other languages, but it also limits other types of errors that
may be caused by undefined variables or unassigned types.
It was originally designed for developing programs for set-top It took 18 months to develop the first working version. This language
boxes and handheld devices, but later became a popular choice for Unlike Windows executables (.EXE files) or Macintosh applications was initially called “Oak,” but was renamed “Java” in 1995.
creating web applications. (.APP files), Java programs are not run directly by the operating system.
Between the initial implementation of Oak in the fall of 1992 and the
The Java syntax is similar to C++, but is strictly an object-oriented Instead, Java programs are interpreted by the Java Virtual Machine, or public announcement of Java in the spring of 1995, many more people
programming language. JVM, which runs on multiple platforms. contributed to the design and evolution of the language.
For example, most Java programs contain classes, which are used This means all Java programs are multiplatform and can run on
different platforms, including Macintosh, Windows, and Unix Bill Joy, Arthur van Hoff, Jonathan Payne, Frank Yellin, and Tim
to define objects, and methods, which are assigned to individual Lindholm were key contributors to the maturing of the original
classes. computers. However, the JVM must be installed for Java applications or
applets to run at all. prototype.
7 8 9
23
The language was initially called Oak after an oak tree that stood The Evolution of Java The first release of Java 2 carried the version number 1.2. It may
outside Gosling's office. seem odd that the first release of Java 2 used the 1.2 version
Java continued to evolve at an explosive pace. number.
Later the project went by the name Green and was finally renamed
Java, from Java coffee, the coffee from Indonesia in 1995. Soon after the release of Java 1.0, the designers of Java had already The reason is that it originally referred to the internal version
created Java 1.1. number of the Java libraries.
It promised Write Once, Run Anywhere (WORA) functionality,
providing no-cost run-times on popular platforms. Java 1.1 added many new library elements, redefined the way Java 2 added support for a number of new features, such as Swing
events are handled, and reconfigured many features of the 1.0 and the Collections Framework, and it enhanced the Java Virtual
The three editions of Java are library. Machine and various programming tools.
Java Mobile / Micro Edition (ME)
Java Standard Edition (SE) The next major release of Java was Java 2, where the “2” indicates Java 2 also contained a few deprecations. The most important
“second generation.” affected the Thread class in which the methods suspend( ),
Java Enterprise Edition (EE) resume( ), and stop( ) were deprecated.
10 11 12
J2SE 1.3 was the first major upgrade to the original Java 2 release. The next release of Java was J2SE 5, and it was revolutionary. The importance of these new features is reflected in the use of the
For the most part, it added to existing functionality and “tightened version number “5.”
up” the development environment. To grasp the magnitude of the changes that J2SE 5 made to Java,
The next version number for Java would normally have been 1.5.
consider the following list of its major new features:
However, the new features were so significant that a shift from 1.4
The release of J2SE 1.4 further enhanced Java. This release Generics to 1.5 just didn’t seem to express the magnitude of the change.
contained several important upgrades, enhancements, and Annotations
additions.
Autoboxing and auto-unboxing Instead, Sun elected to increase the version number to 5 as a way of
Enumerations emphasizing that a major event was taking place. Thus, it was
For example, it added the new keyword assert, chained exceptions, named J2SE 5, and the developer’s kit was called JDK 5.
and a channel-based I/O subsystem. Enhanced, for-each style for loop
Variable-length arguments (varargs) However, in order to maintain consistency, Sun decided to use 1.5
It also made changes to the Collections Framework and the Static import as its internal version number, which is also referred to as the
networking classes. In addition, numerous small changes were Formatted I/O developer version number. The “5” in J2SE 5 is called the product
version number.
made throughout. Concurrency utilities
13 14 15
The next release of Java was called Java SE 6. Sun once again Java SE 7 was the next release of Java, with the Java Development The new language features were developed as part of Project Coin.
decided to change the name of the Java platform. Kit being called JDK 7, and an internal version number of 1.7. The purpose of Project Coin was to identify a number of small
changes to the Java language that would be incorporated into JDK
First, notice that the “2” was dropped. Thus, the platform was now Java SE 7 was the first major release of Java since Sun 7.
named Java SE, and the official product name was Java Platform,
Standard Edition 6. Microsystems was acquired by Oracle.
Although these features were collectively referred to as “small,”
Java SE 7 contained many new features, including significant the effects of these changes have been quite large in terms of the
The Java Development Kit was called JDK 6. As with J2SE 5, the 6 code they impact.
in Java SE 6 is the product version number. The internal, developer additions to the language and the API libraries.
version number is 1.6.
Upgrades to the Java run-time system that support non-Java Here is a list of the language features added by JDK 7:
Java SE 6 built on the base of J2SE 5, adding incremental languages were also included, but it is the language and library A String can now control a switch statement.
improvements. Java SE 6 added no major features to the Java additions that were of most interest to Java programmers. Binary integer literals
language proper, but it did enhance the API libraries, added
several new packages, and offered improvements to the runtime. Underscores in numeric literals
16 17 18
24
An expanded try statement, called try-with-resources, that Java SE 7 made several additions to the Java API library. The Fork/Join Framework provides important support for parallel
supports automatic resource management. (For example, programming. Parallel programming is the name commonly given
streams can be closed automatically when they are no longer to the techniques that make effective use of computers that contain
needed.) Two of the most important were the enhancements to the NIO more than one processor, including multicore systems.
Framework and the addition of the Fork/Join Framework.
Type inference (via the diamond operator) when constructing a The advantage that multicore environments offer is the prospect of
generic instance. NIO (which originally stood for New I/O) was added to Java in significantly increased program performance. The Fork/Join
version 1.4. Framework addressed parallel programming by
Enhanced exception handling in which two or more exceptions Simplifying the creation and use of tasks that can execute
can be caught by a single catch (multi-catch) and better type concurrently
However, the changes added by Java SE 7 fundamentally expanded
checking for exceptions that are rethrown. Automatically making use of multiple processors
its capabilities.
Although not a syntax change, the compiler warnings associated Therefore, by using the Fork/Join Framework, you can easily create
with some types of varargs methods were improved, and you So significant were the changes, that the term NIO.2 is often used. scalable applications that automatically take advantage of the
have more control over the warnings. processors available in the execution environment.
19 20 21
The newest release of Java is Java SE 8, with the developer’s kit being
called JDK 8.
2. Java Features (i) Object Oriented
In Java, everything is an Object. Java can be easily extended since it
is based on the Object model.
It has an internal version number of 1.8. JDK 8 represents a very
significant upgrade to the Java language because of the inclusion of a
far-reaching new language feature: the lambda expression. (ii) Simple
Java is very easy to learn, and its syntax is simple, clean and easy to
The inclusion of lambda expressions has also had a wide-ranging effect understand.
on the Java libraries, with new features being added to take advantage of
them. According to Sun, Java language is a simple programming
language because:
One of the most important is the new stream API, which is packaged in Java syntax is based on C and influenced by C++.
java.util.stream. The stream API supports pipeline operations on data
Java has removed many complicated and rarely-used features,
and is optimized for lambda expressions.
for example, explicit pointers, operator overloading, etc.
Another very important new package is java.util.function. It defines a There is no need to remove unreferenced objects because there is
number of functional interfaces. an Automatic Garbage Collection in Java.
22 23 24
Bytecode Verifier: It checks the code fragments for illegal code that can
violate access right to objects.
25 26 27
25
(v) Robust (vi) Portable (viii) Dynamic
Robust simply means strong. Java is robust because: Java is portable because it facilitates you to carry the Java bytecode to Java is considered to be more dynamic than C or C++ since it is
any platform. designed to adapt to an evolving environment.
It uses strong memory management.
Java programs can carry extensive amount of run-time information
(vii) Architectural Neutral that can be used to verify and resolve accesses to objects on run-
There is a lack of pointers that avoids security problems.
Compiler generates bytecodes, which have nothing to do with a time.
particular computer architecture, hence a Java program is easy to
There is automatic garbage collection in java which runs on the interpret on any machine.
Java Virtual Machine to get rid of objects which are not being (ix) Interpreted
used by a Java application anymore. Java programs are compiled into an intermediate byte code format,
Java is architecture neutral because there are no implementation
dependent features, for example, the size of primitive types is fixed. which in turn will be interpreted by the VM at run time.
There are exception handling and the type checking mechanism
in Java. All these points make Java robust. In C programming, int data type occupies 2 bytes of memory for 32-bit Hence, any Java program is checked twice before it actually runs.
architecture and 4 bytes of memory for 64-bit architecture. However, it
occupies 4 bytes of memory for both 32 and 64-bit architectures in Java.
28 29 30
(x) High Performance 3. Java’s Magic: Byte Code This makes it easier for compiler as it has to generate byte code for
With the use of Just-In-Time compilers, Java enables high performance. JVM rather than different machine code for each type of machine.
Java is a high level programming language. A program written in high
(xi) Multi-threaded level language cannot be run on any machine directly.
JVM executes the byte code generated by compiler and produce
With Java's multithreaded feature it is possible to write programs that output. JVM is the one that makes java platform independent.
can perform many tasks simultaneously. This design feature allows the First, it needs to be translated into that particular machine language.
developers to construct interactive applications that can run smoothly.
The javac compiler does this thing, it takes java program (.java file So, now we understood that the primary function of JVM is to
containing source code) and translates it into machine code (referred as execute the byte code produced by compiler.
(xii) Distributed byte code or .class file).
Java is distributed because it facilitates users to create distributed
applications in Java. Each operating system has different JVM, however the output they
A Java class file is a file (with the .class filename extension) containing produce after execution of byte code is same across all operating
RMI and EJB are used for creating distributed applications. This feature Java bytecode that can be executed on the Java Virtual Machine (JVM).
of Java makes us able to access files by calling the methods from any
systems which means that the byte code generated on Windows
machine on the internet. can be run on Mac OS and vice versa.
Java Virtual Machine (JVM) is a virtual machine that resides in the real
machine (your computer) and the machine language for JVM is byte
code.
31 32 33
1. Class Loader
Working of JVM Java Virtual Machine (JVM) Architecture The class loader is a subsystem used for loading class files.
First, Java code is compiled into bytecode. This bytecode gets It performs three major functions such as Loading, Linking, and Initialization.
interpreted on different machines
Loading: The Class loader reads the .class file, generate the corresponding
binary data and save it in method area.
Between host system and Java source, Bytecode is an intermediary
language. Linking: Performs verification, preparation, and (optionally) resolution.
Verification: It ensures the correctness of .class file i.e. it check whether
this file is properly formatted and generated by valid compiler or not. If
JVM is responsible for allocating memory space. verification fails, we get run-time exception java.lang.VerifyError.
Preparation: JVM allocates memory for class variables and initializing the
memory to default values.
Resolution: It is the process of replacing symbolic references from the type
with direct references. It is done by searching into method area to locate
the referenced entity.
Initialization: In this phase, all static variables are assigned with their values
defined in the code and static block(if any).
34 35 36
26
2. Method Area 5. Program Counter (PC) Registers Interpreter
JVM Method Area stores class structures like metadata, the constant Each thread will have separate PC Registers, to hold the address of It interprets the bytecode line by line and then executes.
runtime pool, and the code for methods. current executing instruction once the instruction is executed the PC The disadvantage here is that when one method is called multiple
register will be updated with the next instruction. times, every time interpretation is required.
3. Heap
All the Objects, their related instance variables, and arrays are 6. Native Method Stacks Just-In-Time Compiler(JIT)
stored in the heap. This memory is common and shared across Native Method Stack holds native method information. For every It is used to increase efficiency of interpreter.
multiple threads. thread, a separate native method stack will be created. It compiles the entire bytecode and changes it to native code so
whenever interpreter see repeated method calls, JIT provide direct
4. JVM Language Stacks 7. Execution Engine native code for that part so re-interpretation is not required, thus
For every thread, a separate runtime stack will be created. For every Execution engine execute the .class (bytecode). It reads the byte- efficiency is improved.
method call, one entry will be made in the stack memory which is code line by line, use data and information present in various Garbage Collector
called Stack Frame. All local variables will be created in the stack memory area and execute instructions. It can be classified in three Collects and removes unreferenced objects.
memory parts :- Interpreter, Just-In-Time (JIT) Compiler, Garbage Collector.
37 38 39
8. Native Method Interface Software Code Compilation & Execution Process Java Code Compilation and Execution in Java VM
The Native Method Interface is a programming framework.
It allows Java code which is running in a JVM to call by libraries and In order to write and execute a software program, you need the following In your main, you have two methods f1 and f2.
native applications. The main method is stored in file a1.java
1) Editor – To type your program into, a notepad could be used for this
f1 is stored in a file as a2.java and f2 is stored in a file as a3.java
9. Native Method Libraries 2) Compiler – To convert your high language program into native machine code
Native Libraries is a collection of the Native Libraries(C, C++) which
are needed by the Execution Engine. 3) Linker – To combine different program files reference in your main program
together.
4) Loader – To load the files from your secondary storage device like Hard Disk,
Flash Drive, CD into RAM for execution. The loading is automatically done when
you execute your code.
40 41 42
The compiler will compile the three files and produces 3 Next, the execution engine will convert the Bytecode into Native 4. How Java differs from C and C++
corresponding .class file which consists of BYTE code. machine code. This is just in time compiling.
Metrics C C++ Java
The Java VM or Java Virtual Machine resides on the RAM. During
Programming Procedural language Object-Oriented Pure Object Oriented
execution, using the class loader the class files are brought on the Paradigm Programming (OOP) Oriented
RAM. The BYTE code is verified for any security breaches. Developer Dennis Ritchie in 1972 Bjarne Stroustrup in 1979 James Gosling in 1991
43 44 45
27
AN OVERVIEW OF JAVA 1. Object Oriented Programming
Object-oriented programming (OOP) is a programming methodology
1. Object Oriented Programming that helps organize complex programs through the use of inheritance,
encapsulation, and polymorphism.
Two paradigms
The Three OOP Principles OOP is an approach to program organization and development, which
attempts to eliminate some of the pitfalls of conventional programming
An Overview of Java methods by incorporating the best of structured programming features
with several new concepts.
2. A First simple Program
It is a new way of organizing and developing programs and has nothing
to do with any particular language.
3. Control statements
C++ is basically a procedural language with Object-oriented extension
whereas Java is a pure object-oriented language.
46 47 48
Two Paradigm The first way is called the process-oriented model. To manage increasing complexity, the second approach, called
object-oriented programming, was conceived.
All computer programs consist of two elements: code and data.
This approach characterizes a program as a series of linear steps
(that is, code). Object-oriented programming organizes a program around its data
Furthermore, a program can be conceptually organized around its (that is, objects) and a set of well-defined interfaces to that data.
code or around its data.
The process-oriented model can be thought of as code acting on
data. An object-oriented program can be characterized as data
That is, some programs are written around “what is happening” controlling access to code.
and others are written around “who is being affected.” Procedural languages such as C employ this model to considerable
success.
These are the two paradigms that govern how a program is
constructed.
49 50 51
52 53 54
28
Data Abstraction Inheritance
Abstraction refers to the act of representing essential features without
including the background details or explanations. Inheritance is the process by which objects of one class acquire the
properties of objects of another class.
Classes use the concept of abstraction and are defined as a list of Inheritance supports the concept of hierarchical classification.
abstract attributes such as size, weight and cost, and methods that
operate on these attributes. For example, the bird robin is the part of the class flying bird,
which is again a part of the class bird.
Encapsulation
The wrapping up of data and methods into a single unit (called class) is
known as encapsulation. It is the most striking feature of a class.
The data is not accessible to the outside world and only those methods,
which are wrapped in the class, can access it.
These method provide the interface between the object’s data and the
program.
55 56 57
In OOP, the concept of inheritance provides the idea of reusability. Polymorphism Dynamic Binding
This means that we can add additional features to an existing class Polymorphism means the ability to take more than one form. Dynamic binding means that the code associated with a given
without modifying it. For example, an operation may exhibit different behaviour in procedure call in not known until the time of the call at runtime.
This is possible by deriving a new class from the existing one. different instances. It is associated with polymorphism and inheritance.
The new class will have the combined features of both the classes. The behaviour depends upon the types of data used in the A procedure call associated with a polymorphic reference depends
Thus the real appeal and power of the inheritance mechanism is operation. on the dynamic type of that reference.
that it allows the programmer to reuse a class that is almost, but not Consider the procedure “area”. By inheritance, every object will
exactly, what he wants and to tailor the class in such a way that it have this procedure.
does not introduce any undesirable side effects into the rest of the Its algorithm is, however, unique to each object and so the area
classes. procedure will be redefined in each class that defines the object.
In Java, the derived class is known as ‘subclass’. At run-time, the code matching the object under current reference
Without inheritance, each class would have to explicitly include all will be called.
of its features.
58 59 60
Message Communication Objects communicate with other by sending and receiving A message for an object is a request for execution of a procedure,
An object-oriented program consists of a set of objects that information much the same way as people pass messages to one and therefore will invoke a method (procedure) in the receiving
communicate with each other. another. object that generates the desired result.
The process of programming in an object-oriented language, Message passing involves specifying the name of the object, the
therefore, involves the following basic steps: name of the method(message) and the information to be sent. For
Create classes that define objects and their behaviour example, consider the statement
Create objects from class definitions emp.salary(name);
Establish communication among objects through message
passing Here, emp is the object, salary is the message and the name is the
parameter that contains information.
61 62 63
29
2. A First Simple Program The public keyword is an access modifier, which allows the programmer Any information that you need to pass to a method is received by
to control the visibility of class members. variables specified within the set of parentheses that follow the
name of the method.
class Example When a class member is preceded by public, then that member may be
{ accessed by code outside the class in which it is declared. (The opposite
of public is private, which prevents a member from being used by code These variables are called parameters. If there are no parameters
// Your program begins with a call to main(). defined outside of its class.) required for a given method, you still need to include the empty
public static void main(String args[]) parentheses.
{ In this case, main( ) must be declared as public, since it must be called by
System.out.println("This is a simple Java program."); code outside of its class when the program is started.
In main( ), there is only one parameter, albeit a complicated one.
} String args[ ] declares a parameter named args, which is an array of
} The keyword static allows main( ) to be called without having to
instantiate a particular instance of the class. This is necessary since instances of the class String. (Arrays are collections of similar
main( ) is called by the Java Virtual Machine before any objects are objects.)
made.
C:\>javac Example.java Objects of type String store character strings. In this case, args
C:\>java Example The keyword void simply tells the compiler that main( ) does not return
a value. receives any command-line arguments present when the program
This is a simple Java program. is executed.
64 65 66
67 68 69
Java defines eight primitive types of data: byte, short, int, long, char, Integers:
float, double, and boolean. Java defines four integer types: byte, short, int, and long. All of
The primitive types are also commonly referred to as simple types. these are signed, positive and negative values.
Integers: This group includes byte, short, int, and long, which are for
whole-valued signed numbers.
Java does not support unsigned, positive-only integers. Many other
computer languages support both signed and unsigned integers.
Floating-point numbers: This group includes float and double, which
represent numbers with fractional precision.
However, Java’s designers felt that unsigned integers were
Characters: This group includes char, which represents symbols in a
unnecessary.
character set, like letters and numbers.
Specifically, they felt that the concept of unsigned was used mostly
Boolean: This group includes boolean, which is a special type for to specify the behavior of the high-order bit, which defines the sign
representing true/false values. of an integer value.
70 71 72
30
short Floating-Point Types
short is a signed 16-bit type. It has a range from –32,768 to 32,767. It is Floating-point numbers, also known as real numbers, are used
probably the least used Java type. when evaluating expressions that require fractional precision.
Here are some examples of short variable declarations:
short s;
For example, calculations such as square root, or transcendentals
int such as sine and cosine, result in a value whose precision requires a
byte
The most commonly used integer type is int. It is a signed 32-bit type. floating point type.
The smallest integer type is byte. This is a signed 8-bit type that has In addition to other uses, variables of type int are commonly employed
a range from –128 to 127. to control loops and to index arrays.
Variables of type byte are especially useful when you’re working Java implements the standard (IEEE–754) set of floating-point types
with a stream of data from a network or file. and operators.
long
They are also useful when you’re working with raw binary data long is a signed 64-bit type and is useful for those occasions where an int
that may not be directly compatible with Java’s other built-in types. type is not large enough to hold the desired value. There are two kinds of floating-point types, float and double,
byte b, c; which represent single- and double-precision numbers,
The range of a long is quite large. This makes it useful when big, whole
numbers are needed.
respectively.
73 74 75
float Double A short program that uses double variables to compute the area of a circle
The type float specifies a single-precision value that uses 32 bits of Double precision, as denoted by the double keyword, uses 64 bits class Area
storage. to store a value. {
public static void main(String args[])
Single precision is faster on some processors and takes half as much Double precision is actually faster than single precision on some {
space as double precision, but will become imprecise when the values
modern processors that have been optimized for high-speed double pi, r, a;
are either very large or very small.
mathematical calculations.
r = 10.8; // radius of circle
Variables of type float are useful when you need a fractional component, pi = 3.1416; // pi, approximately
but don’t require a large degree of precision. All transcendental math functions, such as sin( ), cos( ), and sqrt( ),
a = pi * r * r; // compute area
return double values.
System.out.println("Area of circle is " + a);
For example, float can be useful when representing dollars and cents.
}
When you need to maintain accuracy over many iterative
calculations, or are manipulating large-valued numbers, double is }
Here are some example float variable declarations:
the best choice. Area of circle is 366.436224
float hightemp, lowtemp;
76 77 78
79 80 81
31
Notice that ch1 is assigned the value 88, which is the ASCII (and import java.io.*;
In the program, ch1 is first given the value X. Next, ch1 is
Unicode) value that corresponds to the letter X. class CharDemo2
incremented. This results in ch1
{
As mentioned, the ASCII character set occupies the first 127 values public static void main(String args[])
{ containing Y, the next character in the ASCII (and Unicode)
in the Unicode character set.
sequence.
char ch1;
Although char is designed to hold Unicode characters, it can also ch1 = 'X';
be used as an integer type on which you can perform arithmetic System.out.println("ch1 contains " + ch1);
operations. ch1++; // increment ch1
System.out.println("ch1 is now " + ch1);
For example, you can add two characters together, or increment the }
value of a character variable. }
ch1 contains X
ch1 is now Y
82 83 84
//outcome of a relational operator is a boolean value Further, the extra set of parentheses around 10>9 is necessary because the +
System.out.println("10 > 9 is " + (10 > 9));
}
operator has a higher precedence than the >.
}
85 86 87
88 89 90
32
Dynamic Initialization Here, three local variables—a, b, and c—are declared. The Scope and Lifetime of Variables
Java allows variables to be initialized dynamically, using any So far, all of the variables used have been declared at the start of
expression valid at the time the variable is declared. the main( ) method.
The first two, a and b, are initialized by constants.
class DynInit However, Java allows variables to be declared within any block.
{ However, c is initialized dynamically to the length of the
public static void main(String args[]) hypotenuse (using the Pythagorean theorem).
A block is begun with an opening curly brace and ended by a
{ closing curly brace. A block defines a scope.
double a = 3.0, b = 4.0; The program uses another of Java’s built-in methods, sqrt( ), which
// c is dynamically initialized is a member of the Math class, to compute the square root of its
argument. Thus, each time you start a new block, you are creating a new
double c = Math.sqrt(a * a + b * b); scope.
System.out.println("Hypotenuse is " + c);
}
A scope determines what objects are visible to other parts of
} your program. It also determines the lifetime of those objects.
91 92 93
class Scope Variables are created when their scope is entered, and class LifeTime
{ destroyed when their scope is left. {
public static void main(String args[])
public static void main(String args[])
{
int x; // known to all code within main This means that a variable will not hold its value once it has {
x = 10; gone out of scope. Therefore, variables declared within a int x;
if(x == 10) method will not hold their values between calls to that for(x = 0; x < 3; x++)
{
method. {
// start new scope
int y = -1; // y is initialized each time block is entered
int y = 20; // known only to this block
System.out.println("y is: " + y); // this always prints -1
// x and y both known here. Also, a variable declared within a block will lose its value
System.out.println("x and y: " + x + " " + y); when the block is left. Thus, the lifetime of a variable is y = 100;
x = y * 2;
confined to its scope. System.out.println("y is now: " + y);
} }
// y = 100; // Error! y not known here
}
// x is still known here If a variable declaration includes an initializer, then that
}
System.out.println("x is " + x); variable will be reinitialized each time the block in which it is
} declared is entered.
}
94 95 96
y is: -1 Although blocks can be nested, you cannot declare a variable to have the same 5. Type Conversion and Casting
y is now: 100 name as one in an outer scope.
y is: -1 class ScopeErr
If the two types are compatible, then Java will perform the
y is now: 100 { conversion automatically. For example, it is always possible to
y is: -1 public static void main(String args[]) assign an int value to a long variable.
y is now: 100 {
int bar = 1;
However, not all types are compatible, and thus, not all type
y is reinitialized to –1 each time the inner for loop is entered. { conversions are implicitly allowed.
// creates a new scope
Even though it is subsequently assigned the value 100, this value is lost. int bar = 2; // Compile-time error – bar already defined!
For instance, there is no automatic conversion defined from double
} to byte.
}
}
Fortunately, it is still possible to obtain a conversion between
incompatible types. To do so, you must use a cast, which performs
an explicit conversion between incompatible types.
97 98 99
33
Java’s Automatic Conversions For widening conversions, the numeric types, including integer and Casting Incompatible Types
floating-point types, are compatible with each other.
Although the automatic type conversions are helpful, they will not
When one type of data is assigned to another type of variable, an
fulfil all needs.
automatic type conversion will take place if the following two However, there are no automatic conversions from the numeric
conditions are met: types to char or boolean.
The two types are compatible. For example, what if you want to assign an int value to a byte
variable?
The destination type is larger than the source type. Also, char and boolean are not compatible with each other.
This conversion will not be performed automatically, because a
When these two conditions are met, a widening conversion takes
byte is smaller than an int.
place. For example, the int type is always large enough to hold all
valid byte values, so no explicit cast statement is required.
This kind of conversion is sometimes called a narrowing
conversion, since you are explicitly making the value narrower so
that it will fit into the target type.
To create a conversion between two incompatible types, you int a; class Conversion
must use a cast. byte b; {
// … public static void main(String args[])
{
b = (byte) a;
A cast is simply an explicit type conversion. It has this general byte b;
form: A different type of conversion will occur when a floating-point value is
int i = 257;
double d = 323.142;
(target-type) value assigned to an integer type: truncation. As you know, integers do not System.out.println("\nConversion of int to byte.");
have fractional components.
b = (byte) i;
Here, target-type specifies the desired type to convert the Thus, when a floating-point value is assigned to an integer type, the
System.out.println("i and b " + i + " " + b);
System.out.println("\nConversion of double to int.");
specified value to. For example, the following fragment casts fractional component is lost. i = (int) d;
an int to a byte. System.out.println("d and i " + d + " " + i);
For example, if the value 1.23 is assigned to an integer, the resulting System.out.println("\nConversion of double to byte.");
value will simply be 1.
If the integer’s value is larger than the range of a byte, it will b = (byte) d;
be reduced modulo (the remainder of an integer division by System.out.println("d and b " + d + " " + b);
The 0.23 will have been truncated. Of course, if the size of the whole }
the) byte’s range. number component is too large to fit into the target integer type, then }
that value will be reduced modulo the target type’s range.
Conversion of int to byte. Let’s look at each conversion. When the value 257 is cast into a Automatic Type Promotion in Expressions
i and b 257 1 byte variable, the result is the remainder of the division of 257 by In addition to assignments, there is another place where certain type
conversions may occur: in expressions.
256 (the range of a byte), which is 1 in this case. byte a = 40;
Conversion of double to int.
byte b = 50;
d and i 323.142 323
When the d is converted to an int, its fractional component is lost. byte c = 100;
int d = a * b / c;
Conversion of double to byte.
d and b 323.142 67 When d is converted to a byte, its fractional component is lost, The result of the intermediate term a * b easily exceeds the range of
and the value is reduced modulo 256, which in this case is 67. either of its byte operands.
34
As useful as the automatic promotions are, they can cause confusing In cases where you understand the consequences of overflow, The Type Promotion Rules
compile-time errors. For example, this seemingly correct code causes a
problem: you should use an explicit cast, such as Java defines several type promotion rules that apply to
byte b = 50; byte b = 50; expressions. They are as follows: First, all byte, short, and char
b = b * 2; // Error! Cannot assign an int to a byte! values are promoted to int, as just described.
b = (byte)(b * 2);
The code is attempting to store 50 * 2, a perfectly valid byte value, back which yields the correct value of 100.
into a byte variable. Then, if one operand is a long, the whole expression is promoted
to long.
However, because the operands were automatically promoted to int
when the expression was evaluated, the result has also been promoted
to int. If one operand is a float, the entire expression is promoted to
float.
Thus, the result of the expression is now of type int, which cannot be
assigned to a byte without the use of a cast.
If any of the operands are double, the result is double.
This is true even if, as in this particular case, the value being assigned
would still fit in the target type.
How to declare an array in Java? How to initialize arrays in Java? //declare and initialize and array
In the Java array, each memory location is associated with a number.
Array can be declared as The number is known as an array index. We can also initialize arrays int[] age = {10, 20, 30, 40, 50};
dataType[] arrayName; in Java, using the index number. For example,
// declare an array
int[] age = new int[3];
Here, we have created an array named age and initialized it
dataType - it can be primitive data types like int, char, double, with the values inside the curly brackets.
byte, etc. or Java objects. // initialize array
age[0] = 10; Note that we have not provided the size of the array. In this
age[1] = 20;
arrayName - it is an identifier case, the Java compiler automatically specifies the size by
age[2] = 30;
counting the number of elements in the array (i.e. 5).
Array indices always start from 0. That is, the first element of an array
Example: is at index 0.
double[] data; // declare an array
double[] data = new double[10]; // allocate memory If the size of an array is n, then the last element of the array will be at
index n-1.
The expression age.length is used in for loop for-each Loop class ExampleEach
Syntax {
length property of the array is used to get the size of the The syntax of Java for-each loop consists of data_type with the public static void main(String[] args)
variable followed by a colon (:), then array or collection.
array. {
for(data_type variable : array | collection)
int[] age = {10, 20, 30};
{
length can be used for int[], double[], String[] to know the System.out.println("Using for-each Loop:");
//body of for-each loop
length of the arrays. }
for(int a : age)
{
length() can be used for String, StringBuilder, etc. How it works? System.out.println(a);
The Java for-each loop traverses the array or collection until }
String class related Objects to know the length of the String the last element. For each element, it stores the element in the }
variable and executes the body of the for-each loop. }
} }
The class is at the core of Java. Perhaps the most important thing to understand about a class is
8. Overloading Methods that it defines a new data type.
9. Using Objects as Parameters It is the logical construct upon which the entire Java language is
built because it defines the shape and nature of an object. Once defined, this new type can be used to create objects of that
10. Returning Objects type.
11. Recursion As such, the class forms the basis for object-oriented programming
in Java. Thus, a class is a template for an object, and an object is an instance
12. Static and Final Keywords of a class.
Any concept you wish to implement in a Java program must be
13. Nested and Inner Classes
encapsulated within a class.
class classname
The General Form of a Class {
The data, or variables, defined within a class are called instance
A class is declared by use of the class keyword. type instance-variable1; variables.
type instance-variable2;
// ...
Classes can (and usually do) get much more complex. A simplified type instance-variableN; The code is contained within methods. Collectively, the methods
general form of a class definition is shown in next slide: type methodname1(parameter-list) and variables defined within a class are called members of the
{ class.
// body of method
}
type methodname2(parameter-list) In most classes, the instance variables are acted upon and accessed
{
// body of method by the methods defined for that class.
}
// ...
type methodnameN(parameter-list) Thus, as a general rule, it is the methods that determine how a class
{ data can be used.
// body of method
}
}
37
Variables defined within a class are called instance variables A Simple Class To actually create a Box object, you will use a statement like the
because each instance of the class (that is, each object of the class) Here is a class called Box that defines three instance variables: following:
contains its own copy of these variables. width, height, and depth. Box mybox = new Box(); // create a Box object called mybox
class Box
Thus, the data for one object is separate and unique from the data { After this statement executes, mybox will be an instance of Box.
for another. double width;
double height;
As mentioned earlier, each time you create an instance of a class,
Java classes do not need to have a main( ) method. double depth;
you are creating an object that contains its own copy of each
} instance variable defined by the class.
In this case, the new data type is called Box.
You only specify one if that class is the starting point for your
program. Thus, every Box object will contain its own copies of the instance
You will use this name to declare objects of type Box. It is
variables width, height, and depth.
important to remember that a class declaration only creates a
template; it does not create an actual object.
To access these variables, you will use the dot (.) operator. The dot class Box mybox.width = 10;
operator links the name of the object with the name of an instance mybox.height = 20;
variable. {
mybox.depth = 15;
double width;
For example, to assign the width variable of mybox the value 100, you double height; vol = mybox.width * mybox.height * mybox.depth;
would use the following statement:
double depth; System.out.println("Volume is " + vol);
mybox.width = 100;
} }
class BoxDemo }
This statement tells the compiler to assign the copy of width that is
contained within the mybox object the value of 100. {
Volume is 3000.0
public static void main(String args[])
In general, you use the dot operator to access both the instance variables
and the methods within an object.
{ You should call the file that contains this program BoxDemo.java,
Box mybox = new Box(); because the main( ) method is in the class called BoxDemo, not the class
called Box.
Although commonly referred to as the dot operator, the formal double vol;
specification for Java categorizes the . as a separator. When you compile this program, you will find that two .class files have
been created, one for Box and one for BoxDemo.
double height; // assign different values to mybox2’s instance variables As you can see, mybox1’s data is completely separate from the data
double depth; mybox2.width = 3; contained in mybox2
mybox2.height = 6;
}
mybox2.depth = 9;
class BoxDemo2
{ // compute volume of first box
vol = mybox1.width * mybox1.height * mybox1.depth;
public static void main(String args[]) System.out.println("Volume is " + vol);
{
// compute volume of second box
Box mybox1 = new Box();
vol = mybox2.width * mybox2.height * mybox2.depth;
Box mybox2 = new Box(); System.out.println("Volume is " + vol);
double vol; }
}
38
2. Declaring Objects You can do this using the new operator. The new operator The first line declares mybox as a reference to an object of type
dynamically allocates (that is, allocates at run time) memory for an Box.
When you create a class, you are creating a new data type. You can object and returns a reference to it.
use this type to declare objects of that type. At this point, mybox does not yet refer to an actual object.
This reference is, more or less, the address in memory of the object
However, obtaining objects of a class is a two-step process. allocated by new. This reference is then stored in the variable. The next line allocates an object and assigns a reference to it to
Box mybox; // declare reference to object mybox.
First, you must declare a variable of the class type. This variable mybox = new Box(); // allocate a Box object
does not define an object. After the second line executes, you can use mybox as if it were a
Box object.
Instead, it is simply a variable that can refer to an object. Second,
you must acquire an actual, physical copy of the object and assign But in reality, mybox simply holds, in essence, the memory
it to that variable. address of the actual Box object.
This situation is depicted here: Although b1 and b2 both refer to the same object, they are not 4. Introducing Methods
linked in any other way.
A method is a block of code or collection of statements or a set of
For example, a subsequent assignment to b1 will simply unhook b1 code grouped together to perform a certain task or operation. It is
from the original object without affecting the object or affecting b2. used to achieve the reusability of code.
For example:
Box b1 = new Box(); This is the general form of a method:
type name(parameter-list)
Box b2 = b1;
{
// ...
// body of method
b1 = null;
}
Here, b1 has been set to null, but b2 still points to the original object. Here, type specifies the type of data returned by the method. This
can be any valid type, including class types that you create.
class BoxDemo3 //assign different values to mybox2’s instance variables Look closely at the following two lines of code:
{ mybox2.width = 3; mybox1.volume();
mybox2.height = 6;
public static void main(String args[]) mybox2.volume();
mybox2.depth = 9;
{
Box mybox1 = new Box(); // display volume of first box The first line here invokes the volume( ) method on mybox1. That
Box mybox2 = new Box(); mybox1.volume(); is, it calls volume( ) relative to the mybox1 object, using the object’s
name followed by the dot operator.
// assign values to mybox1's instance variables // display volume of second box
mybox2.volume(); Thus, the call to mybox1.volume( ) displays the volume of the box
mybox1.width = 10;
} defined by mybox1, and the call to mybox2.volume( ) displays the
mybox1.height = 20; } volume of the box defined by mybox2.
mybox1.depth = 15;
Volume is 3000.0
Each time volume( ) is invoked, it displays the volume for the
Volume is 162.0
specified box.
There is something very important to notice inside the volume( ) Returning a Value class BoxDemo4
method: the instance variables width, height, and depth are A better way to implement volume( ) is to have it compute the volume of {
referred to directly, without preceding them with an object name or the box and return the result to the caller.
the dot operator. public static void main(String args[])
class Box {
When a method uses an instance variable that is defined by its { Box mybox1 = new Box();
class, it does so directly, without explicit reference to an object and double width; Box mybox2 = new Box();
without use of the dot operator. double height; double vol;
double depth;
Once this invocation has occurred, the object is known. Thus,
within a method, there is no need to specify the object a second // compute and return volume // assign values to mybox1's instance variables
time. double volume() mybox1.width = 10;
{ mybox1.height = 20;
This means that width, height, and depth inside volume( ) return width * height * depth; mybox1.depth = 15;
implicitly refer to the copies of those variables found in the object }
that invokes volume( ).
}
// sets dimensions of box // initialize each box As you can see, the setDim( ) method is used to set the dimensions of
void setDim(double w, double h, double d) mybox1.setDim(10, 20, 15); each box. For example, when
{ mybox1.setDim(10, 20, 15);
mybox2.setDim(3, 6, 9);
width = w;
is executed, 10 is copied into parameter w, 20 is copied into h, and 15
height = h;
// get volume of first box is copied into d.
depth = d;
} vol = mybox1.volume();
} System.out.println("Volume is " + vol); Inside setDim( ) the values of w, h, and d are then assigned to width,
class BoxDemo5 height, and depth, respectively.
{
// get volume of second box
public static void main(String args[])
{ vol = mybox2.volume();
Box mybox1 = new Box(); System.out.println("Volume is " + vol);
Box mybox2 = new Box(); }
double vol; }
5. Constructors We can rework the Box example so that the dimensions of a box are // compute and return volume
automatically initialized when an object is constructed. To do so, replace
setDim( ) with a constructor. double volume()
A constructor initializes an object immediately upon creation. It {
has the same name as the class in which it resides and is class Box return width * height * depth;
syntactically similar to a method. { }
double width;
}
Constructors look a little strange because they have no return type, double height;
double depth; class BoxDemo6
not even void.
{
// This is the constructor for Box. public static void main(String args[])
This is because the implicit return type of a class’ constructor is the Box() {
class type itself. { // declare, allocate, and initialize Box objects
System.out.println("Constructing Box");
Box mybox1 = new Box();
It is the constructor’s job to initialize the internal state of an object width = 10;
so that the code creating an instance will have a fully initialized, height = 10; Box mybox2 = new Box();
usable object immediately. depth = 10; double vol;
}
The default constructor automatically initializes all instance variables Parameterized Constructors class Box
{
to their default values, which are zero, null, and false, for numeric While the Box( ) constructor in the preceding example does initialize double width;
types, reference types, and boolean, respectively. a Box object, it is not very useful—all boxes have the same double height;
double depth;
dimensions.
The default constructor is often sufficient for simple classes, but it // This is the constructor for Box
usually won’t do for more sophisticated ones. Box(double w, double h, double d)
What is needed is a way to construct Box objects of various {
dimensions. width = w;
Once you define your own constructor, the default constructor is no height = h;
depth = d;
longer used. The easy solution is to add parameters to the constructor. As you can }
probably guess, this makes it much more useful.
// compute and return volume
double volume()
For example, the following version of Box defines a parameterized {
return width * height * depth;
constructor that sets the dimensions of a box as specified by those
}
parameters. }
class BoxDemo7 // get volume of second box As you can see, each object is initialized as specified in the parameters
{ vol = mybox2.volume(); to its constructor. For example, in the following line,
public static void main(String args[]) System.out.println("Volume is " + vol); Box mybox1 = new Box(10, 20, 15);
{ }
// declare, allocate, and initialize Box objects } The values 10, 20, and 15 are passed to the Box( ) constructor when
Box mybox1 = new Box(10, 20, 15); new creates the object.
Box mybox2 = new Box(3, 6, 9); Volume is 3000.0
double vol; Volume is 162.0 Thus, mybox1’s copy of width, height, and depth will contain the
values 10, 20, and 15, respectively.
The finalize( ) Method The finalize( ) method has this general form: It is defined in java.lang.Object class, therefore it is available to all the
classes.
Sometime an object will need to perform some specific task before it protected void finalize( )
is destroyed such as closing an open connection or releasing any { It is declare as proctected inside Object class.
resources held.
// finalization code here
} It gets called only once by a Daemon thread named GC (Garbage
To handle such situation finalize() method is used. Collector) thread.
It only request the JVM for garbage collection. This method is present in
System and Runtime class.
public class ExampleGC 8. Overloading Methods When an overloaded method is invoked, Java uses the type and/or
{ number of arguments as its guide to determine which version of
public static void main(String[] args) In Java, it is possible to define two or more methods within the the overloaded method to actually call.
{ same class that share the same name, as long as their parameter
declarations are different. Thus, overloaded methods must differ in the type and/or number
Test t = new Test();
of their parameters.
t=null;
When this is the case, the methods are said to be overloaded, and
System.gc();
the process is referred to as method overloading. While overloaded methods may have different return types, the
} return type alone is insufficient to distinguish two versions of a
public void finalize() method.
Method overloading is one of the ways that Java supports
{ polymorphism.
System.out.println("Garbage Collected"); When Java encounters a call to an overloaded method, it simply
} executes the version of the method whose parameters match the
} arguments used in the call.
// Overload test for a double parameter int i = 88; As you can see, this version of OverloadDemo does not define
void test(double a) ob.test(); test(int).
{ ob.test(10, 20);
Therefore, when test( ) is called with an integer argument inside
System.out.println("Inside test(double) a: " + a); ob.test(i); // this will invoke test(double) Overload, no matching method is found.
} ob.test(123.2); // this will invoke test(double)
} } However, Java can automatically convert an integer into a double,
class OverloadType } and this conversion can be used to resolve the call.
{
public static void main(String args[]) No parameters Therefore, after test(int) is not found, Java elevates i to double and
then calls test(double). Of course, if test(int) had been defined, it
{ a and b: 10 20 would have been called instead.
OverloadDemo ob = new OverloadDemo(); Inside test(double) a: 88
Inside test(double) a: 123.2 Java will employ its automatic type conversions only if no exact
match is found.
// return true if o is equal to the invoking object class PassOb As you can see, the equalTo( ) method inside Test compares two
boolean equalTo(Test o) { objects for equality and returns the result.
{ public static void main(String args[])
if(o.a == a && o.b == b) { That is, it compares the invoking object with the one that it is
return true; Test ob1 = new Test(100, 22); passed.
else Test ob2 = new Test(100, 22);
return false; Test ob3 = new Test(-1, -1); If they contain the same values, then the method returns true.
Otherwise, it returns false.
} System.out.println("ob1 == ob2: " + ob1.equalTo(ob2));
} System.out.println("ob1 == ob3: " + ob1.equalTo(ob3));
Notice that the parameter o in equalTo( ) specifies Test as its type.
}
}
Although Test is a class type created by the program, it is used in
ob1 == ob2: true
just the same way as Java’s built-in types.
ob1 == ob3: false
// constructor used when cube is created class OverloadCons2 // get volume of first box
Box(double len) { vol = mybox1.volume();
{ public static void main(String args[]) System.out.println("Volume of mybox1 is " + vol);
width = height = depth = len; {
} // create boxes using the various constructors // get volume of second box
Box mybox1 = new Box(10, 20, 15); vol = mybox2.volume();
// compute and return volume Box mybox2 = new Box(); System.out.println("Volume of mybox2 is " + vol);
double volume() Box mycube = new Box(7);
{ // get volume of cube
return width * height * depth; // create copy of mybox1 vol = mycube.volume();
} Box myclone = new Box(mybox1); System.out.println("Volume of cube is " + vol);
} double vol;
// get volume of clone A Closer Look at Argument Passing The second way an argument can be passed is call-by-reference.
vol = myclone.volume(); In general, there are two ways that a computer language can pass
System.out.println("Volume of clone is " + vol); an argument to a subroutine. In this approach, a reference to an argument (not the value of the
} argument) is passed to the parameter.
} The first way is call-by-value.
Inside the subroutine, this reference is used to access the actual
Volume of mybox1 is 3000.0 This approach copies the value of an argument into the formal argument specified in the call.
Volume of mybox2 is -1.0 parameter of the subroutine.
Volume of cube is 343.0 This means that changes made to the parameter will affect the
Therefore, changes made to the parameter of the subroutine have argument used to call the subroutine.
Volume of clone is 3000.0
no effect on the argument.
12. Static and Final Keywords When a member is declared static, it can be accessed before any Methods declared as static have several restrictions:
objects of its class are created, and without reference to any object. • They can only directly call other static methods.
Understanding Static • They can only directly access static data.
There will be times when you will want to define a class member You can declare both methods and variables to be static. The most • They cannot refer to this or super in any way.
that will be used independently of any object of that class. common example of a static member is main( ). main( ) is declared
as static because it must be called before any objects exist.
If you need to do computation in order to initialize your static
Normally, a class member must be accessed only in conjunction variables, you can declare a static block that gets executed exactly
with an object of its class. Instance variables declared as static are, essentially, global variables. once, when the class is first loaded.
However, it is possible to create a member that can be used by When objects of its class are declared, no copy of a static variable is The following example shows a class that has a static method, some
itself, without reference to a specific instance. made. static variables, and a static initialization block:
To create such a member, precede its declaration with the keyword Instead, all instances of the class share the same static variable.
static.
class UseStatic static Outside of the class in which they are defined, static methods and
{ variables can be used independently of any object.
{
System.out.println("Static block initialized.");
static int a = 3; To do so, you need only specify the name of their class followed by the
b = a * 4;
static int b; } dot operator.
For example, if you wish to call a static method from outside its class,
static void meth(int x) public static void main(String args[])
you can do so using the following general form:
{ {
classname.method( )
meth(42);
System.out.println("x = " + x);
}
System.out.println("a = " + a); Here, classname is the name of the class in which the static method is
} declared. As you can see, this format is similar to that used to call non-
System.out.println("b = " + b); Static block initialized. static methods through object reference variables.
} x = 42
a=3 A static variable can be accessed in the same way—by use of the dot
b = 12 operator on the name of the class.
final int FILE_NEW = 1; In addition to fields, both method parameters and local variables 13. Nested and Inner Classes
final int FILE_OPEN = 2; can be declared final.
final int FILE_SAVE = 3; It is possible to define a class within another class; such classes are
Declaring a parameter final prevents it from being changed within known as nested classes.
final int FILE_SAVEAS = 4;
final int FILE_QUIT = 5; the method.
The scope of a nested class is bounded by the scope of its enclosing
Declaring a local variable final prevents it from being assigned a class.
Subsequent parts of your program can now use FILE_OPEN, etc.,
as if they were constants, without fear that a value has been value more than once.
changed. Thus, if class B is defined within class A, then B does not exist
The keyword final can also be applied to methods, but its meaning independently of A.
It is a common coding convention to choose all uppercase is substantially different than when it is applied to variables.
identifiers for final fields, as this example shows. A nested class has access to the members, including private
members, of the class in which it is nested.
However, the enclosing class does not have access to the members That is, it cannot refer to non-static members of its enclosing class class Outer
{
of the nested class. directly.
int outer_x = 100;
void test()
A nested class that is declared directly within its enclosing class Because of this restriction, static nested classes are seldom used. {
Inner inner = new Inner();
scope is a member of its enclosing class.
inner.display();
The most important type of nested class is the inner class. An inner }
It is also possible to declare a nested class that is local to a block. class is a non-static nested class.
// this is an inner class
class Inner
There are two types of nested classes: static and non-static. A static It has access to all of the variables and methods of its outer class {
nested class is one that has the static modifier applied. and may refer to them directly in the same way that other non- void display()
static members of the outer class do. {
System.out.println("display: outer_x = " + outer_x);
Because it is static, it must access the non-static members of its }
enclosing class through an object. }
}
Thank You
256
51
20ES3102B – JAVA PROGRAMMING
20ES3102B – JAVA PROGRAMMING
UNIT 2:
String Handling: The String Constructors, String Buffer Class, String
UNIT 2 Tokenizer class.
1 2 3
4 5 6
PACKAGES: INTERFACES:
1. Packages 4. Defining an Interface
2. Access Protection 5. Implementing Interfaces
3. Importing Packages 6. Nested Interfaces
7. Applying Interfaces
8. Variables in Interfaces
7 8 9
52
STRING HANDLING String Handling Somewhat unexpectedly, when you create a String object, you are
creating a string that cannot be changed.
In Java a string is a sequence of characters. But, unlike some other
1. The String Constructors languages that implement strings as character arrays, Java That is, once a String object has been created, you cannot change the
implements strings as objects of type String. characters that comprise that string. At first, this may seem to be a
2. String Buffer Class serious restriction.
Implementing strings as built-in objects allows Java to provide a
3. String Tokenizer class full complement of features that make string handling convenient.
However, such is not the case. You can still perform all types of
string operations.
For example, Java has methods to compare two strings, search for a
substring, concatenate two strings, and change the case of letters
within a string. The difference is that each time you need an altered version of an
existing string, a new String object is created that contains the
Also, String objects can be constructed a number of ways, making it modifications.
easy to obtain a string when needed.
10 11 12
The original string is left unchanged. This approach is used because This allows certain optimizations that increase performance to take 1. The String Constructors
fixed, immutable strings can be implemented more efficiently than place on common string operations. All three implement the
changeable ones. CharSequence interface.
The String class supports several constructors. To create an empty
String, call the default constructor. For example,
For those cases in which a modifiable string is desired, Java One last point: To say that the strings within objects of type String String s = new String();
provides two options: StringBuffer and StringBuilder. Both hold are unchangeable means that the contents of the String instance
will create an instance of String with no characters in it.
strings that can be modified after they are created. cannot be changed after it has been created.
Frequently, you will want to create strings that have initial values.
The String, StringBuffer, and StringBuilder classes are defined in However, a variable declared as a String reference can be changed to
java.lang. Thus, they are available to all programs automatically. point at some other String object at any time.
The String class provides a variety of constructors to handle this. To
create a String initialized by an array of characters, use the
All are declared final, which means that none of these classes may
constructor shown here:
be subclassed.
String(char chars[ ])
13 14 15
16 17 18
53
Even though Java’s char type uses 16 bits to represent the basic Unicode class SubStringCons Extended versions of the byte-to-string constructors are also defined
character set, the typical format for strings on the Internet uses arrays of { in which you can specify the character encoding that determines
8-bit bytes constructed from the ASCII character set. public static void main(String args[]) how bytes are converted to characters.
{
Because 8-bit ASCII strings are common, the String class provides byte ascii[] = {65, 66, 67, 68, 69, 70 };
constructors that initialize a string when given a byte array. However, you will often want to use the default encoding provided
by the platform.
String s1 = new String(ascii);
Two forms are shown here:
System.out.println(s1);
String(byte chrs[ ]) The contents of the array are copied whenever you create a String
String(byte chrs[ ], int startIndex, int numChars) object from an array.
String s2 = new String(ascii, 2, 3);
System.out.println(s2);
Here, chrs specifies the array of bytes. The second form allows you to
specify a subrange. } If you modify the contents of the array after you have created the
} string, the String will be unchanged.
In each of these constructors, the byte-to-character conversion is done by ABCDEF
using the default character encoding of the platform. CDE
19 20 21
You can construct a String from a StringBuffer by using the Method Call Task Performed Method Call Task Performed
constructor shown here:
s2=s1.toLowerCase Converts the string s1 to all lowercase String.valueOf(p) Creates a string object of the parameter p (simple type or
String(StringBuffer strBufObj) object)
s2=s1.toUpperCase Converts the string s1 to all uppercase
s2=s1.replace(‘X’,’y’) Replace all appearances of x with y p.toString() Creates a string representation of the object p
You can construct a String from a StringBuilder by using this s1.indexOf(‘x’) Gives the position of the first occurrence of ‘x’ in the
s2=s1.trim() Remove white spaces at the beginning and end of s1
constructor: string s1
s1.equals(s2) Returns ‘true’ if s1 is equal to s2
String(StringBuilder strBuildObj) s1.indexOf(‘x’,n) Gives the position of ‘x’ that occurs after nth position in
s1.equalsIgnoreCase(s2) Returns ‘true’ if s1=s2 ignoring the case of characters
the string s1
s1.length() Gives the length of s1
The following constructor supports the extended Unicode character String.valueOf(variable) Converts the parameter value to string representation
s1.charAt(n) Gives nth character of s1
set:
s1.compareTo(s2) Returns negative if s1<s2, positive if s1>s2, and zero if s1
String(int codePoints[ ], int startIndex, int numChars)
is equal s2
s1.concat(s2) Concatenates s1 and s2
Here, codePoints is an array that contains Unicode code points. The
s1.substring(n) Gives substring starting from nth character
resulting string is constructed from the range that begins at
startIndex and runs for numChars. s1.substring(n,m) Gives substring starting from nth character upto mth
(not including mth)
22 23 24
2. String Buffer Class StringBuffer Constructors StringBuffer allocates room for 16 additional characters when no
StringBuffer defines these four constructors: specific buffer length is requested, because reallocation is a costly
StringBuffer( ) process in terms of time.
StringBuffer supports a modifiable string. As you know, String
StringBuffer(int size)
represents fixed-length, immutable character sequences.
StringBuffer(String str)
Also, frequent reallocations can fragment memory. By allocating
StringBuffer(CharSequence chars)
room for a few extra characters, StringBuffer reduces the number of
In contrast, StringBuffer represents growable and writable
reallocations that take place.
character sequences. StringBuffer may have characters and The default constructor (the one with no parameters) reserves room for
substrings inserted in the middle or appended to the end. 16 characters without reallocation.
The fourth constructor creates an object that contains the character
StringBuffer will automatically grow to make room for such The second version accepts an integer argument that explicitly sets the sequence contained in chars and reserves room for 16 more
size of the buffer. characters.
additions and often has more characters pre-allocated than are
actually needed, to allow room for growth.
The third version accepts a String argument that sets the initial contents
of the StringBuffer object and reserves room for 16 more characters
without reallocation.
25 26 27
54
length( ) and capacity( ) class StringBufferDemo The output of this program shows how StringBuffer reserves extra
The current length of a StringBuffer can be found via the length( ) { space for additional manipulations.
method, while the total allocated capacity can be found through public static void main(String args[])
the capacity( ) method. { Since sb is initialized with the string "Hello" when it is created, its
StringBuffer sb = new StringBuffer("Hello"); length is 5.
They have the following general forms: System.out.println("buffer = " + sb);
int length( ) System.out.println("length = " + sb.length()); Its capacity is 21 because room for 16 additional characters is
int capacity( ) automatically added.
System.out.println("capacity = " + sb.capacity());
}
}
buffer = Hello
length = 5
capacity = 21
28 29 30
31 32 33
34 35 36
55
The array that will receive the characters is specified by target. insert( ) Here, index specifies the index at which point the string will be
The insert( ) method inserts one string into another. It is overloaded inserted into the invoking StringBuffer object.
The index within target at which the substring will be copied is to accept values of all the primitive types, plus Strings, Objects, and class InsertDemo
passed in targetStart. CharSequences. {
public static void main(String args[])
Care must be taken to assure that the target array is large enough to Like append( ), it obtains the string representation of the value it is
{
hold the number of characters in the specified substring. called with.
StringBuffer sb = new StringBuffer("I Java!");
This string is then inserted into the invoking StringBuffer object. sb.insert(2, "like ");
These are a few of its forms: System.out.println(sb);
StringBuffer insert(int index, String str) }
StringBuffer insert(int index, char ch) }
StringBuffer insert(int index, Object obj) I like Java!
37 38 39
40 41 42
class ReplaceDemo 3. String Tokenizer class To use StringTokenizer, you specify an input string and a string
{ that contains delimiters.
public static void main(String args[]) The processing of text often consists of parsing a formatted input
string. Delimiters are characters that separate tokens. Each character
{
StringBuffer sb = new StringBuffer("This is a test."); in the delimiters string is considered a valid delimiter—for
Parsing is the division of text into a set of discrete parts, or tokens, example, ",;:" sets the delimiters to a comma, semicolon, and
sb.replace(5, 7, "was"); which in a certain sequence can convey a semantic meaning. colon.
System.out.println("After replace: " + sb);
} The StringTokenizer class provides the first step in this parsing The default set of delimiters consists of the whitespace
} process, often called the lexer (lexical analyzer) or scanner. characters: space, tab, form feed, newline, and carriage return.
After replace: This was a test.
StringTokenizer implements the Enumeration interface. Therefore,
given an input string, you can enumerate the individual tokens
contained in it using StringTokenizer.
43 44 45
56
The StringTokenizer constructors are shown here: Once you have created a StringTokenizer object, the nextToken( ) import java.util.StringTokenizer;
class STDemo
StringTokenizer(String str) method is used to extract consecutive tokens.
{
StringTokenizer(String str, String delimiters) static String in = "title=Java: The Complete Reference;" +
StringTokenizer(String str, String delimiters, boolean delimAsToken) The hasMoreTokens( ) method returns true while there are more "author=Schildt;" +
"publisher=McGraw-Hill;" +
tokens to be extracted.
In all versions, str is the string that will be tokenized. In the first version, "copyright=2014";
the default delimiters are used. public static void main(String args[])
Since StringTokenizer implements Enumeration, the {
hasMoreElements( ) and nextElement( ) methods are also StringTokenizer st = new StringTokenizer(in, "=;");
In the second and third versions, delimiters is a string that specifies the while(st.hasMoreTokens())
delimiters. implemented, and they act the same as hasMoreTokens( ) and
{
nextToken( ), respectively. String key = st.nextToken();
In the third version, if delimAsToken is true, then the delimiters are also String val = st.nextToken();
returned as tokens when the string is parsed. Otherwise, the delimiters Here is an example that creates a StringTokenizer to parse System.out.println(key + "\t" + val);
are not returned. Delimiters are not returned as tokens by the first two }
forms. "key=value" pairs. Consecutive sets of "key=value" pairs are }
separated by a semicolon. }
46 47 48
Output:
title Java: The Complete Reference
INHERITANCE
author Schildt
publisher McGraw-Hill 1. Inheritance Basics
copyright 2014
2. Using super
3. Creating a Multilevel Hierarchy
Inheritance 4. Method Overriding
5. Dynamic Method Dispatch
6. Using Abstract Classes
7. Using final with Inheritance
49 50 51
Therefore, a subclass is a specialized version of a superclass. The following program creates a superclass called A and a subclass // Create a subclass by extending class A
called B. class B extends A
{
It inherits all of the members defined by the superclass and adds its int k;
own, unique elements.. Notice how the keyword extends is used to create a subclass of A. void showk()
{
System.out.println("k: " + k);
}
52 53 54
57
void sum() // The superclass may be used by itself Contents of superOb:
{ superOb.i = 10;
superOb.j = 20; i and j: 10 20
System.out.println("i+j+k: " + (i+j+k));
System.out.println("Contents of superOb: "); Contents of subOb:
} superOb.showij();
}
i and j: 7 8
System.out.println();
k: 9
class SimpleInheritance // The subclass has access to all public members of its superclass Sum of i, j and k in subOb:
subOb.i = 7;
{
subOb.j = 8;
i+j+k: 24
public static void main(String args []) subOb.k = 9;
{ System.out.println("Contents of subOb: ");
As you can see, the subclass B includes all of the members of its
A superOb = new A(); subOb.showij();
subOb.showk();
superclass, A.
B subOb = new B();
System.out.println();
System.out.println("Sum of i, j and k in subOb:"); This is why subOb can access i and j and call showij( ). Also, inside
subOb.sum();
sum( ), i and j can be referred to directly, as if they were part of B.
}
}
55 56 57
Member Access and Inheritance // In a class hierarchy, private members remain private to their class // A's j is not accessible here
class B extends A
Although a subclass includes all of the members of its superclass, it // This program contains an error and will not compile {
cannot access those members of the superclass that have been int total;
void sum()
declared as private. // Create a superclass
{
class A total = i + j; // ERROR, j is not accessible here
{ }
For example, consider the following simple class hierarchy: }
int i; // public by default
private int j; // private to A class Access
{
void setij(int x, int y)
public static void main(String args[])
{ {
i = x; B subOb = new B();
subOb.setij(10, 12);
j = y; subOb.sum();
} System.out.println("Total is " + subOb.total);
}
}
}
58 59 60
Access.java:22: error: j has private access in A A More Practical Example // construct clone of an object
Box(Box ob)
total = i + j; // ERROR, j is not accessible here Box class developed is extended to include a fourth component
{
^ called weight. // pass object to constructor
1 error width = ob.width;
Thus, the new class will contain a box’s width, height, depth, and height = ob.height;
weight. depth = ob.depth;
This program will not compile because the use of j inside the sum( ) }
method of B causes an access violation.
class Box // constructor used when all dimensions specified
Since j is declared as private, it is only accessible by other members { Box(double w, double h, double d)
{
of its own class. double width;
width = w;
double height; height = h;
Subclasses have no access to it. double depth; depth = d;
}
61 62 63
58
// constructor used when no dimensions specified // compute and return volume // constructor for BoxWeight
BoxWeight(double w, double h, double d, double m)
Box() double volume()
{
{ { width = w;
width = -1; // use -1 to indicate return width * height * depth; height = h;
depth = d;
height = -1; // an uninitialized }
weight = m;
depth = -1; // box } }
} }
// Here, Box is extended to include weight
class DemoBoxWeight
// constructor used when cube is created class BoxWeight extends Box {
Box(double len) { public static void main(String args[])
{ double weight; // weight of box {
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
width = height = depth = len;
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
} double vol;
64 65 66
vol = mybox1.volume();
2. Using Super Using super to Call Superclass Constructors
System.out.println("Volume of mybox1 is " + vol); A subclass can call a constructor defined by its superclass by use of
System.out.println("Weight of mybox1 is " + mybox1.weight); the following form of super:
Whenever a subclass needs to refer to its immediate superclass, it
System.out.println();
can do so by use of the keyword super. super(arg-list);
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol); super has two general forms. Here, arg-list specifies any arguments needed by the constructor in
System.out.println("Weight of mybox2 is " + mybox2.weight); the superclass.
} The first calls the superclass’ constructor.
} super( ) must always be the first statement executed inside a
Volume of mybox1 is 3000.0 subclass’ constructor.
The second is used to access a member of the superclass that has
Weight of mybox1 is 34.3
been hidden by a member of a subclass.
Volume of mybox2 is 24.0
Weight of mybox2 is 0.076
67 68 69
// BoxWeight now uses super to initialize its Box attributes In the preceding example, super( ) was called with three arguments. class Box
class BoxWeight extends Box Since constructors can be overloaded, super( ) can be called using {
any form defined by the superclass. private double width;
{
double weight; // weight of box private double height;
The constructor executed will be the one that matches the private double depth;
arguments.
// initialize width, height, and depth using super()
// construct clone of an object
BoxWeight(double w, double h, double d, double m) For example, here is a complete implementation of BoxWeight that
provides constructors for the various ways that a box can be Box(Box ob)
{ constructed. {
super(w, h, d); // call superclass constructor // pass object to constructor
weight = m; In each case, super( ) is called using the appropriate arguments. width = ob.width;
} height = ob.height;
} Notice that width, height, and depth have been made private within depth = ob.depth;
Box. }
70 71 72
59
// constructor used when all dimensions specified // constructor used when cube is created // BoxWeight now fully implements all constructors
Box(double w, double h, double d) Box(double len) class BoxWeight extends Box
{
{ {
width = w;
height = h; width = height = depth = len; double weight; // weight of box
depth = d; }
} // construct clone of an object
// compute and return volume BoxWeight(BoxWeight ob)
// constructor used when no dimensions specified
double volume() {
Box()
{ // pass object to constructor
{
width = -1; // use -1 to indicate return width * height * depth; super(ob);
height = -1; // an uninitialized } weight = ob.weight;
depth = -1; // box } }
}
73 74 75
// constructor when all parameters are specified // constructor used when cube is created vol = mybox1.volume();
BoxWeight(double len, double m)
BoxWeight(double w, double h, double d, double m) System.out.println("Volume of mybox1 is " + vol);
{
{ super(len); System.out.println("Weight of mybox1 is " + mybox1.weight);
weight = m; System.out.println();
super(w, h, d); // call superclass constructor
}
weight = m; }
vol = mybox2.volume();
}
class DemoSuper System.out.println("Volume of mybox2 is " + vol);
{ System.out.println("Weight of mybox2 is " + mybox2.weight);
// default constructor public static void main(String args[])
{ System.out.println();
BoxWeight()
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
{ BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076); vol = mybox3.volume();
super(); BoxWeight mybox3 = new BoxWeight(); // default
System.out.println("Volume of mybox3 is " + vol);
BoxWeight mycube = new BoxWeight(3, 2);
weight = -1; BoxWeight myclone = new BoxWeight(mybox1); System.out.println("Weight of mybox3 is " + mybox3.weight);
} double vol; System.out.println();
76 77 78
vol = myclone.volume(); Volume of mybox1 is 3000.0 Notice that super( ) is passed an object of type BoxWeight—not of type Box.
System.out.println("Volume of myclone is " + vol); Weight of mybox1 is 34.3 This still invokes the constructor Box(Box ob).
System.out.println("Weight of myclone is " + myclone.weight);
System.out.println(); Volume of mybox2 is 24.0 As mentioned earlier, a superclass variable can be used to reference any
Weight of mybox2 is 0.076 object derived from that class. Thus, we are able to pass a BoxWeight object
to the Box constructor. Of course, Box only has knowledge of its own
vol = mycube.volume(); members.
System.out.println("Volume of mycube is " + vol); Volume of mybox3 is -1.0
System.out.println("Weight of mycube is " + mycube.weight); Weight of mybox3 is -1.0 Let’s review the key concepts behind super( ). When a subclass calls super( ),
System.out.println(); it is calling the constructor of its immediate superclass.
} Volume of myclone is 3000.0
} Weight of myclone is 34.3 Thus, super( ) always refers to the superclass immediately above the calling
class. This is true even in a multileveled hierarchy.
Volume of mycube is 27.0
Weight of mycube is 2.0 Also, super( ) must always be the first statement executed inside a subclass
constructor.
79 80 81
60
A Second Use for super // Using super to overcome name hiding void show()
The second form of super acts somewhat like this, except that it class A {
always refers to the superclass of the subclass in which it is used. { System.out.println("i in superclass: " + super.i);
int i; System.out.println("i in subclass: " + i);
}
This usage has the following general form: }
}
super.member
// Create a subclass by extending class A class UseSuper
class B extends A {
Here, member can be either a method or an instance variable.
{ public static void main(String args[])
int i; // this i hides the i in A {
This second form of super is most applicable to situations in which B subOb = new B(1, 2);
B(int a, int b)
member names of a subclass hide members by the same name in the
{ subOb.show();
superclass.
super.i = a; // i in A }
i = b; // i in B }
Consider this simple class hierarchy: i in superclass: 1
}
i in subclass: 2
82 83 84
Single Inheritance
Although the instance variable i in B hides the i in A, super allows Types of Inheritance class A
access to the i defined in the superclass.
{
public void methodA()
As you will see, super can also be used to call methods that are {
hidden by a subclass. System.out.println("Base or Parent class method");
}
}
class B extends A
{
public void methodB()
{
System.out.println("Derived or Child class method");
}
}
85 86 87
88 89 90
61
Hierarchical Inheritance class C extends A System.out.println("Calling for child class C");
class A {
void DisplayC() C c = new C();
{
{ c.DisplayA();
void DisplayA() System.out.println("This is a content of child class 2");
{ c.DisplayC();
}
System.out.println("This is a content of parent class"); }
}
} }
class HierarchicalIn
{ }
public static void main(String args[])
class B extends A Calling for child class B
{
{ System.out.println("Calling for child class B"); This is a content of parent class
void DisplayB() B b = new B(); This is a content of child class 1
b.DisplayA();
{
b.DisplayB();
System.out.println("This is a content of child class 1"); Calling for child class C
} System.out.println();
This is a content of parent class
}
This is a content of child class 2
91 92 93
94 95 96
3. Creating Multilevel Hierarchy When Constructors Are Executed Further, since super( ) must be the first statement executed in a
When a class hierarchy is created, in what order are the constructors subclass constructor, this order is the same whether or not super( ) is
for the classes that make up the hierarchy executed? used.
It is perfectly acceptable to use a subclass as a superclass of another. For
example, given three classes called A, B, and C, C can be a subclass of B,
which is a subclass of A. If super( ) is not used, then the default or parameterless constructor
For example, given a subclass called B and a superclass called A, is
A’s constructor executed before B’s, or vice versa? of each superclass will be executed.
When this type of situation occurs, each subclass inherits all of the traits
found in all of its superclasses. In this case, C inherits all aspects of B and
A. The answer is that in a class hierarchy, constructors complete their Refer DemoShipment.java
execution in order of derivation, from superclass to subclass.
To see how a multilevel hierarchy can be useful, consider the following
program. In it, the subclass BoxWeight is used as a superclass to create
the subclass called Shipment.
Shipment inherits all of the traits of BoxWeight and Box, and adds a field
called cost, which holds the cost of shipping such a parcel.
97 98 99
62
4. Method Overriding No. Method Overloading Method Overriding Java Method Overloading
1 Method overloading is used to increase Method overriding is used to provide the class OverloadingExample
In a class hierarchy, when a method in a subclass has the same the readability of the program. specific implementation of the method that {
name and type signature as a method in its superclass, then the is already provided by its super class.
static int add(int a,int b)
method in the subclass is said to override the method in the 2 Method overloading is performed Method overriding occurs in two classes {
superclass. within class. that have IS-A (inheritance) relationship.
return a+b;
3 In case of method overloading, In case of method overriding, parameter }
When an overridden method is called from within its subclass, it parameter must be different. must be same.
will always refer to the version of that method defined by the static int add(int a,int b,int c)
4 Method overloading is the example of Method overriding is the example of run
subclass. compile time polymorphism. time polymorphism. {
5 In java, method overloading can't be Return type must be same or covariant in return a+b+c;
performed by changing return type of method overriding. }
The version of the method defined by the superclass will be
the method only. Return type can be same
hidden. or different in method overloading. But }
you must have to change the parameter.
Java Method Overriding Real example of Java Method Overriding class Bank
class Animal {
{ int getRateOfInterest()
void eat() {
{ return 0;
System.out.println("eating..."); }
} }
}
class Dog extends Animal class SBI extends Bank
{ {
void eat() int getRateOfInterest()
{ {
System.out.println("eating bread..."); return 8;
}
}
}
}
A r; // obtain a reference of type A This program creates one superclass called A and two subclasses of it, class A
called B and C. {
r = a; // r refers to an A object void display()
r.callme(); // calls A's version of callme Subclasses B and C override callme( ) declared in A. Inside the main( ) {
method, objects of type A, B, and C are declared. Also, a reference of type System.out.println("Displaying from class A");
r = b; // r refers to a B object A, called r, is declared. }
r.callme(); // calls B's version of callme }
The program then in turn assigns a reference to each type of object to r
r = c; // r refers to a C object and uses that reference to invoke callme( ). class B extends A
r.callme(); // calls C's version of callme {
} As the output shows, the version of callme( ) executed is determined by public void display()
} the type of object being referred to at the time of the call. {
Inside A's callme method System.out.println("Displaying from class B");
Inside B's callme method Had it been determined by the type of the reference variable, r, you }
Inside C's callme method would see three calls to A’s callme( ) method. }
There can be no objects of an abstract class. abstract class Figure class Rectangle extends Figure
{ {
That is, an abstract class cannot be directly instantiated with the double dim1; Rectangle(double a, double b)
new operator. {
double dim2;
super(a, b);
Figure(double a, double b)
Such objects would be useless, because an abstract class is not fully }
{
defined. dim1 = a; // override area for rectangle
dim2 = b; double area()
Also, you cannot declare abstract constructors, or abstract static }
methods. {
System.out.println("Inside Area for Rectangle.");
// area is now an abstract method return dim1 * dim2;
Any subclass of an abstract class must either implement all of the
abstract double area(); }
abstract methods in the superclass, or be declared abstract itself.
} }
class Triangle extends Figure class AbstractAreas Inside Area for Rectangle.
{ { Area is 45.0
Triangle(double a, double b) public static void main(String args[]) Inside Area for Triangle.
{ {
Area is 40.0
super(a, b); // Figure f = new Figure(10, 10); // illegal now
} Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
// override area for right triangle Figure figref; // this is OK, no object is created
double area() figref = r;
{ System.out.println("Area is " + figref.area());
System.out.println("Inside Area for Triangle."); figref = t;
return dim1 * dim2 / 2; System.out.println("Area is " + figref.area());
} }
} }
Declaring a class as final implicitly declares all of its methods as // The following class is illegal.
final, too. class B extends A
{
Packages and Interfaces
As you might expect, it is illegal to declare a class as both abstract // ERROR! Can't subclass A
and final since an abstract class is incomplete by itself and relies //...
upon its subclasses to provide complete implementations.
}
As the comments imply, it is illegal for B to inherit A since A is
declared as final.
2. Access Protection 5. Implementing Interfaces After a while, without some way to manage the name space, you
could run out of convenient, descriptive names for individual
3. Importing Packages 6. Nested Interfaces classes.
7. Applying Interfaces
You also need some way to be assured that the name you choose
8. Variables in Interfaces for a class will be reasonably unique and not collide with class
names chosen by other programmers.
Finding Packages and CLASSPATH Second, you can specify a directory path or paths by setting the When the second two options are used, the class path must not
As just explained, packages are mirrored by directories. This raises CLASSPATH environmental variable. include mypack, itself.
an important question: How does the Java run-time system know
where to look for packages that you create? Third, you can use the -classpath option with java and javac to specify It must simply specify the path to mypack. For example, in a
the path to your classes. Windows environment, if the path to mypack is
The answer has three parts. C:\MyPrograms\Java\mypack
For example, consider the following package specification:
then the class path to mypack is
package mypack
First, by default, the Java run-time system uses the current working C:\MyPrograms\Java
directory as its starting point.
In order for a program to find MyPack, one of three things must be true.
The easiest way is to simply create the package directories below
Thus, if your package is in a subdirectory of the current directory, it your current development directory, put the .class files into the
Either the program can be executed from a directory immediately above
will be found. appropriate directories, and then execute the programs from the
myPack, or the CLASSPATH must be set to include the path to mypack,
or the -classpath option must specify the path to mypack when the development directory.
program is run via java.
package mypack; class AccountBalance Compile the file. Make sure that the resulting .class file is also in the
class Balance
{ mypack directory.
{
String name; public static void main(String args[])
Then, try executing the AccountBalance class, using the following
double bal; { command line:
Balance(String n, double b) Balance current[] = new Balance[3];
{
java mypack.AccountBalance
name = n; current[0] = new Balance("K. J. Fielding", 123.23);
bal = b; current[1] = new Balance("Will Tell", 157.02); Remember, you will need to be in the directory above mypack when you
} current[2] = new Balance("Tom Jackson", -12.33); execute this command.
A non-nested class has only two possible access levels: default and Compiling and Running the files in p1 package
public.
C:\Users\Prabu\Desktop>javac ./p1/Demo.java
When a class is declared as public, it is accessible by any other C:\Users\Prabu\Desktop>java p1.Demo
code.
3. Importing Packages Here, pkg1 is the name of a top-level package, and pkg2 is the All of the standard Java classes included with Java are stored in a
name of a subordinate package inside the outer package separated package called java.
Java includes the import statement to bring certain classes, or entire by a dot (.).
packages, into visibility. Once imported, a class can be referred to The basic language functions are stored in a package inside of the
directly, using only its name. There is no practical limit on the depth of a package hierarchy, java package called java.lang.
except that imposed by the file system.
In a Java source file, import statements occur immediately Normally, you have to import every package or class that you want
following the package statement (if it exists) and before any class Finally, you specify either an explicit classname or a star (*), which to use, but since Java is useless without much of the functionality in
definitions. indicates that the Java compiler should import the entire package. java.lang, it is implicitly imported by the compiler for all programs.
This is the general form of the import statement: This code fragment shows both forms in use:
import pkg1 [.pkg2].(classname | *); import java.util.Date;
import java.io.*;
5. Implementing Interfaces If a class implements more than one interface, the interfaces are
separated with a comma.
Here is a small example class that implements the Callback interface
shown earlier:
Once an interface has been defined, one or more classes can implement
that interface. If a class implements two interfaces that declare the same method, class Client implements Callback
then the same method will be used by clients of either interface. {
To implement an interface, include the implements clause in a class // Implement Callback's interface
definition, and then create the methods required by the interface.
The methods that implement an interface must be declared public. public void callback(int p)
The general form of a class that includes the implements clause looks {
like this: Also, the type signature of the implementing method must match System.out.println("callback called with " + p);
exactly the type signature specified in the interface definition. }
class classname [extends superclass] [implements interface [,interface...]]
}
{
// class-body
} Notice that callback( ) is declared using the public access modifier
class NestedIFDemo
7. Applying Interfaces interface IDemo
{ {
public static void main(String args[]) In Java 9 version, a new feature is added that allows us to declare // Default method
{ private methods inside the interface. default void msg()
// use a nested interface reference {
A.NestedIF nif = new B(); greet();
The purpose of private method is just to share some task between
}
if(nif.isNotNegative(10)) the non-abstract methods of the interface.
System.out.println("10 is not negative");
// Private method
if(nif.isNotNegative(-12)) An interface IDemo is created that has a default method and a
private void greet()
System.out.println("this won't be displayed"); private method as well. Since private methods are not accessible
outside to interface. So, it is called from the default method. {
} System.out.println("This is private method");
} }
10 is not negative }
}
}
Thank You
Later
Soon
No
Yes
1 2 3
4 5 6
1. Exception-Handling Fundamentals Exceptions thrown by Java relate to fundamental errors that violate If an exception occurs within the try block, it is thrown.
the rules of the Java language or the constraints of the Java
A Java exception is an object that describes an exceptional (that is, execution environment. Your code can catch this exception (using catch) and handle it in
error) condition that has occurred in a piece of code. some rational manner.
Manually generated exceptions are typically used to report some
When an exceptional condition arises, an object representing that error condition to the caller of a method. System-generated exceptions are automatically thrown by the Java
exception is created and thrown in the method that caused the
error. runtime system.
Java exception handling is managed via five keywords: try, catch,
throw, throws, and finally. To manually throw an exception, use the keyword throw. Any
That method may choose to handle the exception itself or pass it
on. Either way, at some point, the exception is caught and exception that is thrown out of a method must be specified as such
processed. Program statements that you want to monitor for exceptions are by a throws clause.
contained within a try block.
Exceptions can be generated by the Java run-time system, or they Any code that absolutely must be executed after a try block
can be manually generated by your code completes is put in a finally block.
7 8 9
73
This is the general form of an exception-handling block:
2. Exception Types There is an important subclass of Exception, called
try RuntimeException.
{ All exception types are subclasses of the built-in class Throwable.
// block of code to monitor for errors
} Thus, Throwable is at the top of the exception class hierarchy. Exceptions of this type are automatically defined for the programs
catch (ExceptionType1 exOb) that you write and include things such as division by zero and
{
// exception handler for ExceptionType1 Immediately below Throwable are two subclasses that partition invalid array indexing.
} exceptions into two distinct branches. One branch is headed by
catch (ExceptionType2 exOb) Exception.
{
The other branch is topped by Error, which defines exceptions that
// exception handler for ExceptionType2 are not expected to be caught under normal circumstances by your
} This class is used for exceptional conditions that user programs program.
// ...
should catch.
finally Exceptions of type Error are used by the Java run-time system to
{
This is also the class that you will subclass to create your own indicate errors having to do with the run-time environment, itself.
// block of code to be executed after try block ends
} custom exception types. Stack overflow is an example of such an error.
10 11 12
When the Java run-time system detects the attempt to divide by zero, it
3. Uncaught Exceptions constructs a new exception object and then throws this exception.
This small program includes an expression that intentionally This causes the execution of Exc0 to stop, because once an exception has
causes a divide-by-zero error: been thrown, it must be caught by an exception handler and dealt with
class Exc0 immediately.
{
In this example, we haven’t supplied any exception handlers of our own,
public static void main(String args[]) so the exception is caught by the default handler provided by the Java run-
{ time system.
int d = 0;
Any exception that is not caught by your program will ultimately be
int a = 42 / d; processed by the default handler.
}
} The default handler displays a string describing the exception, prints a
stack trace from the point at which the exception occurred, and terminates
the program.
13 14 15
Here is the exception generated when this example is executed: 4. Using try and catch class Exc2
java.lang.ArithmeticException: / by zero {
at Exc0.main(Exc0.java:4) Although the default exception handler provided by the Java run- public static void main(String args[])
time system is useful for debugging, you will usually want to {
handle an exception yourself. int d, a;
Doing so provides two benefits. First, it allows you to fix the error. // monitor a block of code
Second, it prevents the program from automatically terminating.
try
{
To handle a run-time error, simply enclose the code that you want
to monitor inside a try block. d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
Immediately following the try block, include a catch clause that
specifies the exception type that you wish to catch. }
16 17 18
74
// catch divide-by-zero error A try and its catch statement form a unit. Java Random Class Methods
catch (ArithmeticException e) nextBoolean() - This method returns next pseudorandom which is a
{ The scope of the catch clause is restricted to those statements boolean value from random number generator sequence.
System.out.println("Division by zero."); specified by the immediately preceding try statement.
} nextDouble() - his method returns next pseudorandom which is double
value between 0.0 and 1.0.
A catch statement cannot catch an exception thrown by another try
System.out.println("After catch statement."); statement (except in the case of nested try statements, described
} shortly). nextFloat() - This method returns next pseudorandom which is float value
} between 0.0 and 1.0.
Once an exception is thrown, program control transfers out of the try nextInt(int n) - This method return a pseudorandom which is int value
block into the catch block. between 0 and specified value from random number generator sequence.
19 20 21
22 23 24
25 26 27
75
In the next program each iteration of the for loop obtains two Displaying a Description of an Exception import java.util.Random;
random integers. class HandleErrorDescription
Throwable overrides the toString( ) method (defined by Object) so
{
that it returns a string containing a description of the exception.
public static void main(String args[])
Those two integers are divided by each other, and the result is used
{
to divide the value 12345.
You can display this description in a println( ) statement by simply int a=0, b=0, c=0;
passing the exception as an argument. Random r = new Random();
The final result is put into a. If either division operation causes a for(int i=0; i<10; i++)
divide-by-zero error, it is caught, the value of a is set to zero, and {
the program continues. try
{
b = r.nextInt();
c = r.nextInt();
a = 12345 / (b/c);
}
28 29 30
31 32 33
34 35 36
76
6. throw, throws, finally Here, ThrowableInstance must be an object of type Throwable or a
The nearest enclosing try block is inspected to see if it has a catch
subclass of Throwable.
statement that matches the type of exception.
throw
So far, you have only been catching exceptions that are thrown by Primitive types, such as int or char, as well as non-Throwable
If it does find a match, control is transferred to that statement.
the Java run-time system. classes, such as String and Object, cannot be used as exceptions.
If not, then the next enclosing try statement is inspected, and so on.
However, it is possible for your program to throw an exception There are two ways you can obtain a Throwable object: using a
explicitly, using the throw statement. The general form of throw is parameter in a catch clause or creating one with the new operator.
shown here: If no matching catch is found, then the default exception handler
halts the program and prints the stack trace.
throw ThrowableInstance; The flow of execution stops immediately after the throw statement;
any subsequent statements are not executed.
37 38 39
40 41 42
import java.io.*; public static void main(String[] args) Differences between throw and throws
class TestThrows {
try
{
{
public static void findFile() throws IOException findFile();
{ }
// code that may produce IOException catch(IOException e)
File newFile=new File("test.txt"); {
System.out.println(e);
FileInputStream stream=new FileInputStream(newFile);
}
}
}
}
43 44 45
77
finally This can be useful for closing file handles and freeing up any other public class TestFinally
finally creates a block of code that will be executed after a try /catch resources that might have been allocated at the beginning of a {
block has completed and before the code following the try/catch method with the intent of disposing of them before returning. public static void main(String args[])
block.
{
The finally clause is optional. However, each try statement requires try
The finally block will execute whether or not an exception is thrown. at least one catch or a finally clause.
{
int data=25/0;
If an exception is thrown, the finally block will execute even if no
System.out.println(data);
catch statement matches the exception.
}
catch(ArithmeticException e)
Any time a method is about to return to the caller from inside a
try/catch block, via an uncaught exception or an explicit return {
statement, the finally clause is also executed just before the method System.out.println(e);
returns. }
46 47 48
finally 7. Creating Your Own Exception Subclasses The Exception class does not define any methods of its own. It
does, of course, inherit those methods provided by Throwable.
{
System.out.println("finally block is always executed"); Although Java’s built-in exceptions handle most common errors,
Thus, all exceptions, including those that you create, have the
you will probably want to create your own exception types to
} methods defined by Throwable available to them.
handle situations specific to your applications.
System.out.println("rest of the code...");
} You may also wish to override one or more of these methods in
This is quite easy to do: just define a subclass of Exception (which exception classes that you create.
} is, of course, a subclass of Throwable).
Exception defines four public constructors. Two support chained
java.lang.ArithmeticException: / by zero Your subclasses don’t need to actually implement anything—it is exceptions, described in the next section. The other two are shown
finally block is always executed their existence in the type system that allows you to use them as here:
rest of the code... exceptions. Exception( )
Exception(String msg)
49 50 51
52 53 54
78
class MyException extends Exception class ExceptionDemo public static void main(String args[])
{ { {
private int detail; static void compute(int a) throws MyException try
{ {
MyException(int a)
System.out.println("Called compute(" + a + ")"); compute(1);
{
compute(20);
detail = a;
} if(a > 10) }
throw new MyException(a); catch (MyException e)
public String toString() {
{ System.out.println("Normal exit"); System.out.println("Caught " + e);
return "MyException[" + detail + "]"; } }
} }
} }
55 56 57
These two constructors have also been added to the Error, Exception, Thus, you can associate a cause with an exception after the
and RuntimeException classes. exception has been created.
58 59 60
However, the cause exception can be set only once. class ChainExcDemo public static void main(String args[])
{
{
try
Thus, you can call initCause( ) only once for each exception object. static void demoproc() {
{ demoproc();
Furthermore, if the cause exception was set by a constructor, then // create an exception }
catch(NullPointerException e)
you can’t set it again using initCause( ). NullPointerException e = new NullPointerException("top layer"); {
// display top level exception
In general, initCause( ) is used to set a cause for legacy exception // add a cause System.out.println("Caught: " + e);
classes that don’t support the two additional constructors described e.initCause(new ArithmeticException("cause"));
earlier. // display cause exception
throw e; System.out.println("Original cause: " +e.getCause());
} }
}
}
61 62 63
79
Multi-catch Features To use a multi-catch, separate each exception type in the catch
Caught: java.lang.NullPointerException: top layer The multi-catch feature allows two or more exceptions to be caught clause with the OR operator.
Original cause: java.lang.ArithmeticException: cause by the same catch clause.
Each multi-catch parameter is implicitly final. (You can explicitly
It is not uncommon for two or more exception handlers to use the specify final, if desired, but it is not necessary.)
same code sequence even though they respond to different
exceptions. Because each multi-catch parameter is implicitly final, it can’t be
assigned a new value.
Instead of having to catch each exception type individually, you can
use a single catch clause to handle all of the exceptions without
code duplication.
64 65 66
67 68 69
Overview of I/O Streams No matter how they work internally, all streams present the same A program uses an output stream to write data to a destination, one
simple model to programs that use them: A stream is a sequence of item at time:
data.
An I/O Stream represents an input source or an output destination.
70 71 72
80
Buffered Streams:
What is a Stream? Different Types of I/O Streams Buffered input streams read data from a memory area known as a
buffer; the native input API is called only when the buffer is empty.
Abstraction that consumes or produces information Byte Streams: Similarly, buffered output streams write data to a buffer, and the native
They provide a convenient means for handling input and output of output API is called only when the buffer is full.
Linked to source and destination bytes.
Data Streams:
Programs use byte streams to perform input and output of 8-bit
Data streams support binary I/O of primitive data type values (Boolean,
Implemented within class hierarchies defined in java.io package bytes. char, byte, short, int, long, float, and double) as well as String values.
All byte stream classes descend from InputStream and
OutputStream class. Object Streams:
An input stream acts as a source of data
Just as data streams support I/O of primitive data types, object streams
Character Streams: support I/O of objects.
An output stream acts as a destination of data
They provide a convenient means for handling input and output of
Scanning and Formatting:
characters.
It allows a program to read and write formatted text.
They use Unicode and therefore, can be internationalized.
73 74 75
out and err are objects of type PrintStream class and in is an object
of the InputStream class.
76 77 78
Java’s stream-based I/O is built upon four abstract classes: The byte stream classes provide a rich environment for handling InputStream is an abstract class that defines Java’s model of
InputStream, OutputStream, Reader, and Writer. byte-oriented I/O. streaming byte input.
InputStream and OutputStream are designed for byte streams. A byte stream can be used with any type of object, including binary It implements the AutoCloseable and Closeable interfaces.
Reader and Writer are designed for character streams. data.
Most of the methods in this class will throw an IOException when
The byte stream classes and the character stream classes form This versatility makes byte streams important to many types of an I/O error occurs. (The exceptions are mark( ) and
separate hierarchies. programs. markSupported( ).)
In general, you should use the character stream classes when The methods in InputStream is shown in the table
working with characters or strings and use the byte stream classes
when working with bytes or other binary objects.
79 80 81
81
OutputStream
Most of the methods defined by this class return void and throw an
IOException in the case of I/O errors.
82 83 84
FileInputStream
The FileInputStream class creates an InputStream that you can use
to read bytes from a file.
85 86 87
The FileInputStream class of the java.io package can be used to read Create a FileInputStream 2. Using an object of the file
data (in bytes) from files. In order to create a file input stream, we must import the FileInputStream input = new FileInputStream(File fileObject);
java.io.FileInputStream package first.
It extends the InputStream abstract class. Here, we have created an input stream that will be linked to the file
Once we import the package, here is how we can create a file input specified by fileObject.
stream in Java.
Methods of FileInputStream
1. Using the path to file read() - reads a single byte from the file
FileInputStream input = new FileInputStream(stringPath); read(byte[] array) - reads the bytes from the file and stores in the
specified array
Here, we have created an input stream that will be linked to the file read(byte[] array, int start, int length) - reads the number of bytes
specified by the path. equal to length from the file and stores in the specified array
starting from the position start
88 89 90
82
import java.io.*; input.close(); available() Method
public class FIS
} To get the number of available bytes, we can use the available() method.
{
public static void main(String args[])
{ import java.io.*;
try catch(IOException e) public class AvailableExample
{
FileInputStream input = new FileInputStream("Sample.txt");
{ {
System.out.println("Data in the file: "); System.out.println("Error:" +e); public static void main(String args[])
} {
// Reads the first byte
int i = input.read(); } try
while(i != -1) {
{
}
FileInputStream input = new FileInputStream("Sample.txt");
System.out.print((char)i);
// Reads next byte from the file Data in the file: // Returns the number of available bytes
i = input.read(); Hello World System.out.println("Available bytes at the beginning: " +
} input.available());
91 92 93
// Reads 2 bytes from the file skip() Method // Reads the first byte
input.read(); To discard and skip the specified number of bytes, we can use the skip() int i = input.read();
input.read(); method. while (i != -1)
{
// Returns the number of available bytes import java.io.*; System.out.print((char) i);
System.out.println("Available bytes at the end: " + input.available());
public class SkipExample // Reads next byte from the file
{ i = input.read();
input.close();
} public static void main(String args[]) }
{
catch (Exception e) try input.close();
{ { }
System.out.println("Error:" +e); FileInputStream input = new FileInputStream("Sample.txt"); catch (Exception e)
} {
} // Skips the 2 bytes System.out.println("Error:" +e);
} input.skip(2); }
Available bytes at the beginning: 11 System.out.println("Input stream after skipping 2 bytes:"); }
Available bytes at the end: 9 }
94 95 96
97 98 99
83
The FileOutputStream class of the java.io package can be used to Create a FileOutputStream Here, we have created an output stream that will be linked to the
write data (in bytes) to the files. In order to create a file output stream, we must import the file specified by the path.
java.io.FileOutputStream package first.
It extends the OutputStream abstract class. Also, value is an optional boolean parameter.
Once we import the package, here is how we can create a file
output stream in Java.
If it is set to true, the new data will be appended to the end of the
1. Using the path to file existing data in the file.
// Including the boolean parameter
FileOutputStream output = new FileOutputStream(String path, Otherwise, the new data overwrites the existing data in the file.
boolean value);
Now, the objStream can be used to read objects from the file.
The ObjectOutputStream class only writes those objects that // Creates the ObjectOutputStream
implement the Serializable interface. This is because objects need to
be serialized while writing to the stream. ObjectOutputStream objStream = new ObjectOutputStream(fileStream);
Create a BufferedInputStream // Creates a BufferedInputStream with specified size internal buffer Methods of BufferedInputStream
In order to create a BufferedInputStream, we must import the BufferedInputStream buffer = new BufferInputStream(file, int size); The BufferedInputStream class provides implementations for
java.io.BufferedInputStream package first. different methods present in the InputStream class.
The buffer will help to read bytes from the files more quickly.
// Creates a FileInputStream read() Method
FileInputStream file = new FileInputStream(String path); read() - reads a single byte from the input stream
read(byte[] arr) - reads bytes from the stream and stores in the
// Creates a BufferedInputStream specified array
BufferedInputStream buffer = new BufferInputStream(file); read(byte[] arr, int start, int length) - reads the number of bytes equal
to the length from the stream and stores in the specified array starting
from the position start
A BufferdInputStream named buffer with the FileInputStream
named file.
Here, the internal buffer has the default size of 8192 bytes. However,
we can specify the size of the internal buffer as well.
PrintStream Create a PrintStream Here, we have created a print stream that will write formatted data
The PrintStream class of the java.io package can be used to write In order to create a PrintStream, we must import the to the file represented by FileOutputStream
output data in commonly readable form (text) instead of bytes. java.io.PrintStream package first.
the autoFlush is an optional boolean parameter that specifies
It extends the abstract class OutputStream. 1. Using other output streams whether to perform auto flushing or not.
// Creates a FileOutputStream
FileOutputStream file = new FileOutputStream(String file); 2. Using filename
// Creates a PrintStream
// Creates a PrintStream PrintStream output = new PrintStream(String file, boolean autoFlush);
PrintStream output = new PrintStream(file, autoFlush);
We have created a print stream that will write formatted data to the
specified file.
autoFlush is an optional boolean parameter that specifies whether to
perform autoflush or not.
Methods of PrintStream Example: print() method with System class Example: print() method with System class
The PrintStream class provides various methods that allow us to print class Main class Main
data to the output. { {
public static void main(String[] args) public static void main(String[] args)
print() Method { {
print() - prints the specified data to the output stream String data = "Hello World."; String data = "Hello World.";
println() - prints the data to the output stream along with a new line System.out.print(data); System.out.print(data);
character at the end } }
} }
Reader input = new FileReader("ReaderInput.txt"); This line is printed from the ReaderInput File.
The InputStreamReader class works with other input streams. It is Create an InputStreamReader Methods of InputStreamReader
also known as a bridge between byte streams and character streams. In order to create an InputStreamReader, we must import the The InputStreamReader class provides implementations for different
java.io.InputStreamReader package first. methods present in the Reader class.
This is because the InputStreamReader reads bytes from the input
stream as characters. // Creates an InputStream read() Method
FileInputStream file = new FileInputStream(String path); read() - reads a single character from the reader
For example, some characters required 2 bytes to be stored in the read(char[] array) - reads the characters from the reader and stores in
storage. // Creates an InputStreamReader the specified array
InputStreamReader input = new InputStreamReader(file); read(char[] array, int start, int length) - reads the number of characters
To read such data we can use the input stream reader that reads the equal to length from the reader and stores in the specified array
2 bytes together and converts into the corresponding character. starting from the start
OutputStreamWriter The OutputStreamWriter class works with other output streams. It is Create an OutputStreamWriter
The OutputStreamWriter class of the java.io package can be used to also known as a bridge between byte streams and character streams. In order to create an OutputStreamWriter, we must import the
convert data in character form into data in bytes form. java.io.OutputStreamWriter package first.
This is because the OutputStreamWriter converts its characters into
It extends the abstract class Writer. bytes. // Creates an OutputStream
FileOutputStream file = new FileOutputStream(String path);
For example, some characters require 2 bytes to be stored in the
storage. // Creates an OutputStreamWriter
OutputStreamWriter output = new OutputStreamWriter(file);
To write such data we can use the output stream writer that converts
the character into corresponding bytes and stores the bytes together.
import java.io.StringWriter; // Prints the string writer Access Data from StringBuffer
public class StringWriterEx System.out.println("Data in the StringWriter: " + output); getBuffer() - returns the data present in the string buffer
{ output.close(); toString() - returns the data present in the string buffer as a string
public static void main(String[] args) }
{ catch(Exception e)
String data = "This is the text in the string."; {
try e.getStackTrace();
{ }
// Create a StringWriter with default string buffer capacity }
StringWriter output = new StringWriter(); }
Data in the StringWriter: This is the text in the string.
// Writes data to the string buffer
output.write(data);
catch(Exception e)
MULTITHREADED PROGRAMMING Multithreaded Programming
{
e.getStackTrace(); Java provides built-in support for multithreaded programming. A
1. The Java Thread Model
} multithreaded program contains two or more parts that can run
} 2. Creating a Thread concurrently.
} Implementing Runnable
Extending Thread Each part of such a program is called a thread, and each thread
defines a separate path of execution. Thus, multithreading is a
3. Creating Multiple Threads specialized form of multitasking.
4. Thread Priorities
5. Synchronization You are almost certainly acquainted with multitasking because it is
Using Synchronized methods supported by virtually all modern operating systems. However,
there are two distinct types of multitasking: process-based and
The synchronized Statement thread-based.
Multithreading enables you to write efficient programs that make In a single-threaded environment, your program has to wait for 1. The Java Thread Model
maximum use of the processing power available in the system. each of these tasks to finish before it can proceed to the next one—
even though most of the time the program is idle, waiting for input.
The Java run-time system depends on threads for many things, and
One important way multithreading achieves this is by keeping idle all the class libraries are designed with multithreading in mind.
time to a minimum. This is especially important for the interactive, Multithreading helps you reduce this idle time because another
networked environment in which Java operates because idle time is thread can run when one is waiting.
common. The value of a multithreaded environment is best understood in
contrast to its counterpart.
Once this polling mechanism returns with, say, a signal that a The benefit of Java’s multithreading is that the main loop/polling Threads exist in several states. Here is a general description. A
network file is ready to be read, then the event loop dispatches mechanism is eliminated. thread can be running.
control to the appropriate event handler.
One thread can pause without stopping other parts of your It can be ready to run as soon as it gets CPU time. A running thread
Until this event handler returns, nothing else can happen in the program. For example, the idle time created when a thread reads can be suspended, which temporarily halts its activity.
program. This wastes CPU time. data from a network or waits for user input can be utilized
elsewhere. A suspended thread can then be resumed, allowing it to pick up
It can also result in one part of a program dominating the system where it left off. A thread can be blocked when waiting for a
and preventing any other events from being processed. Multithreading allows animation loops to sleep for a second resource.
between each frame without causing the whole system to pause.
In general, in a single-threaded environment, when a thread blocks At any time, a thread can be terminated, which halts its execution
(that is, suspends execution) because it is waiting for some When a thread blocks in a Java program, only the single thread that immediately. Once terminated, a thread cannot be resumed.
resource, the entire program stops running. is blocked pauses. All other threads continue to run.
try Output: In this program, a reference to the current thread (the main thread, in
{ Current thread: Thread[main,5,main] this case) is obtained by calling currentThread( ), and this reference is
for(int n = 6; n > 0; n--) After name change: Thread[My Thread,5,main] stored in the local variable t.
{ 6
System.out.println(n); Next, the program displays information about the thread. The
5
Thread.sleep(1000); program then calls setName( ) to change the internal name of the
4 thread.
}
} 3
catch (InterruptedException e) 2 Information about the thread is then redisplayed. Next, a loop counts
{ 1 down from five, pausing one second between each line.
System.out.println("Main thread interrupted");
} The pause is accomplished by the sleep( ) method. The argument to
} sleep( ) specifies the delay period in milliseconds. Notice the try/catch
} block around this loop.
The sleep( ) method in Thread might throw an InterruptedException. This The sleep( ) method causes the thread from which it is called to The name of a thread can be set by using setName( ).
would happen if some other thread wanted to interrupt this sleeping one. suspend execution for the specified period of milliseconds. Its general
form is shown here: The name of a thread can be obtained by calling getName( ) (but note
Notice the output produced when t is used as an argument to println( ).
This displays, in order: the name of the thread, its priority, and the name
static void sleep(long milliseconds) throws InterruptedException that this is not shown in the program).
of its group.
The number of milliseconds to suspend is specified in milliseconds. These methods are members of the Thread class and are declared like
By default, the name of the main thread is main. Its priority is 5, which is This method may throw an InterruptedException. this:
the default value, and main is also the name of the group of threads to
which this thread belongs. final void setName(String threadName)
The sleep( ) method has a second form, shown next, which allows final String getName( )
A thread group is a data structure that controls the state of a collection of you to specify the period in terms of milliseconds and nanoseconds:
threads as a whole. static void sleep(long milliseconds, int nanoseconds) throws InterruptedException
Here, threadName specifies the name of the thread.
After the name of the thread is changed, t is again output. This time, the This second form is useful only in environments that allow timing
new name of the thread is displayed. periods as short as nanoseconds.
Inside run( ), the code is defined that constitutes the new thread. Thread defines several constructors. The one that we will use is
shown here:
Thread(Runnable threadOb, String threadName)
In this constructor, threadOb is an instance of a class that implements class NewThread implements Runnable // This is the entry point for the second thread.
public void run()
the Runnable interface. { {
Thread t; try
This defines where execution of the thread will begin. The name of {
NewThread()
for(int i = 5; i > 0; i--)
the new thread is specified by threadName. { {
// Create a new, second thread System.out.println("Child Thread: " + i);
After the new thread is created, it will not start running until you call Thread.sleep(500);
t = new Thread(this, "Demo Thread"); }
its start( ) method, which is declared within Thread. In essence, start(
) executes a call to run( ). System.out.println("Child thread: " + t); }
catch (InterruptedException e)
// Start the thread
{
The start( ) method is shown here: t.start(); System.out.println("Child interrupted.");
} }
void start( ) System.out.println("Exiting child thread.");
}
}
// This is the entry point for the second thread. class ExtendThread catch (InterruptedException e)
public void run()
{ {
{
try public static void main(String args[]) System.out.println("Main thread interrupted.");
{ { }
for(int i = 5; i > 0; i--) // create a new thread
{ System.out.println("Main thread exiting.");
System.out.println("Child Thread: " + i); new NewThread();
}
Thread.sleep(500); try
} { }
} for(int i = 5; i > 0; i--)
catch (InterruptedException e)
{ {
System.out.println("Child interrupted."); System.out.println("Main Thread: " + i);
} Thread.sleep(1000);
System.out.println("Exiting child thread.");
}
}
} }
Output: The child thread is created by instantiating an object of NewThread, 3. Creating Multiple Threads
Child thread: Thread[Demo Thread,5,main] which is derived from Thread.
Child Thread: 5
So far, only two threads : the main thread and one child thread
Main Thread: 5 Notice the call to super( ) inside NewThread. This invokes the have been used.
Child Thread: 4 following form of the Thread constructor:
Main Thread: 4 public Thread(String threadName)
Child Thread: 3 However, the program can spawn as many threads as it needs.
Child Thread: 2 Here, threadName specifies the name of the thread
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Output:
catch (InterruptedException e) New thread: Thread[One,5,main] Once started, all three child threads share the CPU.
{ New thread: Thread[Two,5,main]
New thread: Thread[Three,5,main]
System.out.println("Main thread Interrupted"); One: 5 Notice the call to sleep(10000) in main( ).
Three: 5
} Two: 5
One: 4
System.out.println("Main thread exiting."); Three: 4 This causes the main thread to sleep for ten seconds and ensures that
} Two: 4 it will finish last.
One: 3
} Three: 3
Two: 3
One: 2
Three: 2
Two: 2
One: 1
Three: 1
Two: 1
One exiting.
Three exiting.
Two exiting.
Main thread exiting.
Using isAlive( ) and join( ) class NewThread implements Runnable // This is the entry point for thread.
public void run()
Two ways exist to determine whether a thread has finished. First, you { {
can call isAlive( ) on the thread. // name of thread try
{
String name;
This method is defined by Thread, and its general form is shown for(int i = 5; i > 0; i--)
here: Thread t; {
NewThread(String threadname) System.out.println(name + ": " + i);
final boolean isAlive( ) Thread.sleep(1000);
{ }
The isAlive( ) method returns true if the thread upon which it is name = threadname; }
called is still running. It returns false otherwise. t = new Thread(this, name); catch (InterruptedException e)
{
System.out.println("New thread: " + t); System.out.println(name + " interrupted.");
While isAlive( ) is occasionally useful, the method that you will more }
// Start the thread
commonly use to wait for a thread to finish is called join( ), shown System.out.println(name + " exiting.");
here: t.start(); }
final void join( ) throws InterruptedException } }
Three: 2
One: 2
4. Threads Priorities To set a thread’s priority, use the setPriority( ) method, which is a
member of Thread. This is its general form:
Two: 2 final void setPriority(int level)
Thread priorities are used by the thread scheduler to decide when each
Three: 1
thread should be allowed to run.
Two: 1
Here, level specifies the new priority setting for the calling thread.
One: 1 The value of level must be within the range MIN_PRIORITY and
In theory, over a given period of time, higher-priority threads get more
Three exiting. CPU time than lower-priority threads. MAX_PRIORITY. Currently, these values are 1 and 10, respectively.
Two exiting. To return a thread to default priority, specify NORM_PRIORITY,
One exiting. In practice, the amount of CPU time that a thread gets often depends on which is currently 5.
Thread One is alive: false several factors besides its priority. (For example, how an operating
Thread Two is alive: false system implements multitasking can affect the relative availability of These priorities are defined as static final variables within Thread.
CPU time.)
Thread Three is alive: false
Main thread exiting. You can obtain the current priority setting by calling the getPriority(
In theory, threads of equal priority should get equal access to the CPU.
But you need to be careful. ) method of Thread, shown here:
final int getPriority( )
public class ThreadPriorityEx extends Thread t1.start(); System.out.println("Priority of thread t1 is: " + t1.getPriority()); //1
{ t2.start(); System.out.println("Priority of thread t2 is: " + t2.getPriority()); //5
System.out.println("Priority of thread t3 is: " + t3.getPriority()); //10
public void run() t3.start();
System.out.println("Priority of thread t4 is: " + t4.getPriority()); //9
{ t4.start(); try
System.out.println("Thread Running... "+Thread.currentThread().getName()); t5.start(); {
} t5.setPriority(11);
public static void main(String args[]) t1.setPriority(Thread.MIN_PRIORITY); System.out.println("Priority of thread t5 is: " + t5.getPriority()); //11
{ t2.setPriority(Thread.NORM_PRIORITY); }
ThreadPriorityEx t1=new ThreadPriorityEx(); catch (Exception e)
t3.setPriority(Thread.MAX_PRIORITY);
{
ThreadPriorityEx t2=new ThreadPriorityEx(); t4.setPriority(9); System.out.println("Illegal Arguement");
ThreadPriorityEx t3=new ThreadPriorityEx(); }
ThreadPriorityEx t4=new ThreadPriorityEx(); }
ThreadPriorityEx t5=new ThreadPriorityEx(); }
104
20ES3102B – JAVA PROGRAMMING
20ES3102B – JAVA PROGRAMMING
UNIT 4:
Pragmatic Functional Programming using Lambdas: Introduction to
UNIT 4 Functional programming, Functional Programming concepts and
terminology, Functional Interfaces, Working with Lambda Expressions
and Method References.
Lecture By,
Prabu.U Collections Framework: Collections Overview, Collection interfaces:
Assistant Professor,
Department of Computer Science and Engineering. Collection, List, and Set. Collection Classes: ArrayList, LinkedList,
HashSet. Map Classes: HashMap, TreeMap
1 2 3
4 5 6
1. Introduction to Functional Programming Java functional programming comes into existence after Java 8th
version onwards.
2. Functional Programming Concepts and Terminology
3. Introducing Lambda Expressions Functional programming means a fundamental change in the
4. Block Lambda Expressions approach of problem-solving.
5. Generic Functional Interfaces
Functional programming allowing programming with expressions
6. Passing Lambda Expressions as Arguments (declaring functions), passing functions as arguments and also used
7. Lambda Expressions and Exceptions functions as statements.
8. Lambda Expressions and Variable Capture
9. Method References
7 8 9
105
Types of Functional Programming How does Functional programming work in Java? Structured programming is divided into small units or functions,
1. Streams functional Programming Before we get into the functional programming concept, let’s see the whereas Functional programming is divided into small run-time
difference between Functional and Structure programming. entities called objects.
2. Lambda Expressions functional Programming
3. Method Reference functional Programming
Structured programming gives importance to logical structure or Structured programming is less secure, whereas Functional
process, whereas Functional programming mainly focuses on data. programming is highly secure.
Structured programming follows a top-down approach, whereas Structured programming can’t handle complex problems, whereas
Functional programming follows bottom to top. Functional programming handles any level of a complex problem.
10 11 12
2. Functional Programming Concepts and Terminology If you are familiar with SQL or regular expressions, then you have Each time a functional programming function is called with the same
some experience with the declarative style; both use expressions to arguments, the same result is achieved.
Functional programming is a programming style in which describe what needs to be done, rather than using statements to
computations are codified as functional programming functions. describe how to do it. Functions in functional programming are said to exhibit referential
These are mathematical function-like constructs (e.g., lambda transparency. This means you could replace a function call with its
resulting value without changing the computation's meaning.
functions) that are evaluated in expression contexts. A computation in functional programming is described by functions
that are evaluated in expression contexts.
Functional programming favors immutability, which means the state
Functional programming languages are declarative, meaning that a cannot change. This is typically not the case in imperative
computation's logic is expressed without describing its control flow. These functions are not the same as the functions used in imperative programming, where an imperative function might be associated with
programming, such as a Java method that returns a value. state (such as a Java instance variable).
In declarative programming, there are no statements. Instead,
programmers use expressions to tell the computer what needs to be Instead, a functional programming function is like a mathematical Calling this function at different times with the same arguments
done, but not how to accomplish the task. function, which produces an output that typically depends only on might result in different return values because in this case state is
mutable, meaning it changes.
its arguments.
13 14 15
3. Introducing Lambda Expressions A functional interface is an interface that contains one and only one Lambda Expression Fundamentals
abstract method. Normally, this method specifies the intended purpose of
the interface. The lambda expression introduces a new syntax element and
Key to understanding Java’s implementation of lambda expressions operator into the Java language.
are two constructs. The first is the lambda expression, itself. The Thus, a functional interface typically represents a single action. For
second is the functional interface. example, the standard interface Runnable is a functional interface The new operator, sometimes referred to as the lambda operator or
because it defines only one method: run( ). the arrow operator, is −>. It divides a lambda expression into two
parts.
A lambda expression is, essentially, an anonymous (that is, unnamed)
Therefore, run( ) defines the action of Runnable. Furthermore, a
method. However, this method is not executed on its own.
functional interface defines the target type of a lambda expression. The left side specifies any parameters required by the lambda
expression. (If no parameters are needed, an empty parameter list is
Instead, it is used to implement a method defined by a functional Here is a key point: a lambda expression can be used only in a context in used.)
interface. Thus, a lambda expression results in a form of anonymous which its target type is specified.
class. Lambda expressions are also commonly referred to as closures. On the right side is the lambda body, which specifies the actions of
One other thing: a functional interface is sometimes referred to as a SAM the lambda expression. The −> can be verbalized as “becomes” or
type, where SAM stands for Single Abstract Method. “goes to.”
16 17 18
106
Java defines two types of lambda bodies. One consists of a single Of course, the method defined by a lambda expression does not have This lambda expression returns true if the value of parameter n is
expression, and the other type consists of a block of code. a name. A slightly more interesting lambda expression is shown even.
here:
Let’s begin with what is probably the simplest type of lambda expression
you can write. It evaluates to a constant value and is shown here:
() -> Math.random() * 100 Although it is possible to explicitly specify the type of a parameter,
() -> 123.45 such as n in this case, often you won’t need to do so because in
This lambda expression obtains a pseudo-random value from many cases its type can be inferred.
This lambda expression takes no parameters, thus the parameter list is Math.random( ), multiplies it by 100, and returns the result. It, too,
empty. It returns the constant value 123.45. does not require a parameter. Like a named method, a lambda expression can specify as many
parameters as needed.
Therefore, it is similar to the following method:
When a lambda expression requires a parameter, it is specified in the
double myMeth()
parameter list on the left side of the lambda operator. Here is a simple
{
example:
return 123.45;
(n) -> (n % 2)==0
}
19 20 21
Functional Interfaces In this case, the method getValue( ) is implicitly abstract, and it is the Let’s work through an example that shows how a lambda expression
As stated, a functional interface is an interface that specifies only one only method defined by MyNumber. Thus, MyNumber is a can be used in an assignment context. First, a reference to the
abstract method. functional interface, and its function is defined by getValue( ). functional interface MyNumber is declared:
// Create a reference to a MyNumber instance.
An interface method is abstract only if it does not specify a default A lambda expression is not executed on its own. Rather, it forms the
implementation of the abstract method defined by the functional MyNumber myNum;
implementation. Because nondefault interface methods are implicitly
abstract, there is no need to use the abstract modifier (although you interface that specifies its target type.
can specify it, if you like). Next, a lambda expression is assigned to that interface reference:
As a result, a lambda expression can be specified only in a context // Use a lambda in an assignment context.
Here is an example of a functional interface: in which a target type is defined. One of these contexts is created myNum = () -> 123.45;
when a lambda expression is assigned to a functional interface
interface MyNumber reference.
{ When a lambda expression occurs in a target type context, an
double getValue(); Other target type contexts include variable initialization, return instance of a class is automatically created that implements the
} statements, and method arguments, to name a few. functional interface, with the lambda expression defining the
behavior of the abstract method declared by the functional interface.
22 23 24
When that method is called through the target, the lambda In order for a lambda expression to be used in a target type context, Some Lambda Expression Examples
expression is executed. Thus, a lambda expression gives us a way to the type of the abstract method and the type of the lambda Refer LambdaDemo.
transform a code segment into an object. expression must be compatible.
In the preceding example, the lambda expression becomes the For example, if the abstract method specifies two int parameters,
implementation for the getValue( ) method. As a result, the then the lambda must specify two parameters whose type either is
following displays the value 123.45: explicitly int or can be implicitly inferred as int by the context.
// Call getValue(), which is implemented by the previously assigned
// lambda expression. In general, the type and number of the lambda expression’s
System.out.println("myNum.getValue()); parameters must be compatible with the method’s parameters; the
return types must be compatible; and any exceptions thrown by the
lambda expression must be acceptable to the method.
Because the lambda expression assigned to myNum returns the
value 123.45, that is the value obtained when getValue( ) is called.
25 26 27
107
4. Block Lambda Expressions To handle such cases, Java supports a second type of lambda expression Aside from allowing multiple statements, block lambdas are used
in which the code on the right side of the lambda operator consists of a
block of code that can contain more than one statement. This type of much like the expression lambdas just discussed.
The body of the lambdas shown in the preceding examples consist lambda body is called a block body.
of a single expression. One key difference, however, is that you must explicitly use a return
Lambdas that have block bodies are sometimes referred to as block
lambdas. statement to return a value. This is necessary because a block
These types of lambda bodies are referred to as expression bodies, lambda body does not represent a single expression.
and lambdas that have expression bodies are sometimes called A block lambda expands the types of operations that can be handled
within a lambda expression because it allows the body of the lambda to
expression lambdas. contain multiple statements. Here is an example that uses a block lambda to compute and return
the factorial of an int value:
In an expression body, the code on the right side of the lambda For example, in a block lambda you can declare variables, use loops,
specify if and switch statements, create nested blocks, and so on. A block
operator must consist of a single expression. lambda is easy to create. Refer BlockLambdaDemo
While expression lambdas are quite useful, sometimes the situation Simply enclose the body within braces as you would any other block of
statements.
will require more than a single expression.
28 29 30
In the program, notice that the block lambda declares a variable 5. Generic Functional Interfaces To understand the value of generic functional interfaces, consider this.
called result, uses a for loop, and has a return statement. The two examples in the previous section used two different functional
interfaces, one called NumericFunc and the other called StringFunc.
A lambda expression, itself, cannot specify type parameters. Thus, a
These are legal inside a block lambda body. In essence, the block lambda expression cannot be generic. (Of course, because of type However, both defined a method called func( ) that took one parameter
body of a lambda is similar to a method body. inference, all lambda expressions exhibit some “generic-like” and returned a result. In the first case, the type of the parameter and
qualities.) return type was int. In the second case, the parameter and return type
was String.
One other point. When a return statement occurs within a lambda
expression, it simply causes a return from the lambda. It does not However, the functional interface associated with a lambda
Thus, the only difference between the two methods was the type of data
cause an enclosing method to return. expression can be generic. they required.
Another example of a block lambda is shown in the following In this case, the target type of the lambda expression is determined, Instead of having two functional interfaces whose methods differ only in
program. It reverses the characters in a string. in part, by the type argument or arguments specified when a their data types, it is possible to declare one generic interface that can be
used to handle both circumstances. The following program shows this
functional interface reference is declared.
approach: Refer GenericFunctionalInterfaceDemo
Refer BlockLambdaDemo2
31 32 33
In the program, the generic functional interface SomeFunc is declared as 6. Passing Lambda Expressions as Arguments To pass a lambda expression as an argument, the type of the
shown here: parameter receiving the lambda expression argument must be of a
interface SomeFunc<T> functional interface type compatible with the lambda.
As explained earlier, a lambda expression can be used in any
{
context that provides a target type.
T func(T t);
}
Although using a lambda expression as an argument is
One of these is when a lambda expression is passed as an straightforward, it is still helpful to see it in action.
Here, T specifies both the return type and the parameter type of func( ). argument. In fact, passing a lambda expression as an argument is a
This means that it is compatible with any lambda expression that takes common use of lambdas. The following program demonstrates the process:
one parameter and returns a value of the same type.
Moreover, it is a very powerful use because it gives you a way to Refer LambdasAsArgumentsDemo
The SomeFunc interface is used to provide a reference to two different
types of lambdas. The first uses type String. The second uses type pass executable code as an argument to a method.
Integer. Thus, the same functional interface can be used to refer to the
reverse lambda and the factorial lambda. Only the type argument passed
This greatly enhances the expressive power of Java.
to SomeFunc differs.
34 35 36
108
In the program, first notice the stringOp( ) method. It has two Here, a simple expression lambda is passed as an argument. When Next, the program passes a block lambda to stringOp( ). This
parameters. The first is of type StringFunc, which is a functional this occurs, an instance of the functional interface StringFunc is lambda removes spaces from a string. It is shown again here:
interface. created and a reference to that object is passed to the first parameter outStr = stringOp((str) ->
of stringOp( ). {
Thus, this parameter can receive a reference to any instance of String result = "";
StringFunc, including one created by a lambda expression. Thus, the lambda code, embedded in a class instance, is passed to int i;
the method. The target type context is determined by the type of
The second argument of stringOp( ) is of type String, and this is the parameter. Because the lambda expression is compatible with that
type, the call is valid. for(i = 0; i < str.length(); i++)
string operated on.
if(str.charAt(i) != ' ‘)
Embedding simple lambdas, such as the one just shown, inside a result += str.charAt(i);
Next, notice the first call to stringOp( ), shown again here:
method call is often a convenient technique—especially when the
outStr = stringOp((str) -> str.toUpperCase(), inStr); lambda expression is intended for a single use. return result;
}, inStr);
37 38 39
Although this uses a block lambda, the process of passing the This lambda is assigned to reverse, which is a reference to a 7. Lambda Expressions and Exceptions
lambda expression is the same as just described for the simple StringFunc instance.
expression lambda. A lambda expression can throw an exception. However, it if throws
Thus, reverse can be used as an argument to the first parameter of a checked exception, then that exception must be compatible with
stringOp( ). The program then calls stringOp( ), passing in reverse the exception(s) listed in the throws clause of the abstract method
In this case, however, some programmers will find the syntax a bit and the string on which to operate.
awkward. in the functional interface.
40 41 42
Refer LambdaExceptionDemo Remember, the type of a lambda expression parameter will be 8. Lambda Expressions and Variable Capture
inferred from the target context.
The first call to average.func( ) returns the value 2.5. The second call, Variables defined by the enclosing scope of a lambda expression are
which passes a zero-length array, causes an EmptyArrayException In this case, the target context is double[ ], thus the type of n will be accessible within the lambda expression.
to be thrown.
double[ ].
For example, a lambda expression can use an instance or static
Remember, the inclusion of the throws clause in func( ) is necessary. variable defined by its enclosing class.
Without it, the program will not compile because the lambda It is not necessary (or legal) to specify it as n[ ]. It would be legal to
expression will no longer be compatible with func( ). explicitly declare it as double[ ] n, but doing so gains nothing in this
case. A lambda expression also has access to this (both explicitly and
implicitly), which refers to the invoking instance of the lambda
This example demonstrates another important point about lambda expression’s enclosing class.
expressions. Notice that the parameter specified by func( ) in the
functional interface DoubleNumericArrayFunc is an array.
However, the parameter to the lambda expression is simply n, rather Thus, a lambda expression can obtain or set the value of an
than n[ ]. instance or static variable and call a method defined by its
enclosing class.
43 44 45
109
However, when a lambda expression uses a local variable from its It is important to understand that a local variable of the enclosing 9. Method References
enclosing scope, a special situation is created that is referred to as a scope cannot be modified by the lambda expression.
variable capture. There is an important feature related to lambda expressions called
Doing so would remove its effectively final status, thus rendering it the method reference.
In this case, a lambda expression may only use local variables that illegal for capture.
are effectively final. A method reference provides a way to refer to a method without
The following program illustrates the difference between effectively executing it.
An effectively final variable is one whose value does not change final and mutable local variables:
after it is first assigned. It relates to lambda expressions because it, too, requires a target
Refer VarCapture type context that consists of a compatible functional interface.
There is no need to explicitly declare such a variable as final,
although doing so would not be an error. (The this parameter of an When evaluated, a method reference also creates an instance of the
enclosing scope is automatically effectively final, and lambda functional interface.
expressions do not have a this of their own.)
46 47 48
There are different types of method references. They are i. Method References to static Methods Refer MethodRefDemo
i. Method References to static Methods
ii. Method References to Instance Methods To create a static method reference, use this general syntax: Here, a reference to the static method strReverse( ), declared inside
iii. Method References with Generics ClassName::methodName MyStringOps, is passed as the first argument to stringOp( ).
Notice that the class name is separated from the method name by a This works because strReverse is compatible with the StringFunc
double colon. functional interface.
The :: is a new separator that has been added to Java by JDK 8 Thus, the expression MyStringOps::strReverse evaluates to a
expressly for this purpose. reference to an object in which strReverse provides the
implementation of func( ) in StringFunc.
This method reference can be used anywhere in which it is
compatible with its target type.
49 50 51
ii. Method References to Instance Methods In the program, notice that strReverse( ) is now an instance method It is also possible to handle a situation in which you want to specify
of MyStringOps. an instance method that can be used with any object of a given
To pass a reference to an instance method on a specific object, use class—not just a specified object.
this basic syntax: Inside main( ), an instance of MyStringOps called strOps is created.
objRef::methodName In this case, you will create a method reference as shown here:
This instance is used to create the method reference to strReverse in ClassName::instanceMethodName
As you can see, the syntax is similar to that used for a static the call to stringOp, as shown again, here:
method, except that an object reference is used instead of a class outStr = stringOp(strOps::strReverse, inStr); Here, the name of the class is used instead of a specific object, even
name. though an instance method is specified.
In this example, strReverse( ) is called on the strOps object.
Here is the previous program rewritten to use an instance method With this form, the first parameter of the functional interface
reference: Refer MethodRefDemo2 matches the invoking object and the second parameter matches the
parameter specified by the method.
52 53 54
110
Here is an example. It defines a method called counter( ) that counts Each method has a parameter of type HighTemp and each method One other point: you can refer to the superclass version of a method
the number of objects in an array that satisfy the condition defined returns a boolean result. by use of super, as shown here:
by the func( ) method of the MyFunc functional interface. In this
case, it counts instances of the HighTemp class. super::name
Thus, each is compatible with the MyFunc functional interface because
the invoking object type can be mapped to the first parameter of func( )
and the argument mapped to func( )’s second parameter. Thus, when the The name of the method is specified by name.
Refer InstanceMethWithObjectRefDemo
expression
HighTemp::sameTemp
In the program, notice that HighTemp has two instance methods:
sameTemp( ) and lessThanTemp( ).
is passed to the counter( ) method, an instance of the functional interface
MyFunc is created in which the parameter type of the first parameter is
The first returns true if two HighTemp objects contain the same that of the invoking object of the instance method, which is HighTemp.
temperature.
The type of the second parameter is also HighTemp because that is the
The second returns true if the temperature of the invoking object is type of the parameter to sameTemp( ). The same is true for the
less than that of the passed object. lessThanTemp( ) method.
55 56 57
iii. Method References with Generics passes the type argument Integer. Notice that it occurs after the ::. COLLECTIONS FRAMEWORK
This syntax can be generalized: When a generic method is specified
You can use method references with generic classes and/or generic as a method reference, its type argument comes after the :: and
methods. For example, consider the following program: before the method name. 1. Collections Overview
2. The Collection Interfaces
Refer GenericMethodRefDemo It is important to point out, however, that explicitly specifying the
type argument is not required in this situation (and many others) 3. The Collection Classes
because the type argument would have been automatically inferred.
In the program, MyArrayOps is a non-generic class that contains a 4. The Map Classes
generic method called countMatching( ).
In cases in which a generic class is specified, the type argument
follows the class name and precedes the ::.
The method returns a count of the elements in an array that match
a specified value. Notice how the generic type argument is
specified. For example, its first call in main( ), shown here:
count = myOp(MyArrayOps::<Integer>countMatching, vals, 4);
58 59 60
1. Collections Overview An item closely associated with the Collections Framework is the
Iterator interface.
Java Collections Framework (JCF):
A Collection is a group of objects.
The Java Collections Framework standardizes the way in which
groups of objects are handled by your programs. An iterator offers a general-purpose, standardized way of accessing
the elements within a collection, one at a time. Collections Framework provides a set of standard utility
Collections were not part of the original Java release but were
classes to manage collections.
added by J2SE 1.2. Thus, an iterator provides a means of enumerating the contents of a
collection.
Collections Framework consists of three parts:
Prior to the Collections Framework, Java provided adhoc classes Core Interfaces
such as Dictionary, Vector, Stack, and Properties to store and Because each collection provides an iterator, the elements of any
manipulate groups of objects. collection class can be accessed through the methods defined by Concrete Implementations
Iterator. Algorithms such as searching and sorting
61 62 63
111
Advantages: Collections vs Collection: Implementations
Reduces programming effort by providing useful data Collections is a class with static utility methods.
Hash
structures and algorithms.
Hash Resizable Balanced Linked Table+
Collection is an interface with declarations of the methods Table Array Tree List Linked
Interfaces
Increases performance by providing high-performance common to most collections including add(), remove(), List
implementation of useful data structures and algorithms. contains(), size() and iterator().
Set HashSet TreeSet
Linked
HashSet
Provides interoperability between unrelated APIs.
List ArrayList LinkedList
64 65 66
67 68 69
Collection Implementations: 2. The Collection Interfaces In addition to the collection interfaces, collections also use the
Comparator, RandomAccess, Iterator, and ListIterator interfaces.
HashMap
The Collections Framework defines several core interfaces.
Unsorted and Unordered Map Beginning with the collection interfaces is necessary because they Beginning with JDK 8, Spliterator can also be used.
Allows one null key and multiple null values. determine the fundamental nature of the collection classes.
Comparator defines how two objects are compared; Iterator,
ListIterator, and Spliterator enumerate the objects within a collection.
TreeMap
Sorted Map By implementing RandomAccess, a list indicates that it supports
efficient, random access to its elements.
LinkedHashMap
Maintains the insertion order
70 71 72
112
To provide the greatest flexibility in their use, the collection interfaces The Collection Interface
allow some methods to be optional.
The Collection interface is the foundation upon which the Collections
Framework is built because it must be implemented by any class that
The optional methods enable you to modify the contents of a defines a collection.
collection.
Collection is a generic interface that has this declaration:
Collections that support these methods are called modifiable. interface Collection<E>
Collections that do not allow their contents to be changed are called Here, E specifies the type of objects that the collection will hold.
unmodifiable. Collection extends the Iterable interface.
If an attempt is made to use one of these methods on an unmodifiable This means that all collections can be cycled through by use of the
collection, an UnsupportedOperationException is thrown. All the foreach style for loop.
built-in collections are modifiable.
73 74 75
You can add the entire contents of one collection to another by calling
addAll( ).
76 77 78
You can determine whether a collection contains a specific object by The List Interface In addition to the methods defined by Collection, List defines some
calling contains( ). of its own, which are summarized in Table
The List interface extends Collection and declares the behavior of a
To determine whether one collection contains all the members of another, collection that stores a sequence of elements.
call containsAll( ).
Elements can be inserted or accessed by their position in the list,
You can determine when a collection is empty by calling isEmpty( ). The using a zero-based index. A list may contain duplicate elements.
number of elements currently held in a collection can be determined by
calling size( ).
List is a generic interface that has this declaration:
The toArray( ) methods return an array that contains the elements stored interface List<E>
in the invoking collection. The first returns an array of Object.
The second returns an array of elements that have the same type as the Here, E specifies the type of objects that the list will hold.
array specified as a parameter. Normally, the second form is more
convenient because it returns the desired array type.
79 80 81
113
Note again that several of these methods will throw an To the versions of add( ) and addAll( ) defined by Collection, List
UnsupportedOperationException if the list cannot be modified, and a adds the methods add(int, E) and addAll(int, Collection).
ClassCastException is generated when one object is incompatible
with another, such as when an attempt is made to add an These methods insert elements at the specified index.
incompatible object to a list.
A NullPointerException is thrown if an attempt is made to store a You can modify each element in the collection by using replaceAll( ).
null object and null elements are not allowed in the list.
82 83 84
To obtain the object stored at a specific location, call get( ) with the
index of the object. The Set Interface 3. The Collection Classes
The Set interface defines a set. It extends Collection and specifies the
behavior of a collection that does not allow duplicate elements. The core collection classes are summarized in the following table:
To assign a value to an element in the list, call set( ), specifying the
index of the object to be changed.
Therefore, the add( ) method returns false if an attempt is made to
To find the index of an object, use indexOf( ) or lastIndexOf( ). add duplicate elements to a set.
You can obtain a sublist of a list by calling subList( ), specifying the It does not specify any additional methods of its own.
beginning and ending indexes of the sublist.
One way to sort a list is with the sort( ) method defined by List. Here, E specifies the type of objects that the set will hold.
85 86 87
The ArrayList Class But, sometimes, you may not know until run time precisely how ArrayList has the constructors shown here:
large an array you need. ArrayList( )
The ArrayList class extends AbstractList and implements the List
interface. ArrayList is a generic class that has this declaration: ArrayList(Collection<? extends E> c)
class ArrayList<E> To handle this situation, the Collections Framework defines ArrayList(int capacity)
ArrayList.
Here, E specifies the type of objects that the list will hold. The syntax <? extends E> means "some type that either is E or a
In essence, an ArrayList is a variable-length array of object subtype of E". The ? is a wildcard.
references. That is, an ArrayList can dynamically increase or decrease
ArrayList supports dynamic arrays that can grow as needed. In Java, in size.
standard arrays are of a fixed length. The question mark (?) is known as the wildcard. It represents an
unknown type.
Array lists are created with an initial size. When this size is exceeded,
After arrays are created, they cannot grow or shrink, which means the collection is automatically enlarged.
that you must know in advance how many elements an array will
hold.
When objects are removed, the array can be shrunk.
88 89 90
114
The first constructor builds an empty array list. The program shows a simple use of ArrayList. The LinkedList Class
The LinkedList class extends AbstractSequentialList and implements
The second constructor builds an array list that is initialized with the An array list is created for objects of type String, and then several the List, Deque, and Queue interfaces.
elements of the collection c. strings are added to it. (Recall that a quoted string is translated into a
String object.)
It provides a linked-list data structure. LinkedList is a generic class
The third constructor builds an array list that has the specified that has this declaration:
initial capacity. The list is then displayed. class LinkedList<E>
The capacity is the size of the underlying array that is used to store Some of the elements are removed and the list is displayed again. Here, E specifies the type of objects that the list will hold. LinkedList
the elements. has the two constructors shown here:
Refer ArrayListDemo.java LinkedList( )
The capacity grows automatically as elements are added to an array LinkedList(Collection<? extends E> c)
list.
91 92 93
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.
Refer LinkedListDemo.java The HashSet Class
HashSet extends AbstractSet and implements the Set interface. It
Because LinkedList implements the List interface, calls to add(E) append
Because LinkedList implements the Deque interface, you have access to creates a collection that uses a hash table for storage.
items to the end of the list, as do calls to addLast( ).
the methods defined by Deque.
To insert items at a specific location, use the add(int, E) form of add( ), HashSet is a generic class that has this declaration:
For example, to add elements to the start of a list, you can use addFirst( )
or offerFirst( ). as illustrated by the call to add(1, "A2") in the example. class HashSet<E>
To add elements to the end of the list, use addLast( ) or offerLast( ). To Notice how the third element in ll is changed by employing calls to get( ) Here, E specifies the type of objects that the set will hold.
obtain the first element, you can use getFirst( ) or peekFirst( ). and set( ).
94 95 96
In hashing, the informational content of a key is used to determine a The following constructors are defined: The fill ratio must be between 0.0 and 1.0, and it determines how full the
unique value, called its hash code. HashSet( ) hash set can be before it is resized upward.
HashSet(Collection<? extends E> c)
HashSet(int capacity) Specifically, when the number of elements is greater than the capacity of
The hash code is then used as the index at which the data associated the hash set multiplied by its fill ratio, the hash set is expanded.
HashSet(int capacity, float fillRatio)
with the key is stored. The transformation of the key into its hash
code is performed automatically—you never see the hash code itself. For constructors that do not take a fill ratio, 0.75 is used.
The first form constructs a default hash set.
Also, your code can’t directly index the hash table. HashSet does not define any additional methods beyond those provided
The second form initializes the hash set by using the elements of c.
by its superclasses and interfaces.
The advantage of hashing is that it allows the execution time of The third form initializes the capacity of the hash set to capacity. (The
default capacity is 16.) It is important to note that HashSet does not guarantee the order of its
add( ), contains( ), remove( ), and size( ) to remain constant even for elements, because the process of hashing doesn’t usually lend itself to the
large sets. creation of sorted sets.
The fourth form initializes both the capacity and the fill ratio (also called
load capacity ) of the hash set from its arguments.
Refer HashSetDemo.java
97 98 99
115
The TreeSet Class TreeSet has the following constructors: Refer TreeSetDemo.java
TreeSet extends AbstractSet and implements the NavigableSet TreeSet( )
interface. TreeSet(Collection<? extends E> c) Because TreeSet stores its elements in a tree, they are automatically
TreeSet(Comparator<? super E> comp) arranged in sorted order, as the output confirms.
It creates a collection that uses a tree for storage. Objects are stored in TreeSet(SortedSet<E> ss)
sorted, ascending order.
Because TreeSet implements the NavigableSet interface, you can use
The first form constructs an empty tree set that will be sorted in the methods defined by NavigableSet to retrieve elements of a
Access and retrieval times are quite fast, which makes TreeSet an ascending order according to the natural order of its elements. TreeSet.
excellent choice when storing large amounts of sorted information
that must be found quickly. The second form builds a tree set that contains the elements of c.
subSet( ) - to obtain a subset of ts that contains the elements between
TreeSet is a generic class that has this declaration: C (inclusive) and F (exclusive).
The third form constructs an empty tree set that will be sorted
class TreeSet<E> according to the comparator specified by comp.
Here, E specifies the type of objects that the set will hold. The fourth form builds a tree set that contains the elements of ss.
4. The Map Classes The HashMap Class The following constructors are defined:
HashMap( )
The HashMap class extends AbstractMap and implements the Map
HashMap(Map<? extends K, ? extends V> m)
Several classes provide implementations of the map interfaces. The interface.
HashMap(int capacity)
classes that can be used for maps are summarized here:
HashMap(int capacity, float fillRatio)
It uses a hash table to store the map. This allows the execution time
of get( ) and put( ) to remain constant even for large sets. HashMap is The first form constructs a default hash map. The second form initializes
a generic class that has this declaration: the hash map by using the elements of m.
class HashMap<K, V>
The third form initializes the capacity of the hash map to capacity.
Here, K specifies the type of keys, and V specifies the type of values.
The fourth form initializes both the capacity and fill ratio of the hash map
by using its arguments.
The meaning of capacity and fill ratio is the same as for HashSet, described
earlier. The default capacity is 16. The default fill ratio is 0.75.
HashMap implements Map and extends AbstractMap. It does not The program begins by creating a hash map and then adds the mapping of
names to balances.
The TreeMap Class
add any methods of its own. The TreeMap class extends AbstractMap and implements the
NavigableMap interface.
Next, the contents of the map are displayed by using a set-view, obtained
You should note that a hash map does not guarantee the order of its by calling entrySet( ).
elements. It creates maps stored in a tree structure. A TreeMap provides an
The keys and values are displayed by calling the getKey( ) and getValue( ) efficient means of storing key/value pairs in sorted order and allows
methods that are defined by Map.Entry. rapid retrieval.
Therefore, the order in which elements are added to a hash map is
not necessarily the order in which they are read by an iterator.
Pay close attention to how the deposit is made into John Doe’s account. You should note that, unlike a hash map, a tree map guarantees that
its elements will be sorted in ascending key order. TreeMap is a
Refer HashMapDemo.java The put( ) method automatically replaces any preexisting value that is generic class that has this declaration:
associated with the specified key with the new value. class TreeMap<K, V>
Thus, after John Doe’s account is updated, the hash map will still contain Here, K specifies the type of keys, and V specifies the type of values.
just one "John Doe" account.
The first form constructs an empty tree map that will be sorted by using How to Obtain a Stream
the natural order of its keys. A Simple Stream Example
2. Reduction Operations
The second form constructs an empty tree-based map that will be sorted
by using the Comparator comp. 3. Using Parallel Streams
4. Mapping
The third form initializes a tree map with the entries from m, which will
be sorted by using the natural order of the keys. 5. Collecting
6. Iterators and Streams
The fourth form initializes a tree map with the entries from sm, which will Use an Iterator with a Stream
be sorted in the same order as sm.
Use Spliterator
1. Stream Basics Stream Interfaces The methods declared by BaseStream are shown in Table
The stream API defines several stream interfaces, which are
A stream is a conduit for data. Thus, a stream represents a sequence of packaged in java.util.stream. At the foundation is BaseStream,
objects. A stream operates on a data source, such as an array or a which defines the basic functionality available in all streams.
collection.
BaseStream is a generic interface declared like this:
A stream, itself, never provides storage for the data. It simply moves
interface BaseStream<T, S extends BaseStream<T, S>>
data, possibly filtering, sorting, or otherwise operating on that data in
the process. Here, T specifies the type of the elements in the stream, and S
specifies the type of stream that extends BaseStream.
As a general rule, however, a stream operation by itself does not modify
the data source. For example, sorting a stream does not change the order
of the source. BaseStream extends the AutoCloseable interface; thus, a stream can
be managed in a try-with-resources statement.
Rather, sorting a stream results in the creation of a new stream that
produces the sorted result.
From BaseStream are derived several types of stream interfaces. A Sampling of Methods Declared by Stream
The most general of these is Stream. It is declared as shown here:
interface Stream<T>
Another key aspect of streams is that some intermediate operations are Because Stream operates on object references, it can’t operate How to Obtain a Stream
stateless and some are stateful. In a stateless operation, each element is directly on primitive types. To handle primitive type streams, the
processed independently of the others. You can obtain a stream in a number of ways. Perhaps the most
stream API defines the following interfaces: common is when a stream is obtained for a collection. Beginning
DoubleStream with JDK 8, the Collection interface has been expanded to include
In a stateful operation, the processing of an element may depend on two methods that obtain a stream from a collection. The first is
aspects of the other elements. For example, sorting is a stateful operation IntStream
because an element’s order depends on the values of the other elements.
stream( ), shown here:
LongStream default Stream<E> stream( )
Thus, the sorted( ) method is stateful.
However, filtering elements based on a stateless predicate is stateless These streams all extend BaseStream and have capabilities similar Its default implementation returns a sequential stream. The second
because each element is handled individually. Thus, filter( ) can (and to Stream except that they operate on primitive types rather than method is parallelStream( ), shown next:
should be) stateless. reference types. default Stream<E> parallelStream( )
Parallel streams support parallel execution of stream operations. Several overloads of the stream( ) method are also defined, such as A Simple Stream Example
Because Collection is implemented by every collection, these those that handle arrays of the primitive types.
The following program creates an ArrayList called myList that
methods can be used to obtain a stream from any collection class,
holds a collection of integers (which are automatically boxed into
such as ArrayList or HashSet. They return a stream of type IntStream, DoubleStream, or the Integer reference type).
LongStream.
A stream can also be obtained from an array by use of the static
Next, it obtains a stream that uses myList as a source. It then
stream( ) method, which was added to the Arrays class by JDK 8. Streams can be obtained in a variety of other ways. For example, demonstrates various stream operations.
One of its forms is shown here: many stream operations return a new stream, and a stream to an
static <T> Stream<T> stream(T[ ] array) I/O source can be obtained by calling lines( ) on a BufferedReader.
Refer StreamDemo.java
This method returns a sequential stream to the elements in array. However a stream is obtained, it can be used in the same way as
For example, given an array called addresses of type Address, the any other stream.
following obtains a stream to it:
Stream<Address> addrStrm = Arrays.stream(addresses);
The next lines obtain and display the maximum value in the The program then obtains a sorted stream through the use of this line: The forEach( ) method has this general form:
stream: Stream<Integer> sortedStream = myList.stream().sorted(); void forEach(Consumer<? super T> action)
myStream = myList.stream();
Optional<Integer> maxVal = myStream.max(Integer::compare); Here, the sorted( ) method is called on the stream returned by Consumer is a generic functional interface declared in
if(maxVal.isPresent()) myList.stream( ). Because sorted( ) is an intermediate operation, its java.util.function. Its abstract method is accept( ), shown here:
result is a new stream, and this is the stream assigned to sortedStream.
System.out.println("Maximum value: " +maxVal.get()); void accept(T objRef)
The contents of the sorted stream are displayed by use of forEach( ):
First, myStream is once again assigned the stream returned by sortedStream.forEach((n) -> System.out.print(n + " ")); The lambda expression in the call to forEach( ) provides the
myList.stream( ). As just explained, this is necessary because the implementation of accept( ).
previous call to min( ) consumed the previous stream.
Here, the forEach( ) method executes an operation on each element in
the stream. In this case, it simply calls System.out.print( ) for each The forEach( ) method is a terminal operation. Thus, after it
Thus, a new one is needed. Next, the max( ) method is called to element in sortedStream. This is accomplished by use of a lambda completes, the stream has been consumed.
obtain the maximum value. Like min( ), max( ) returns an Optional expression.
object. Its value is obtained by calling get( ).
Next, a sorted stream is filtered by filter( ) so that it contains only It returns true if the object referred to by objRef satisfies the 2. Reduce Operations
odd values: predicate, and false otherwise.
Stream<Integer> oddVals = Consider the min( ) and max( ) methods in the preceding example
myList.stream().sorted().filter((n) -> (n % 2) == 1); The lambda expression passed to filter( ) implements this method. program. Both are terminal operations that return a result based on
Because filter( ) is an intermediate operation, it returns a new the elements in the stream.
The filter( ) method filters a stream based on a predicate. It returns stream that contains filtered values, which, in this case, are the odd
a new stream that contains only those elements that satisfy the numbers. These elements are then displayed via forEach( ) as
In the language of the stream API, they represent reduction
predicate. It is shown here: before.
operations because each reduces a stream to a single value—in this
Stream<T> filter(Predicate<? super T> pred) case, the minimum and maximum.
Because filter( ), or any other intermediate operation, returns a new
stream, it is possible to filter a filtered stream a second time. This is
Predicate is a generic functional interface defined in The stream API refers to these as special case reductions because
demonstrated by the following line, which produces a stream that
java.util.function. Its abstract method is test( ), which is shown here: they perform a specific function. In addition to min( ) and max( ),
contains only those odd values greater than 5:
boolean test(T objRef) other special case reductions are also available, such as count( ),
oddVals = myList.stream().filter((n) -> (n % 2) == 1).filter((n) -> n > 5);
which counts the number of elements in a stream.
Thus, as it relates to BinaryOperator, apply( ) looks like this: As explained earlier, stateless means that the operation does not rely on any
state information. Thus, each element is processed independently.
3. Using Parallel Streams
T apply(T val, T val2)
Non-interfering means that the data source is not modified by the operation. The parallel execution of code via multicore processors can result in
Furthermore, as it relates to reduce( ), val will contain the previous a substantial increase in performance.
Finally, the operation must be associative.
result and val2 will contain the next element.
Here, the term associative is used in its normal, arithmetic sense, which Because of this, parallel programming has become an important
In its first invocation, val will contain either the identity value or the means that, given an associative operator used in a sequence of operations, it
first element, depending on which version of reduce( ) is used. part of the modern programmer’s job.
does not matter which pair of operands are processed first. For example,
(10 * 2) * 7
It is important to understand that the accumulator operation must yields the same result as However, parallel programming can be complex and error-prone.
satisfy three constraints. It must be 10 * (2 * 7) One of the benefits that the stream library offers is the ability to
Stateless easily—and reliably—parallel process certain operations.
Non-interfering Refer StreamDemo2
Associative Parallel processing of a stream is quite simple to request just use a
parallel stream.
One way to obtain a parallel stream is to use the parallelStream( ) Once a parallel stream has been obtained, operations on the stream As a general rule, any operation applied to a parallel stream must
method defined by Collection. Another way to obtain a parallel can occur in parallel, assuming that parallelism is supported by the be stateless. It should also be non-interfering and associative.
stream is to call the parallel( ) method on a sequential stream. environment.
This ensures that the results obtained by executing operations on a
The parallel( ) method is defined by BaseStream, as shown here For example, the first reduce( ) operation in the preceding program parallel stream are the same as those obtained from executing the
S parallel() can be parallelized by substituting parallelStream( ) for the call to same operations on a sequential stream.
stream( ):
It returns a parallel stream based on the sequential stream that Optional<Integer> productObj = When using parallel streams, you might find the following version
invokes it. (If it is called on a stream that is already parallel, then myList.parallelStream().reduce((a,b) -> a*b); of reduce( ) especially helpful. It gives you a way to specify how
the invoking stream is returned.) partial results are combined:
The results will be the same, but the multiplications can occur in <U> U reduce(U identityVal, BiFunction<U, ? super T, U> accumulator
Understand, of course, that even with a parallel stream, parallelism different threads. BinaryOperator<U> combiner)
As you can see, in this example, both the accumulator and combiner As another example, you might want to apply some transformation Function is a functional interface declared in java.util.function. It is
perform the same function. However, there are cases in which the to the elements in a stream. To do this, you could map the declared as shown here:
actions of the accumulator must differ from those of the combiner. For
example, consider the following program. transformed elements to a new stream. Because mapping Function<T, R>
operations are quite common, the stream API provides built-in
Here, myList contains a list of double values. It then uses the combiner support for them. The most general mapping method is map( ). It is
As it relates to map( ), T is the element type and R is the result of
version of reduce( ) to compute the product of the square roots of each shown here:
the mapping.
element in the list. Refer StreamDemo3 <R> Stream<R> map(Function<? super T, ? extends R> mapFunc)
Function has the abstract method shown here: 5. Collecting Here, R specifies the type of the result, and T specifies the element
type of the invoking stream. The internal accumulated type is
R apply(T val)
Here, val is a reference to the object being mapped. The mapped result specified by A. The collectorFunc specifies how the collection
As the preceding examples have shown, it is possible (indeed, process works. The collect( ) method is a terminal operation.
is returned.
common) to obtain a stream from a collection.
The following is a simple example of map( ). It provides a variation The Collector interface is declared in java.util.stream, as shown
on the previous example program. As before, the program Sometimes it is desirable to obtain the opposite: to obtain a here:
computes the product of the square roots of the values in an collection from a stream. interface Collector<T, A, R>
ArrayList.
To perform such an action, the stream API provides the collect( ) T, A, and R have the same meanings as just described. Collector
In this version, however, the square roots of the elements are first method. It has two forms. The one we will use first is shown here: specifies several methods, but for the purposes of this chapter, we
mapped to a new stream. Then, reduce( ) is employed to compute won’t need to implement them.
<R, A> R collect(Collector<? super T, A, R> collectorFunc)
the product.
Instead, we will use two of the predefined collectors that are
Refer StreamDemo4, StreamDemo5, StreamDemo6 provided by the Collectors class, which is packaged in
java.util.stream.
The following program shows how to iterate through the elements Here, action specifies the action that is executed on the next When tryAdvance( ) returns false, the iteration is complete. Notice
of a stream. In this case, the strings in an ArrayList are iterated, but element in the iteration. how tryAdvance( ) consolidates the purposes of hasNext( ) and
the process is the same for any type of stream. next( ) provided by Iterator into a single method. This improves the
efficiency of the iteration process.
tryAdvance( ) returns true if there is a next element. It returns false
Refer StreamDemo8 if no elements remain. Consumer declares one method called
accept( ) that receives an element of type T as an argument and The following version of the preceding program substitutes a
returns void. Spliterator for the Iterator: StreamDemo9
In some cases, you might want to perform some action on each One other Spliterator method of particular interest is trySplit( ). It Although splitting the Spliterator in this simple illustration is of no
element collectively, rather than one at a time. splits the elements being iterated in two, returning a new practical value, splitting can be of great value when parallel
Spliterator to one of the partitions. processing over large data sets.
To handle this type of situation, Spliterator provides the
forEachRemaining( ) method, shown here:
The other partition remains accessible by the original Spliterator. It However, in many cases, it is better to use one of the other Stream
default void forEachRemaining(Consumer<? super T> action) is shown here: methods in conjunction with a parallel stream, rather than
Spliterator<T> trySplit( ) manually handling these details with Spliterator.
This method applies action to each unprocessed element and then
returns. For example, assuming the preceding program, the
following displays the strings remaining in the stream: If it is not possible to split the invoking Spliterator, null is Spliterator is primarily for the cases in which none of the
splitItr.forEachRemaining((n) -> System.out.println(n)); returned. Otherwise, a reference to the partition is returned. For predefined methods seems appropriate.
example, here is another version of the preceding program that
Notice how this method eliminates the need to provide a loop to demonstrates trySplit( ):
cycle through the elements one at a time. This is another advantage
of Spliterator. Refer StreamDemo10
References
1. Herbert Schildt, “Java The Complete Reference”, 9th Edition,
McGraw-Hill Education, New Delhi, 2017.
Thank You
An Overview of Java
Q. No. Question BTL Level
3. Discuss the benefits of OOPs. 2
4. Define data abstraction. 1
PART – B
123
An Overview of Java
Q. No. Question BTL Level
3. Explain object-oriented programming principles in detail 2
4. Explain various Java control statements with examples 2
5. Make a comparison of procedural programming paradigm with object-oriented 2
programming paradigm
124
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
String Handling
Q. No. Question BTL Level
1. Summarize String Tokenizer. 2
2. List string manipulation functions of Java string class. 1
3. Differentiate between String and StringBuffer class. 2
Inheritance
Q. No. Question BTL Level
4. Define inheritance. 1
5. List the inheritances supported by Java. 1
6. List out the uses of super keyword. 1
7. What is meant by abstract class? 1
8. Define dynamic method dispatch. 1
PART – B
String Handling
Q. No. Question BTL Level
1. Explain about any five methods present in StringBufferClass with suitable 2
examples.
2. Discuss about any four methods in String class with an example. 2
3. Illustrate the usage of StringTokenizer class. 3
4. Write a short note on String Tokenizer. 2
5. Explain the purpose of the following methods with example. 2
i) ensure capacity () ii) getChars () iii) replace () iv) delete ()
125
Q. No. Question BTL Level
6. Demonstrate the following methods of String class with example. 3
i) toString()
ii) equlas()
iii) indexOf()
iv) trim()
7. Write a Java program to check whether a given string is palindrome or not. 2
Inheritance
Q. No. Question BTL Level
8. Define Inheritance. Explain all the types of inheritance with suitable examples. 2
9. Is multiple inheritance supported by Java? Justify your answer. 2
10. Why doesn’t Java support multiple inheritance? How it can be implemented in 2
Java?
11. What is meant by dynamic method dispatch? Explain with a program. 2
12. Describe about abstract classes and abstract methods with its syntax and write 3
an example to illustrate it.
13. Explain run time polymorphism with an example. 2
14. Describe the mechanism in which Java achieves run time polymorphism. 2
126
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
Exception handling
Q. No. Question BTL Level
1. Write the hierarchy of exception class. 1
2. Differentiate between error and exception. 2
3. List different exception types. 1
4. List out some of the checked exceptions in Java. 1
5. Write the importance of try and catch blocks. 1
6. How many catch blocks and finally blocks can we use with try blocks? Why? 1
7. Is ‘finally’ block compulsory with all try-catch blocks? 1
I/O streams
Q. No. Question BTL Level
8. What does an I/O streams represents? 1
9. What is FileInputStream? 1
10. List two classes of byte and character streams. 1
Multithread Programming
Q. No. Question BTL Level
11. What are the two ways to create thread in java? 1
12. Why are the threads created using runnable interface? 1
13. How can we change the priority of a thread? 1
14. How to assign priorities to threads? 1
15. What is meant by thread priority? 1
PART – B
Exception handling
Q. No. Question BTL Level
1. Demonstrate the various keywords used in exception handling. 3
2. How to create user defined exceptions in Java? Explain with an example. 2
3. Create a user defined exception for student class when the marks obtained by the 3
student exceeds the maximum marks?
127
Q. No. Question BTL Level
4. Explain user defined exceptions and create a user defined exception for 2
validating that the user is eligible to vote or not.
5. Explain exception handling fundamentals and also write an example program to 3
illustrate arithmetic exception.
6. How to handle multiple catch blocks for a nested try block? Explain with an 2
example.
7. What are the uses of ‘throw’ and ‘throws’ clauses for exception handling? 1
8. Write a program to demonstrate user defined exception. 2
I/O streams
Q. No. Question BTL Level
9. Write a Java program to copy contents of one file to another file. 2
10. What is the significance of stream classes in Java? 2
11. Explain CharacterStream hierarchy. 2
12. Differentiate between character streams and byte streams. 2
13. Illustrate FileReader and FileWriter with an example. 3
14. Explain FileInputStream and FileOutputStream with an example. 2
15. Write a Java program to copy the contents of a file to another file using byte 2
streams.
Multithread Programming
Q. No. Question BTL Level
16. What is meant by thread synchronization? How is it implemented in Java? 2
17. Illustrate Java thread model with a neat diagram. 3
18. Explain in detail about thread lifecycle. 2
19. Explain the concept of thread synchronization with an example. 2
20. Describe the mechanism on how thread priorities are used in Java? 2
21. Write short notes on multi-threading in java. 2
22. Summarize the implementation of Thread Priorities in java with an example. 2
23. Describe how to create a thread with an example. 2
24. What is the need of thread synchronization? What is the Java support for this? 2
128
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
Collections Framework
Q. No. Question BTL Level
3. Explain different methods in Set class. 2
4. Why we use set interface? 1
PART – B
Collections Framework
Q. No. Question BTL Level
5. Explain the benefits of the Java collections framework. 2
6. What is vector? How does it differ from array and list? 2
7. What is difference between ArrayList and LinkedList in collection framework? 2
Explain.
129
Q. No. Question BTL Level
8. Explain the following collection classes with suitable examples. 2
i) ArrayList ii) HashList
9. Compare List and Set interfaces with an example. 2
10. Discuss about various methods by which iterators can be implemented in 2
collections.
11. Discuss collections classes and collection interfaces with examples. 2
130
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
An Overview of Java
131
Q. No. Question BTL Level
20. What is an array? 1
21. Why are arrays easier to use compared to a bunch of related variables? 2
PART – B
An Overview of Java
Q. No. Question BTL Level
4. Explain object-oriented paradigm in detail. 2
5. Discuss the general concepts of OOP which form the heart of java language. 2
6. Describe the principal advantages of OOP. 2
132
Q. No. Question BTL Level
8. 2
A group of students has been told to get into teams of a specific size for their
coursework. Design and implement a program that prompts for the number of
students in the group and the size of the teams to be formed and displays how
many teams can be formed and how many students are left without a team.
9. Write a program to take an order for a new computer. The basic system costs 2
375.99. The user then has to choose from a 38 cm screen (costing 75.99) or a 43
cm screen (costing 99.99). The following extras are optional.
Item Price
Antivirus software 65.99
Printer 125.00
10. Using a for loop, write a program that displays a “6 times” multiplication table; 2
the output should look like this:
1×6=6
2 × 6 = 12
3 × 6 = 18
4 × 6 = 24
5 × 6 = 30
6 × 6 = 36
7 × 6 = 42
8 × 6 = 48
9 × 6 = 54
10 × 6 = 60
11 × 6 = 66
12 × 6 = 72
11. Consider the following array declaration, to store a collection of student grades. 2
char [][] grades = new char[4][20];
Grades are recorded for 4 tutorial groups, and each tutorial group consists of 20
students.
a) How many dimensions does this array have?
b) What is the value of grades.length?
c) What is the value of grades[0].length?
d) Write the instruction to record the grade ‘B’ for the first student in the
first tutorial group.
133
Introducing Classes and Objects
Q. No. Question BTL Level
12. Examine the program below and then answer the questions that follow: 2
public class SampleProgram
{
public static void main(String[] args)
{
Oblong oblong1 = new Oblong(3.0, 4.0);
Oblong oblong2 = new Oblong(5.0, 6.0);
System.out.println("The area of oblong1 is " + oblong1.calculateArea());
System.out.println("The area of oblong2 is " + oblong2.calculateArea());
}
}
a) By referring to the program above distinguish between a class and an
object.
b) By referring to the program above explain the purpose of the constructor.
c) By referring to the program above explain how you call the method of
one class from another class.
d) What output would you expect to see from the program above?
134
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
PART – A
String Handling
Q. No. Question BTL Level
1. Java Strings as compared to C strings, are more reliable and predictable. Justify 2
this statement.
2. How does String class differ from the StringBuffer Class? 1
Inheritance
Q. No. Question BTL Level
3. Define a subclass. 1
4. Discuss the uses of subclass constructor. 2
5. Mention the conditions to be followed while using super keyword. 1
135
PART – B
String Handling
Q. No. Question BTL Level
1. Create a method generateUsername that takes a person's first name and last 3
name as input and generates a username based on these names. However, there
are certain rules for generating the username:
The username should consist of the first letter of the first name followed by the
last name.
The generated username should be in lowercase.
For instance:
For the input ("John", "Doe"), the generated username should be "jdoe".
For ("Alice", "Smith"), the generated username should be "asmith".
Implement the generateUsername method using the String constructor in Java.
2. Create a method removeDuplicates that takes a string as input and removes 3
consecutive duplicate characters from the string.
For instance:
For the input string "Hello, World!!", the method should return "Helo, World!"
For "Mississippi", it should return "Misisipi"
You decide to use the StringBuffer class to efficiently manipulate strings.
Implement the removeDuplicates method using the StringBuffer class in Java.
3. Implement a method countWords that takes a sentence as input and counts the 3
number of words present in it.
Your approach is to utilize the StringTokenizer class to break down the sentence
into individual words and then count them.
For example:
For the input "The quick brown fox jumps over the lazy dog.", the method should
return 9.
For "Java programming is fun!", the method should return 4.
Implement the countWords method using the StringTokenizer class in Java.
Inheritance
Q. No. Question BTL Level
4. You've been assigned a task to build a simple system to manage employees 3
within a company. You are required to create a hierarchy of classes representing
different types of employees. The classes should include a base class Employee
and two subclasses Manager and Worker. Each subclass should inherit from
the Employee class.
Your task is to implement the Employee class and its subclasses with appropriate
attributes and methods. For this scenario, consider the following:
The Employee class should have attributes such as name and salary. It should
also contain a method displayInfo() to print the name and salary of the employee.
136
The Manager class should inherit from Employee and have an additional
attribute department. Override the displayInfo() method to include the
department information.
The Worker class should also inherit from Employee and include an attribute
hoursWorked. Override the displayInfo() method to display the name, salary,
and hours worked.
Utilize the super keyword in the overridden methods of the subclasses to call the
corresponding method from the superclass.
Implement the Employee, Manager, and Worker classes as described.
5. Develop a banking application that deals with various types of accounts: 3
SavingsAccount and CurrentAccount. Both account types have a method
named calculateInterest() to calculate the interest specific to each account type.
For SavingsAccount, the interest is calculated based on the balance and a fixed
interest rate, while for CurrentAccount, no interest is provided.
Your task is to create a base class Account and two subclasses SavingsAccount
and CurrentAccount that inherit from Account.
Implement the calculateInterest() method in both subclasses to calculate interest
accordingly:
For SavingsAccount, the interest is 5% of the balance.
For CurrentAccount, there is no interest calculation.
Ensure that the calculateInterest() method is appropriately overridden in the
subclasses based on their specific interest calculation requirements.
6. Develop a virtual pet simulation game where different types of pets can perform 3
unique actions. There are three types of pets: Dog, Cat, and Bird. Each pet has
a method named performAction() that represents a unique action they can do.
The Dog class performs the action "barking".
The Cat class performs the action "meowing".
The Bird class performs the action "singing".
You're required to create a method interactWithPet() in another class Player
that interacts with the pets dynamically. The interactWithPet() method takes an
instance of the Pet class (the superclass of Dog, Cat, and Bird) as a parameter
and calls its performAction() method.
Your task is to implement the Pet class along with its subclasses and the Player
class with the interactWithPet() method, enabling dynamic method dispatch to
perform the unique action based on the pet type passed as a parameter.
7. Develop a drawing application that allows users to create various shapes. Each 3
shape has common properties like area and perimeter, but the calculation of
these properties differs for different shapes.
Your task is to create an abstract class Shape that serves as the base class for
different types of shapes. This class should include abstract methods
calculateArea() and calculatePerimeter().
For Circle, the area is calculated as π * r² and the perimeter as 2 * π * r (where r
is the radius).
137
For Rectangle, the area is calculated as length * width and the perimeter as 2 *
(length + width) (where length and width are sides).
For Triangle, the area is calculated using Heron's formula and the perimeter as
the sum of all three sides.
Implement the Shape class as an abstract class with abstract methods for
calculating area and perimeter. Create concrete subclasses Circle, Rectangle,
and Triangle that extend the Shape class and provide implementations for the
abstract methods.
138
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
PART – A
Exception handling
Q. No. Question BTL Level
1. Write the use of throw, throws, try, catch and finally. 1
2. What are Checked and UnChecked Exceptions? 1
3. What are runtime exceptions? What is the difference between Error and an 1
Exception?
4. How to create custom exceptions? 1
I/O streams
Q. No. Question BTL Level
5. What is an IO Stream? 1
6. List two classes of byte and character streams. 1
7. List the types of streams. 1
Multithread Programming
Q. No. Question BTL Level
8. What is a thread? 1
9. List the two types of multitasking. 1
10. List the methods of a thread class. 1
11. What are interrupting threads? 1
12. What is daemon thread and which method is used to create the daemon thread? 1
13. What are the ways in which you can instantiate a thread? 1
14. How do we start a thread in Java? 2
139
PART – B
Exception handling
Q. No. Question BTL Level
1. Develop a file management system where users can perform various operations 3
on files. Implement exception handling to cover potential issues that might arise
during file operations. Create a FileManager class that includes methods for file
operations: readFileContent(), writeToFile(), and deleteFile(). Implement
these methods to perform the following tasks:
• readFileContent(): Reads the content from a specified file. If the file
doesn't exist or cannot be read, throw a FileReadException.
• writeToFile(): Writes content to a specified file. If the file is not writable or
an error occurs during writing, throw a FileWriteException.
• deleteFile(): Deletes a specified file. If the file doesn’t exist or cannot be
deleted, throw a FileDeleteException.
• Create custom exception classes (FileReadException,
FileWriteException, and FileDeleteException) that extend Java's
Exception class.
• Implement a scenario in the Main class where users attempt to perform these
file operations, catching and handling the specific exceptions thrown by the
FileManager methods.
• Display meaningful error messages or instructions for users in case an
exception is caught.
2. Develop a system for an online shopping platform. The system involves a 3
shopping cart that can hold a maximum of 10 items. To ensure the cart doesn't
exceed its capacity, implement custom exceptions for different scenarios.
• Create a ShoppingCart class that manages the shopping cart functionality.
• Implement an addItem() method in the ShoppingCart class that adds items
to the cart. If the cart is full (contains 10 items) and a user attempts to add
more items, throw a custom CartFullException.
• Implement a removeItem() method in the ShoppingCart class that removes
items from the cart. If the cart is empty and a user tries to remove an item,
throw a custom CartEmptyException.
• Create custom exception classes (CartFullException and
CartEmptyException) that extend Java's Exception class.
• Demonstrate the functionality of the ShoppingCart class by attempting to
add and remove items from the cart in the Main class. Handle the custom
exceptions appropriately to provide feedback to users.
I/O streams
Q. No. Question BTL Level
3. Develop a file copy utility that reads the content from one file and writes it to 3
another file. Implement this utility using InputStream and OutputStream in Java.
140
• Create a FileCopyUtility class that includes methods for copying files.
• Implement a copyFile() method in the FileCopyUtility class that takes two
filenames as input: the source file and the destination file.
• Use FileInputStream to read from the source file and FileOutputStream
to write to the destination file.
• Read the content from the source file using a buffer and write it to the
destination file.
• Ensure proper exception handling for file-related operations such as
opening, reading, and writing files.
• Demonstrate the functionality of the FileCopyUtility class by copying a
source file to a destination file in the Main class.
4. Create a text manipulation tool that performs operations on text files. Develop a
program that reads content from one file, modifies it, and writes the modified
content to another file using FileReader and FileWriter in Java.
• Create a TextManipulator class that includes methods for file
manipulation.
• Implement a manipulateFile() method in the TextManipulator class that
takes two filenames as input: the source file and the destination file.
• Use FileReader to read the content from the source file and FileWriter to
write the modified content to the destination file.
• Read the text from the source file, perform a specific modification (e.g.,
uppercase conversion, adding a prefix or suffix, etc.), and write the modified
content to the destination file.
• Ensure proper exception handling for file-related operations such as
opening, reading, and writing files.
• Demonstrate the functionality of the TextManipulator class by
manipulating a source text file and writing the modified content to a
destination file in the Main class.
Multithread Programming
141
• Ensure that multiple ThreadIncrementer instances are started and execute
concurrently.
• Use synchronization mechanisms to prevent multiple threads from accessing
the increment() method simultaneously, ensuring that each increment
operation is atomic.
6. Develop an application that needs to perform multiple tasks concurrently to 3
improve efficiency. Implement a program that creates multiple threads to execute
various tasks simultaneously.
• Create a TaskExecutor class that manages task execution using threads.
• Implement a method executeTasks(int numTasks) in the TaskExecutor
class that takes an integer parameter numTasks specifying the number of
tasks to execute.
• Inside executeTasks(), create numTasks instances of a Task class that
extends Thread or implements Runnable.
• Each Task should simulate a specific operation (e.g., printing numbers,
performing calculations, etc.) that takes some time to complete.
• Use these Task instances to create and start multiple threads to execute the
tasks concurrently.
• Demonstrate the functionality of the TaskExecutor class by creating and
executing a specified number of tasks concurrently in the Main class.
• Ensure proper handling of concurrency-related issues and proper
termination of threads.
7. Develop a program that utilizes thread priorities to manage and execute these 3
tasks based on their importance.
• Create a TaskManager class responsible for managing tasks and their
execution through threads.
• Implement a method addTask(String taskName, int priority) in the
TaskManager class that adds a new task with a specified name and priority
to the execution queue.
• The priority should be an integer value ranging from 1 to 10, where a higher
number indicates a higher priority (10 being the highest).
• Use Thread or Runnable instances to represent tasks, and assign thread
priorities based on the priority of the tasks added to the TaskManager.
• Implement a method startExecution() in the TaskManager class that starts
the execution of tasks based on their priorities using threads.
• Demonstrate the functionality of the TaskManager class by adding multiple
tasks with different priorities and executing them concurrently in the Main
class.
• Ensure proper handling of thread priorities to execute higher priority tasks
before lower priority ones.
8. Develop a multithreaded bank account management system that ensures safe 3
concurrent access to account balances. Implement a program using synchronized
methods to prevent race conditions and ensure data consistency.
142
• Create a BankAccount class that represents a bank account with a balance
and methods to deposit and withdraw funds.
• Implement synchronized methods deposit() and withdraw() in the
BankAccount class to ensure thread safety when modifying the account
balance.
• The deposit() method should add funds to the account, and the withdraw()
method should deduct funds from the account.
• Develop a TransactionProcessor class responsible for simulating multiple
transactions by executing deposit and withdrawal operations on the bank
account using threads.
• Inside the TransactionProcessor, create multiple threads to perform
concurrent deposit and withdrawal operations on the bank account.
• Demonstrate the functionality of synchronized methods by executing
multiple concurrent transactions in the Main class.
143
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
PART – A
Collections Framework
Q. No. Question BTL Level
7. What is a collection framework? 1
8. List the advantages of Collections framework. 1
9. What is ArrayList? 1
10. What is a HashSet? 1
11. What is HashMap? 1
12. What is TreeMap? 1
144
PART – B
145
Collections Framework
146
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
POs
S. No Advanced Topics or Content beyond the Syllabus CO
&PSOs
Working of JVM, its architecture and working of
1 1 PO1, PO2
execution engine
PO1, PO2, PO3,
2 Evolution of Interfaces 2
PSO1, PSO2
PO1, PO2, PO3,
3 ByteArrayInputStream and ByteArrayOutputStream 3
PSO1, PSO2
PO2, PO3,
4 Generic Functional Interfaces 4 PO5,
PSO1, PSO2
147
VELAGAPUDI RAMAKRISHNA
SIDDHARTHA ENGINEERING COLLEGE
(AUTONOMOUS)
Topics
148