1. What Are Wrapper Classes?
2. Why Wrapper Classes Were Introduced?
3. What Is Autoboxing And Unboxing?
4. When Do Autoboxing And Unboxing Occur ?
5. Why == Operator Works For Integer Value Until 127
Number?
6. Why Integer Wrapper Class Caches This Range ?
7. Can We Increase The IntegerCache Array Range?
8. What Is The MaxSize Of -XX:AutoBoxCacheMax?
9. Do All The Wrapper Classes Support Caching?
10. Why Are Java Wrapper Classes Immutable?
Ref : [Link]
classes/
Wrapper Classes :
The main objectives of wrapper classes are:
1. To wrap primitives into object form so that we can handle primitives also just like objects.
2. To define several utility functions which are required for the primitives.
Java wrapper classes are used to encapsulate primitive data types, allowing
them to be treated as objects. This is essential in Java, an object-oriented
language, where many operations require objects, such as working with
collections or serialization.
Types of Wrapper Classes
Each primitive data type in Java has a corresponding wrapper class:
Primitive Data Type Wrapper Class
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
All most all wrapper classes define the following 2 constructors one can take
corresponding primitive as argument and the other can take String as argument.
Example:
1) Integer i=new Integer(10);
2) Integer i=new Integer("10");
If the String is not properly formatted i.e., if it is not representing number then
we will get runtime exception saying "NumberFormatException".
Example:
class WrapperClassDemo {
public static void main(String[] args)throws Exception {
Integer i=new Integer("ten");
[Link](i);//NumberFormatException
Float class defines 3 constructors with float, String and double arguments.
1) Float f=new Float (10.5f);
2) Float f=new Float ("10.5f");
3) Float f=new Float(10.5);
4) Float f=new Float ("10.5");
Character class defines only one constructor which can take char primitive as
argument there is no String argument constructor.
Character ch=new Character('a');//valid
Character ch=new Character("a");//invalid
Boolean class defines 2 constructors with boolean primitive and String arguments
class WrapperClassDemo {
public static void main(String[] args)throws Exception {
Boolean b1=new Boolean("true");
Boolean b2=new Boolean("True");
Boolean b3=new Boolean("false");
Boolean b4=new Boolean("False");
Boolean b5=new Boolean("ashok");
Boolean b6=new Boolean("TRUE");
[Link](b1);//true
[Link](b2);//true
[Link](b3);//false
[Link](b4);//false
[Link](b5);//false
[Link](b6);//true
Example 2(for exam purpose):
class WrapperClassDemo {
public static void main(String[] args)throws Exception {
Boolean b1=new Boolean("yes");
Boolean b2=new Boolean("no");
[Link](b1);//false
[Link](b2);//false
[Link]([Link](b2));//true
[Link](b1==b2);//false
Utility methods :
1. valueOf() method.
2. XXXValue() method.
3. parseXxx() method.
4. toString() method.
Note :
1) In all wrapper classes toString() method is overridden to return its content.
2) In all wrapper classes .equals() method is overridden for content compression.
Example : Integer i1 = new Integer(10) ;
Integer i2 = new Integer(10);
[Link](i1); //10 [Link]([Link](i2)); //tru
valueOf() method :
We can use valueOf() method to create wrapper object for the given primitive or String
this method is alternative to constructor.
Form 1:
Every wrapper class except Character class contains a static valueOf() method to create
wrapper object for the given String.
public static wrapper valueOf(String s);
Example:
class WrapperClassDemo {
public static void main(String[] args)throws Exception {
Integer i=[Link]("10");
Double d=[Link]("10.5");
Boolean b=[Link]("ashok");
[Link](i);//10
[Link](d);//10.5
[Link](b);//false
Form 2:
Every integral type wrapper class (Byte, Short, Integer, and Long) contains the
following valueOf() method to convert specified radix string to wrapper object.
public static wrapper valueOf(String s , int radix ) ;
//radix means base
Note:
the allowed radix range is 2 to 36.
Form 3 :
Every wrapper class including Character class defines valueOf() method to convert primitive to wrapper
object.
public static wrapper valueOf(primitive p);
Example:
class WrapperClassDemo {
public static void main(String[] args)throws Exception {
Integer i=[Link](10);
Double d=[Link](10.5);
Boolean b=[Link](true);
Character ch=[Link]('a');
[Link](ch);
//a [Link](i);
//10 [Link](d);//10.5 [Link](b);//true } }
xxxValue() method :
We can use xxxValue() methods to convert wrapper object to primitive.
Every number type wrapper class (Byte, Short, Integer, Long, Float, Double) contains
the following 6 xxxValue() methods to convert wrapper object to primitives.
1)public byte byteValue()
2)public short shortValue()
3)public int intValue()
4)public long longValue()
5)public float floatValue()
6)public double doubleValue();
Example:
class WrapperClassDemo {
public static void main(String[] args)throws Exception {
Integer i=new Integer(130);
[Link]([Link]());//-126
[Link]([Link]());//130
[Link]([Link]());//130
[Link]([Link]());//130
[Link]([Link]());//130.0
[Link]([Link]());//130.0
charValue() method:
Character class contains charValue() method to convert Character object to char
primitive.
public char charValue();
Example:
class WrapperClassDemo {
public static void main(String[] args) {
Character ch=new Character('a');
char c=[Link]();
[Link](c);//a
Form 2:
integral type wrapper classes(Byte, Short, Integer, Long) contains the following
parseXxx() method to convert specified radix String form to corresponding primitive.
public static primitive parseXxx(String s,int radix);
The allowed range of redix is : 2 to 36
Example:
class WrapperClassDemo {
public static void main(String[] args) {
int i=[Link]("100",2);
[Link](i);//4
}
toString() method :
We can use toString() method to convert wrapper object (or) primitive to String.
Form 1 :
public String toString();
1. Every wrapper class (including Character class) contains the above toString()
method to convert wrapper object to String.
2. It is the overriding version of Object class toString() method.
3. Whenever we are trying to print wrapper object reference internally this
toString() method only executed.
Example:
class WrapperClassDemo {
public static void main(String[] args) {
Integer i=[Link]("10");
[Link](i);//10
[Link]([Link]());//10
Form 2:
Every wrapper class contains a static toString() method to convert primitive to String.
public static String toString(primitive p);
Example:
class WrapperClassDemo {
public static void main(String[] args) {
String s1=[Link](10);
String s2=[Link](true);
String s3=[Link]('a');
[Link](s1); //10
[Link](s2); //true
[Link](s3); //a
Form 3:
Integer and Long classes contains the following static toString() method to convert the
primitive to specified radix String form.
public static String toString(primitive p, int radix);
Example:
class WrapperClassDemo {
public static void main(String[] args) {
String s1=[Link](7,2);
String s2=[Link](17,2);
[Link](s1);//111
[Link](s2);//10001
Form 4:
Integer and Long classes contains the following toXxxString() methods.
public static String toBinaryString(primitive p);
public static String toOctalString(primitive p);
public static String toHexString(primitive p);
Example:
class WrapperClassDemo {
public static void main(String[] args) {
String s1=[Link](7);
String s2=[Link](10);
String s3=[Link](20);
String s4=[Link](10);
[Link](s1);//111
[Link](s2);//12
[Link](s3);//14
[Link](s4);//a
}
Autoboxing and Autounboxing (1.5v):
Until 1.4 version we can't provide wrapper object in the place of primitive and primitive in the place of
wrapper object all the required conversions should be performed explicitly by the programmer.
But from 1.5 version onwards we can provide primitive value in the place of wrapper and wrapper
object in the place of primitive all required conversions will be performed automatically by compiler.
These automatic conversions are called Autoboxing and Autounboxing.
Autoboxing :
Automatic conversion of primitive to wrapper object by compiler is called Autoboxing.
Example : Integer i=10; [compiler converts "int" to "Integer" automatically by Autoboxing]
After compilation the above line will become. Integer i=[Link](10);
That is internally Autoboxing concept is implemented by using valueOf() method.
Autounboxing :
automatic conversion of wrapper object to primitive by compiler is called Autounboxing.
Example:
Integer I=new Integer(10); Int i=I; [ compiler converts "Integer" to "int" automatically by Autounboxing
]
After compilation the above line will become.
Int i=[Link]();
That is Autounboxing concept is internally implemented by using xxxValue() method.
Byte Stream and Character Stream
Overview
Streams: Provide sequential access to files for reading and writing data.
Two Main Types:
Byte Streams: Handle input/output of 8-bit bytes, mainly for
raw binary data.
Character Streams: Handle input/output of 16-bit Unicode
characters, optimized for text files.
What is Byte Stream in Java?
Byte streams are used to perform input and output of 8-bit bytes. They are used to read bytes
from the input stream and write bytes to the output stream. Mostly, they are used to read or write
raw binary data.
In Java, the byte streams have a 3 phase mechanism:
Split- The input data source is split into a stream by a spliterator. Java Spliterator interface is an
internal iterator that breaks the stream into smaller parts for traversing over them.
Apply- The elements in the stream are processed.
Combine- After the elements are processed, they are again combined together to create a single
result.
Java provides many byte stream classes, but the most common ones are-
FileInputStream- This class is used to read data from a file/source. The FileInputStream class
has constructors which we can use to create an instance of the FileInputStream class.
Syntax : FileInputStream sourceStream = new FileInputStream("path_to_file");
FileOutputStream- This class is used to write data to the destination. The following is
the constructor to create an instance of the FileOutputStream class.
Syntax : FileOutputStream targetStream = new FileOutputStream("path_to_file");
What is Character Stream in Java?
In Java, character values are stored using Unicode conventions. As we saw above, the Byte
stream is used to perform input and output operations of 8-bit bytes, but the Character stream is
used to perform input and output operations of 16-bit Unicode. If we want to copy a text file
containing characters from one source to another destination using streams, character streams
would be advantageous as it deals with characters. Characters in Java are 2 bytes or 16 bits in
size.
In Java, the character streams too have a 3 phase mechanism similar to that of Byte Streams as
explained above.
Java provides many character stream classes, but the most common ones are- FileReader- It is
used to read two bytes at a time from the source. The following is the constructor to create an
instance of the FileReader class.
FileReader in = new FileReader("path_to_file");
FileWriter- It is used to write two bytes at a time to the destination. The following is the
constructor to create an instance of the FileWriter class.
FileWriter in = new FileWriter("path_to_file");
Example of Character Stream
This example deals with the usage of Character Stream to copy the contents of one file to
another. In the example, we will create two objects of the FileReader and the FileWriter classes.
The source and the destination files names are given as parameters to the FileReader and
the FileWriter classes respectively. Then the content of the source file will be copied to the
destination file.
What are Inner Classes?
Inner classes are classes defined inside another class.
Types of Inner Classes Discussed
1. Member Inner Class: A class declared inside another class, similar
to instance variables. It has access to all members of the outer class
(even private ones).
2. Static Nested Class: A static class declared inside another class. It
can access only static members of the outer class.
3. Anonymous Inner Class: A class defined without a name, often
used to create short implementations of interfaces or abstract
classes.
Why Use Inner Classes?
Encapsulation: Helps in grouping classes that are only used in one
place, increasing encapsulation.
Code Organization: Can improve code readability by keeping related
classes together.
Access to Outer Class Members: Inner classes have access to the
members of the outer class, which can be useful in certain situations.
Key Concepts to Consider
Instantiation: Inner classes are typically instantiated with reference
to an instance of the outer class (except for static nested classes).
Access Modifiers: You can use access modifiers
(like private, protected, public) to control the visibility of inner classes.
Anonymous Class
An anonymous class in Java is a type of inner class that is
defined without a name. It is typically used when you
need to provide a one-time implementation of an
interface or extend a class without creating a separate
named class. Anonymous classes are concise and allow
you to define and instantiate the class in a single
expression.
Characteristics of Anonymous Classes
No Name: They are nameless, so they cannot have
constructors.
Single Use: Designed for one-time use, often for short
tasks.
Extend or Implement: They can either extend a class or
implement an interface, but not both simultaneously.
Defined Inline: The class body is defined within an
expression.
lambda expression
Example 1: Lambda Expression with Functional
Interface
Java 8 Stream - Java Stream
a sequence of elements supporting sequential and parallel
aggregate operations
Streams are an abstract layer added in Java 8 that allows
developers to easily manipulate collections of objects or
primitives. It is not a data structure as it does not store data;
rather it serves as a transformative medium from the data
source to its destination
The Stream is often visualized as a pipeline because it acts as
an intermediate step between the source of data, transforms
the data in some way, then outputs it in a new form
downstream.
Stream Operations
Stream operations are divided into two types:
Aggregate operations come in two types; intermediate and
terminal. Each stream has zero or more intermediate
operations and one terminal operation, as well as a data
source at the farthest point upstream, such as an array or list
Intermediate Operations
Intermediate operations take a stream as input and return a
stream after completion, meaning several operations can be
done in a row.
These return another stream and are lazy (executed only when a
terminal operation is invoked). Common examples:
• filter(Predicate) – Filters elements based on a condition.
• map(Function) – Transforms each element.
• flatMap(Function) – Flattens nested structures into a single
stream.
• distinct() – Removes duplicates.
• sorted() – Sorts elements.
Non-Terminal (Intermediate) Operations
These operations process elements in a stream but do not produce a final result. They return a
new stream, allowing further operations to be chained.
Examples:
filter(Predicate<T>) → Filters elements based on a condition.
map(Function<T, R>) → Transforms elements.
sorted() → Sorts the elements.
distinct() → Removes duplicates.
limit(n) → Limits the number of elements.
peek(Consumer<T>) → Used for debugging (does not modify stream elements).
2. Terminal Operations
Terminal operations return something other than a stream,
such as a primitive or an object. This means that while many
intermediate operations can be done in series, there can be
only one terminal operation.
These produce a result or side effect and mark the end of the
stream pipeline. Examples:
• collect() – Converts the stream into a collection or other
data structure.
• reduce(BinaryOperator) – Reduces elements to a single
value.
• forEach(Consumer) – Performs an action on each element.
• count() – Counts elements in the stream.
Creating Streams
Streams can be created from various sources:
1. From collections:
2. From arrays:
3. Using [Link]():
Basic Level
1. Convert a list of integers to a list of their squares using Stream API.
2. Filter out even numbers from a list.
3. Find the first element of a list using streams.
Intermediate Level
4. Find the second highest number in a list using Stream API.
5. Concatenate a list of strings into a single string separated by commas.
6. Count the number of words in a list that start with "A".
7.
Find the sum of all even numbers in a list.
Advanced Level
8. Find the frequency of each character in a given string using Stream API.
9. Find the longest string
in a list.
10. S
ort a list of Employee objects based on salary using Stream API.