Java Unit 4 Notes
Java Unit 4 Notes
Lecture 35
Introduction of Java Collections Framework and I/O
Java Collections Framework (JCF)
The Java Collections Framework (JCF) is a unified architecture for storing and manipulating groups of
objects in Java. It is part of the Java Standard Library and is mainly available in the [Link] package. Before
the introduction of JCF, developers had to create their own data structures. JCF provides ready-made,
efficient, and reusable data structures and algorithms.
They are used to store, search, sort, and organize data more easily - all using standardized methods and
patterns.
Interfaces like List define what tools can do, and classes like ArrayList are the actual tools that do the work.
Overview of Classes
The table below gives an overview of the common data structure classes and their characteristics:
Interface Class Description
ArrayList Resizable array that maintains order and allows duplicates
List
LinkedList List with fast insert and remove operations
HashSet Unordered collection of unique elements
Set TreeSet Sorted set of unique elements (natural order)
LinkedHashSet Maintains the order in which elements were inserted
HashMap Stores key/value pairs with no specific order
Map TreeMap Sorted map based on the natural order of keys
LinkedHashMap Maintains the order in which keys were inserted
Use List classes when you care about order, you may have duplicates, and want to access elements by index.
Use Set classes when you need to store unique values only.
Use Map classes when you need to store pairs of keys and values, like a name and its phone number.
Lecture 37
Definition of List, Set, and Map Interfaces with example
List Interface in Java
The List interface in Java extends the Collection interface and is part of the [Link] package. It is used to
store ordered collections where duplicates are allowed and elements can be accessed by their index.
Maintains insertion order
Allows duplicate elements
Supports null elements (implementation dependent)
Supports bidirectional traversal using ListIterator
import [Link].*;
class Main {
public static void main(String[] args)
{
// Creating a List of Strings using ArrayList
List<String> li = new ArrayList<>();
// Adding elements in List
[Link]("Java");
[Link]("Python");
[Link]("DSA");
[Link]("C++");
[Link]("Elements of List are:");
// Iterating through the list
for (String s : li) {
[Link](s);
}
}
}
Output
Elements of List are:
Java
Python
DSA
C++
Explanation: This Java program demonstrates how to create a List using ArrayList, add elements to it,
and iterate through the list to print each element. It uses an enhanced for loop to display all the stored
programming languages.
1. Adding Elements
To add an element to the list, we can use the add() method. This method is overloaded to perform multiple
operations based on different parameters.
add(Object o): This method is used to add an element at the end of the List.
add(int index, Object o): This method is used to add an element at a specific index in the List
import [Link].*;
class Main {
public static void main(String args[])
{
List<String> al = new ArrayList<>();
// Adding elements to object of List interface Custom elements
[Link]("Python");
[Link]("Java");
[Link](1, "PHP");
[Link](al);
}
}
Output
[Python, PHP, Java]
Note: If we try to add element at index 1 before adding elements at index 0 it will throw an error. It is
always recommended to add elements in a particular index only when the size is defined or to add them
sequentially.
2. Updating Elements
To update an element in a list, use the set() method with the target index and the new value. Since List is
indexed, the element is replaced at the specified position.
import [Link].*;
class Main {
public static void main(String args[])
{
// Creating an object of List interface
List<String> al = new ArrayList<>();
Output
Initial ArrayList [Python, C++, PHP]
Updated ArrayList [Python, Java, PHP]
3. Searching Elements
Searching in a List can be done using indexOf(), lastIndexOf() methods.
indexOf(Object o): It returns the index of the first occurrence of the specified element in the list or -1
if the element is not found
lastIndexOf(Object o): It returns the index of the last occurrence of the specified element in the list or
-1 if the element is not found
import [Link].*;
class Main {
Output
First Occurrence of 2 is at Index: 1
Last Occurrence of 2 is at Index: 3
4. Removing Elements
To remove an element from a list, we can use the remove() method. This method is overloaded to perform
multiple operations based on different parameters.
remove(Object o): Removes the first occurrence of the specified object from the list.
remove(int index): Removes the element at the specified index and shifts subsequent elements left.
import [Link];
import [Link];
class Main {
// Now remove element from the above list present at 1st index
[Link](1);
[Link]("After the Index Removal " + al);
Output
Initial ArrayList [Python, Java, PHP]
After the Index Removal [Python, PHP]
After the Object Removal [Python]
5. Accessing Elements
To access an element in the list, we can use the get() method, which returns the element at the specified
index.
get(int index): This method returns the element at the specified index in the list.
import [Link].*;
class Main {
public static void main(String args[])
{
List<String> al = new ArrayList<>();
// Adding elements to object of List interface
[Link]("Python");
[Link]("Java");
[Link]("PHP");
[Link](first);
[Link](second);
[Link](third);
[Link](al);
}
}
Output
Python
Java
PHP
[Python, Java, PHP]
import [Link].*;
class Main {
Output
Is Python present in the list? true
import [Link].*;
Output
Python Java PHP
Python Java PHP
List vs Set
Both the List interface and the Set interface inherits the Collection interface. However, there exists some
differences between them.
List Set
The List is an ordered sequence. The Set is an unordered sequence.
List allows duplicate elements Set doesn’t allow duplicate elements.
Elements by their position can be accessed. Position access to elements is not allowed.
Multiple null elements can be stored. The null element can store only once.
List implementations are ArrayList, LinkedList, Set implementations are HashSet, LinkedHashSet.
Vector, Stack
Set
In Java, the Set interface is a part of the Java Collection Framework, located in the [Link] package. It
represents a collection of unique elements, meaning it does not allow duplicate values.
The set interface does not allow duplicate elements.
It can contain at most one null value except TreeSet implementation which does not allow null.
The set interface provides efficient search, insertion, and deletion operations.
import [Link];
import [Link];
// Main class
class Main {
[Link]("B");
[Link]("B");
[Link]("C");
[Link]("A");
[Link](s);
}
}
Output
[A, B, C]
2. Accessing the Elements
After adding the elements, if we wish to access the elements, we can use inbuilt methods like contains().
import [Link].*;
class Main {
[Link]("A");
[Link]("B");
[Link]("C");
[Link]("A");
String s = "D";
Output
Set is [A, B, C]
Contains D false
3. Removing Elements
The values can be removed from the Set using the remove() method.
import [Link].*;
class Main {
Output
Initial HashSet [A, B, C, D, E]
After removing element [A, C, D, E]
4. Iterating elements
There are various ways to iterate through the Set. The most famous one is to use the enhanced for loop.
import [Link].*;
class Main {
[Link]();
}
}
Output
A, B, C, D, E,
Methods of Set Interface
Let us discuss methods present in the Set interface provided below in a tabular format below as follows:
Method Description
add(element) Adds element if not already present. Returns true if added.
addAll(collection) Adds all elements from the given collection.
clear() Removes all elements from the set.
contains(element) Checks if the set contains the specified element.
containsAll(collection) Checks if the set contains all elements from the given collection.
hashCode() Returns the hash code of the set.
isEmpty() This method is used to check whether the set is empty or not.
iterator() This method is used to return the iterator of the set.
remove(element) Removes the specified element from the set.
removeAll(collection) Removes all elements in the given collection from the set.
retainAll(collection) Retains only elements present in the given collection.
size() Returns the number of elements in the set.
This method is used to form an array of the same elements as that
toArray()
of the Set.
Map:
In Java, the Map Interface is part of the [Link] package and represents a collection of key-value pairs,
where Keys should be unique, but values can be duplicated.
It provides efficient retrieval, insertion, and deletion operations based on keys.
HashMap and LinkedHashMap allow one null key, and TreeMap does NOT allow null keys (if natural
ordering is used).
Use ConcurrentHashMap for thread-safe operations, or [Link]() to make an
existing map synchronized.
Declaration of the Map interface
public interface Map<K, V>
K -> Type of keys maintained by the map
V -> Type of mapped values
Creating Map Objects
Since a Map is an interface, we cannot create its object directly. We must use a class that implements it
(e.g., HashMap).
Map<String, Integer> hm = new HashMap<>();
import [Link];
import [Link];
Output
Map elements: {Geek3=3, Geek2=2, Geek1=1}
Hierarchy of Map
It is part of the Java Collections Framework, and its key implementation classes
include HashMap, LinkedHashMap, TreeMap, and Hashtable.
1. Adding Elements
Use the put() method to add elements to a Map. In HashMap, insertion order isn’t preserved, each element
is stored based on its hash for faster access.
import [Link].*;
class Main {
// Inserting elements
[Link](1, "Python");
[Link](2, "Java");
[Link](3, "PHP");
[Link](hm1);
[Link](hm2);
}
}
Output
{1=Python, 2=Java, 3=PHP}
{1=Python, 2=Java, 3=PHP}
2. Changing Element
To update a value, use the put() method with the same key. The new value replaces the old one for that
key.
import [Link].*;
class Main {
public static void main(String args[])
{
Output
Initial Map: {1=Python, 2=C++, 3=PHP}
Updated Map: {1=Python, 2=Java, 3=PHP}
3. Removing Elements
To remove an element from the Map, we can use the remove() method. This method takes the key value
and removes the mapping for a key from this map if it is present in the map.
import [Link].*;
class Main{
[Link](hm1);
[Link](new Integer(4));
[Link](hm1);
}
}
Output
{1=Python, 2=Java, 3=PHP, 4=C++}
{1=Python, 2=Java, 3=Java}
4. Iterating through the Map
There are multiple ways to iterate through the Map. The most famous way is to use a for-each loop and
get the keys. The value of the key is found by using the getValue() method.
import [Link].*;
class Java{
public static void main(String args[]){
Output
1 : Python
2 : Java
3 : PHP
Lecture 38
Definition of ArrayList, LinkedList with example
ArrayList:
ArrayList in Java is a resizable array provided in the [Link] package. Unlike normal arrays, its size can
grow or shrink dynamically as elements are added or removed.
Elements can be accessed using their index, just like arrays.
Duplicate elements are allowed.
Elements are stored in the order they are inserted.
ArrayList is not thread-safe. To make it thread-safe, you must wrap it manually
using [Link]().
import [Link];
class Main {
public static void main (String[] args) {
// Creating an ArrayList
ArrayList<Integer> a = new ArrayList<Integer>();
// Printing ArrayList
[Link](a);
}
}
Output
[1, 2, 3]
Explanation: This program creates an ArrayList of integers, adds elements to it using the add() method,
and stores them dynamically. Finally, it prints the elements in insertion order as [1, 2, 3].
Hierarchy of ArrayList
It implements List Interface which is a sub-interface of Collection Interface.
3. ArrayList(int initialCapacity)
This constructor is used to build an array list with the initial capacity being specified.
ArrayList<Double> arr = new ArrayList<>(20);
Operations of ArrayList
Now, Using the constructors we have got ArrayList for further operations like Insertion,Deletion and
Updation of the elements in ArrayList.
import [Link].*;
class Main{
Output
Original List : [Python, PHP]
After Adding element at index 1 : [Python, Java, PHP]
Element removed from index 0 : [Java, PHP]
Element PHP removed : [Java]
List after updation of value : [C++]
LinkedList:
LinkedList is a part of the Java Collections Framework and is present in the [Link] package. It
implements a doubly linked list where elements are stored as nodes containing data and references to the
previous and next nodes, rather than in contiguous memory locations.
The size of the LinkedList can grow or shrink dynamically at runtime.
Maintains the order in which elements are inserted.
Multiple duplicate elements can be stored.
LinkedList is not thread-safe by default; it can be synchronized using [Link]().
Provides better performance than ArrayList for insertion and deletion operations, especially at the
beginning or middle.
import [Link];
// Creating a LinkedList
LinkedList<String> l = new LinkedList<String>();
[Link](l);
}
}
Output
[One, Two, Three, Four, Five]
Explanation:
Creates an empty LinkedList of Strings.
Adds elements "One" to "Five" using the add() method.
Prints the LinkedList showing elements in insertion order: [One, Two, Three, Four, Five].
Note: LinkedList nodes cannot be accessed directly by index; elements must be accessed by traversing
from the head.
Hierarchy of LinkedList
It implements the List and Deque interfaces, both of which are sub-interfaces of the Collection Interface.
Constructors of LinkedList
In order to create a LinkedList, we need to create an object of the LinkedList class. The LinkedList class
consists of various constructors that allow the possible creation of the list. The following are the
constructors available in this class:
1. LinkedList()
This constructor is used to create an empty linked list. If we wish to create an empty LinkedList with the
name list, then it can be created as:
LinkedList list = new LinkedList();
2. LinkedList(Collection C)
This constructor is used to create an ordered list that contains all the elements of a specified collection, as
returned by the collection's iterator. If we wish to create a LinkedList with the name list, then, it can be
created as:
LinkedList list = new LinkedList(C);
import [Link].*;
[Link]("Python");
[Link]("PHP");
[Link](1, "Java");
[Link](ll);
}
}
Output
[Python, Java, PHP]
2. Update Elements
With the help of the set() method, we can update an element in a LinkedList. This method takes an index
and the updated element which needs to be inserted at that index.
import [Link].*;
[Link]("Python");
[Link]("PHP");
[Link](1, "C++");
[Link](1, "Java");
Output
Initial LinkedList [Python, C++, PHP]
Updated LinkedList [Python, Java, PHP]
3. Removing Elements
Removes the first occurrence of the specified element from the list, if it exists. They are:
remove(Object): Removes the first occurrence of the specified object from the LinkedList.
remove(int index): Removes the element at the given index and shifts subsequent elements.
import [Link].*;
[Link]("Python");
[Link]("PHP");
[Link](1, "Java");
// Function call
[Link](1);
[Link]("Python");
Output
Initial LinkedList [Python, Java, PHP]
After the Index Removal [Python, PHP]
After the Object Removal [PHP]
4. Iterating a LinkedList
There are multiple ways to iterate through LinkedList. The most famous ways are by using the basic for
loop in combination with a get() method to get the element at a specific index and the advanced for-loop.
import [Link].*;
[Link]("Python");
[Link]("PHP");
[Link](1, "Java");
[Link]();
Output
Python Java PHP
Python Java PHP
ArrayList vs LinkedList
ArrayList LinkedList
Underlying structure is Dynamic Array Underlying structure is Doubly-linked list
O(1) - Fast random access O(n) - Slow random access
Memory is lower (contiguous memory) Memory is higher (extra pointers per node)
Iteration speed is faster Iteration speed is slower.
Insertion and deletion is slower Insertion and deletion is faster.
Lecture 39
Definition of HashSet, TreeSet, HashMap, and TreeMap with
example
HashSet:
HashSet in Java implements the Set interface of the Collections Framework. It is used to store the unique
elements, and it doesn't maintain any specific order of elements.
HashSet does not allow duplicate elements.
Uses HashMap internally which is an implementation of hash table data structure.
Also implements Serializable and Cloneable interfaces.
HashSet is not thread-safe. To make it thread-safe, synchronization is needed externally.
import [Link].*;
class Main
{
public static void main(String[] args)
{
// Instantiate an object of HashSet
HashSet<Integer> hs = new HashSet<>();
// Adding elements
[Link](1);
[Link](2);
[Link](1);
Output
HashSet Size: 2
Elements in HashSet: [1, 2]
Capacity of HashSet
Capacity refers to the number of buckets in the hash table. The default capacity of a HashSet is 16 and the
load factor is 0.75.
When the number of elements exceeds the capacity automatically increases (resizes) to maintain
performance.
new capacity = old capacity × 2
Load Factor
Load Factor is a measure that controls how full the HashSet can get before resizing. Default Load Factor =
0.75. If the number of elements exceeds the threshold, the capacity is doubled.
Threshold = capacity × load factor
1. HashSet()
Creates a new empty HashSet with default capacity (16) and load factor (0.75).
HashSet<String> set = new HashSet<>();
2. HashSet(int initialCapacity)
Creates an empty HashSet with the specified initial capacity and default load factor (0.75).
HashSet<Type> set = new HashSet<>(int initialCapacity);
import [Link].*;
class Main
{
public static void main(String[] args)
{
// Creating an empty HashSet of string entities
HashSet<String> hs = new HashSet<String>();
Output
HashSet : [Python, Java, PHP]
import [Link].*;
class Main
{
public static void main(String[] args)
{
Output
HashSet : [Python, Java, PHP, C++, C, Basic]
HashSet after removing element [Python, Java, PHP, C++, Basic]
C exists in Set : false
import [Link];
import [Link];
// Traversing HashSet
while ([Link]())
[Link]([Link]() + ", ");
[Link]();
// Using enhanced for loop to iterate Over the HashSet
[Link]("Using enhanced for loop : ");
for (String element : hs)
[Link](element + " , ");
}
}
Output
Using iterator : Java, Basic, C++, C, PHP, Python,
Using enhanced for loop : Java, Basic, C++, C, PHP, Python ,
Methods of HashSet
Method Description
add(E e) Used to add the specified element if it is not present, if it is present then
return false.
clear() Used to remove all the elements from the set.
contains(Object o) Used to return true if an element is present in a set.
remove(Object o) Used to remove the element if it is present in set.
iterator() Used to return an iterator over the element in the set.
isEmpty() Used to check whether the set is empty or not. Returns true for empty and
false for a non-empty condition for set.
size() Used to return the size of the set.
clone() Used to create a shallow copy of the set.
TreeSet:
A TreeSet is a collection class that stores unique elements in a sorted order. It is part of [Link]
package that implements the SortedSet interface, and internally uses a Red-Black tree to maintain sorting.
Does not allow duplicates and null values. From JDK 7 onward, inserting null throws
NullPointerException.
Implements the NavigableSet interface and provides navigation methods like higher(), lower(),
ceiling() and floor().
TreeSet is not synchronized. it must be synchronized using [Link]().
import [Link];
Output
TreeSet elements: []
Constructors of TreeSet
In order to create a TreeSet, we need to create an object of the TreeSet class. The TreeSet class consists of
various constructors which allow the possible creation of the TreeSet. The following are the constructors
available in this class:
1. TreeSet()
Creates an empty TreeSet that sorts elements in their natural order
TreeSet ts = new TreeSet();
2. TreeSet(Comparator)
This constructor is used to build an empty TreeSet object in which elements will need an external
specification of the sorting order.
TreeSet ts = new TreeSet(Comparator comp);
3. TreeSet(Collection)
Creates a TreeSet containing all elements from the given collection, stored in their natural sorted order. It
is useful for converting a collection to a TreeSet.
TreeSet t = new TreeSet(Collection col);
4. TreeSet(SortedSet)
Creates a TreeSet containing the same elements and order as the specified SortedSet.
TreeSet t = new TreeSet(SortedSet s);
1. Adding Elements
To add elements to a TreeSet, use the add() method. Elements are stored in ascending order, duplicates are
ignored, and null values are not allowed.
import [Link].*;
class Main {
public static void main(String[] args)
{
// Creating a Set interface with reference to TreeSet class
Set<String> ts = new TreeSet<>();
Output
[Python, Java, PHP]
import [Link].*;
class Main {
Output
Tree Set is [Java, PHP, python]
Contains python true
First Value Java
Last Value python
Higher python
Lower PHP
import [Link].*;
class Main {
Output
Initial TreeSet [C, C++, Java, OOPs, PHP, Python]
After removing element [C++, Java, OOPs, PHP, Python]
After removing first [Java, OOPs, PHP, Python]
After removing last [Java, OOPs, PHP]
4. Iterating the TreeSet
There are various ways to iterate through the TreeSet. The most famous one is to use the enhanced for
loop.
import [Link].*;
class Main{
[Link]();
}
}
Output
Basic, C, C++, Java, PHP, Python,
import [Link].*;
class Main {
Output
[1, A, B, L, O, Z]
Methods of TreeSet
Method of TreeSet Class are depicted below in tabular format which later on we will be implementing to
showcase in the implementation part.
Method Description
add(Object o) Adds element in sorted order; ignores duplicates.
addAll(Collection c) Adds all elements from a collection; ignores duplicates..
ceiling?(E e) This method returns the least element in this set greater than or equal to the
given element, or null if there is no such element.
clear() This method will remove all the elements.
clone() The method is used to return a shallow copy of the set, which is just a simple
copied set.
Comparator This method will return the Comparator used to sort elements in TreeSet or it
comparator() will return null if the default natural sorting order is used.
contains(Object o) This method will return true if a given element is present in TreeSet else it will
return false.
descendingIterator?() This method returns an iterator over the elements in this set in descending order.
descendingSet?() This method returns a reverse order view of the elements contained in this set.
first() This method will return the first element in TreeSet if TreeSet is not null else it
will throw NoSuchElementException.
floor?(E e) This method returns the greatest element in this set less than or equal to the
given element, or null if there is no such element.
headSet(Object This method will return elements of TreeSet which are less than the specified
toElement) element.
higher?(E e) This method returns the least element in this set strictly greater than the given
element, or null if there is no such element.
isEmpty() This method is used to return true if this set contains no elements or is empty and
false for the opposite case.
Iterator iterator() Returns an iterator for iterating over the elements of the set.
last() This method will return the last element in TreeSet if TreeSet is not null else it
will throw NoSuchElementException.
lower?(E e) This method returns the greatest element in this set strictly less than the given
element, or null if there is no such element.
pollFirst?() This method retrieves and removes the first (lowest) element, or returns null if
this set is empty.
pollLast?() This method retrieves and removes the last (highest) element, or returns null if
this set is empty.
remove(Object o) It returns true/false whether the element was removed
size() This method is used to return the size of the set or the number of elements
present in the set.
spliterator() This method creates a late-binding and fail-fast Spliterator over the elements in
this set.
subSet(Object This method will return elements ranging from fromElement to toElement.
fromElement, Object fromElement is inclusive and toElement is exclusive.
toElement)
tailSet(Object This method will return elements of TreeSet which are greater than or equal to
fromElement) the specified element.
HashMap:
A HashMap is a part of Java’s Collection Framework and implements the Map interface. It stores
elements in key-value pairs, where, Keys are unique. and Values can be duplicated.
Internally uses Hashing, hence allows efficient key-based retrieval, insertion, and removal with an
average of O(1) time.
HashMap is not thread-safe, to make it synchronized, use [Link]().
Insertion order is not preserved in HashMap. To preserve the insertion order, LinkedHashMap is used
and to maintain sorted order, TreeMap is used.
HashMap Declaration;
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable,
Serializable
import [Link];
import [Link];
// Create a HashMap
HashMap<String, Integer> hashMap = new HashMap<>();
Output
John -> 25
Jane -> 30
Jim -> 35
Hierarchy of HashMap in Java
It extends AbstractMap and implements the Map Interface.
Capacity of HashMap
The capacity of a HashMap is the number of buckets it can hold for storing entries.
new capacity=old capacity×2
Default capacity: Default capacity of hashmap is 16.
Load factor: 0.75 (default): when 75% of the capacity is filled, the capacity is doubled.
Constructors of HashMap
HashMap provides 4 constructors and the access modifier of each is public.
1. HashMap()
It is the default constructor which creates an instance of HashMap with an initial capacity of 16 and a load
factor of 0.75.
HashMap<K, V> hm = new HashMap<K, V>();
2. HashMap(int initialCapacity)
It creates a HashMap instance with a specified initial capacity and load factor of 0.75.
HashMap<K, V> hm = new HashMap<K, V>(int initialCapacity);
3. HashMap(int initialCapacity, float loadFactor)
It creates a HashMap instance with a specified initial capacity and specified load factor.
HashMap<K, V> hm = new HashMap<K, V>(int initialCapacity, float loadFactor);
4. HashMap(Map map)
It creates an instance of HashMap with the same mappings as the specified map.
HashMap<K, V> hm = new HashMap<K, V>(Map map);
import [Link].*;
import [Link].*;
class AddElementsToHashMap {
public static void main(String args[])
{
// No need to mention the Generic type twice
HashMap<Integer, String> hm1 = new HashMap<>();
[Link](1, "Python");
[Link](2, "Java");
[Link](3, "PHP");
import [Link].*;
import [Link].*;
class ChangeElementsOfHashMap {
public static void main(String args[])
{
// Initialization of a HashMap
HashMap<Integer, String> hm
= new HashMap<Integer, String>();
[Link](2, "Java");
Output
Initial Map {1=Python, 2=C, 3=PHP}
Updated Map {1=Python, 2=Java, 3=PHP}
import [Link].*;
import [Link].*;
class RemoveElementsOfHashMap{
public static void main(String args[])
{
// Initialization of a HashMap
Map<Integer, String> hm = new HashMap<Integer, String>();
// Initial HashMap
[Link]("Mappings of HashMap are : "+ hm);
// Final HashMap
[Link]("Mappings after removal are : "+ hm);
}
}
Output
Mappings of HashMap are : {1=Python, 2=Java, 3=PHP, 4=C}
Mappings after removal are : {1=Python, 2=Java, 3=PHP}
import [Link];
import [Link];
Output
Key: vaibhav Value: 20
Key: vishal Value: 10
Key: sachin Value: 30
Methods of HashMap
K – The type of the keys in the map.
V – The type of values mapped in the map.
Method Description
clear() Removes all of the mappings from this map.
clone() Returns a shallow copy of this HashMap instance.
compute(K key, BiFunction<? super K,?
Attempts to compute a mapping for the specified key and its
super V,? extends V>
current mapped value
remappingFunction)
computeIfAbsent(K key,
Function<?super K,? extends V> Adds computed value if key absent/null.
mappingFunction)
computeIfPresent(K key, BiFunction<? If the value for the specified key is present and non-null,
super K,? super V,? extends V> attempts to compute a new mapping given the key and its
remappingFunction) current mapped value.
Returns true if this map contains a mapping for the specified
containsKey(Object key)
key.
Returns true if this map maps one or more keys to the specified
containsValue(Object value)
value.
entrySet() Returns a Set view of the mappings contained in this map.
Returns the value to which the specified key is mapped, or null
get(Object key)
if this map contains no mapping for the key.
isEmpty() Returns true if this map contains no key-value mappings.
keySet() Returns a Set view of the keys contained in this map.
merge(K key, V value, BiFunction<?
If the specified key is not already associated with a value or is
super V,? super V,? extends V>
associated with null, associate it with the given non-null value.
remappingFunction)
Associates the specified value with the specified key in this
put(K key, V value)
map.
putAll(Map<? extends K,? extends V>
Copies all of the mappings from the specified map to this map.
m)
Removes the mapping for the specified key from this map if
remove(Object key)
present.
size() Returns the number of key-value mappings in this map.
values() Returns a Collection view of the values contained in this map.
TreeMap
A TreeMap in Java is a part of the [Link] package that implements the Map interface. It stores key-value
pairs in a sorted order using either a natural or custom comparator.
TreeMap internally uses a Red-Black Tree for efficient sorting.
Provides O(log n) time for insertion, deletion and lookup.
TreeMap does not allow null keys, but allows null values.
import [Link];
import [Link];
Output
TreeMap elements: {}
Hierarchy of TreeMap
Hierarchy-TreeMap
Constructors of TreeMap
In order to create a TreeMap, we need to create an object of the TreeMap class. The TreeMap class
consists of various constructors that allow the possible creation of the TreeMap. The following are the
constructors available in this class:
1. TreeMap()
This constructor is used to build an empty TreeMap that will be sorted by using the natural order of its
keys.
Syntax:
TreeMap<K, V> map = new TreeMap<>();
import [Link].*;
[Link](
"TreeMap using TreeMap() constructor");
// Calling constructor
Constructor();
}
}
Output
TreeMap using TreeMap() constructor
TreeMap: {10=Python, 15=Java, 20=PHP}
2. TreeMap(Comparator comp):
This constructor is used to build an empty TreeMap object in which the elements will need an external
specification of the sorting order.
Syntax:
TreeMap<K, V> map = new TreeMap<>(Comparator<? super K> comparator);
import [Link].*;
class Student{
int rollno;
String name, address;
[Link] = rollno;
[Link] = name;
[Link] = address;
}
// Comparator class
class SortByRoll implements Comparator<Student>{
Output
TreeMap sorted by roll number: {111 Java1 New York=1, 121 Java3 Paris=3, 131 Java2 London=2}
3. TreeMap(Map M)
This constructor is used to initialize a TreeMap with the entries from the given map M which will be
sorted by using the natural order of the keys.
Syntax:
TreeMap<K, V> map = new TreeMap<>(Map<? extends K, ? extends V> m);
import [Link].*;
import [Link].*;
[Link](10, "Python");
[Link](20, "Java");
[Link](30, "PHP");
Output
TreeMap using TreeMap(Map) Constructor
TreeMap: {10=Python, 20=Java, 30=PHP}
import [Link].*;
class Main {
// Initialization of TreeMap
TreeMap<Integer, String> tm = new TreeMap<>();
Output
TreeMap with raw type: {1=Python, 2=Java, 3=PHP}
TreeMap with generics: {1=Java, 2=Programming, 3=Language}
2. Changing Elements
To change the element in a TreeMap, simply use the put() method again with the same key and the new
value.
import [Link].*;
class Main{
[Link](tm);
[Link](2, "Python");
[Link](tm);
}
}
Output
{1=Java, 2=C++, 3=PHP}
{1=Java, 2=Python, 3=PHP}
3. Removing Element
We can use the remove() method to remove element from the TreeMap.
import [Link].*;
class Main{
[Link](tm);
[Link](tm);
}
}
Output
{1=Python, 2=C++, 3=Java, 4=JS}
{1=Python, 2=C++, 3=Java}
4. Iterating Elements
There are multiple ways to iterate through the Map. The most famous way is to use a for-each loop and
get the keys. The value of the key is found by using the getValue() method.
import [Link].*;
class Main {
// Initialization of TreeMap
TreeMap<Integer, String> tm = new TreeMap<>();
// Inserting elements
[Link](3, "Python");
[Link](2, "Java");
[Link](1, "PHP");
Output
1 : python
2 : Java
3 : PHP
Methods of TreeMap
Method Action Performed
clear() The method removes all mappings from this TreeMap and clears the map.
clone() The method returns a shallow copy of this TreeMap.
containsKey(Object key) Returns true if this map contains a mapping for the specified key.
containsValue(Object value) Returns true if this map maps one or more keys to the specified value.
entrySet() Returns a set view of the mappings contained in this map.
firstKey() Returns the first (lowest) key currently in this sorted map.
get(Object key) Returns the value to which this map maps the specified key.
The method returns a view of the portion of the map strictly less than the
headMap(Object key_value)
parameter key_value.
keySet() The method returns a Set view of the keys contained in the treemap.
lastKey() Returns the last (highest) key currently in this sorted map.
put(Object key, Object value) The method is used to insert a mapping into a map.
putAll(Map map) Copies all of the mappings from the specified map to this map.
remove(Object key) Removes the mapping for this key from this TreeMap if present.
size() Returns the number of key-value mappings in this map.
subMap(K startKey, K The method returns the portion of this map whose keys range from
endKey) startKey, inclusive, to endKey, exclusive.
values() Returns a collection view of the values contained in this map.
Lecture 40
Iterators and ListIterators with example
Iterators:
The Iterable interface was introduced in JDK 1.5. It belongs to [Link] package. In general, an object
Implementing Iterable allows it to be iterated. An iterable interface allows an object to be the target
of enhanced for loop(for-each loop).
Definition of Iterable
public interface Iterable<T>
{
Iterator<T> iterator();
Spliterator<T> spliterator();
Ways of Iterating
There are three ways in which objects of Iterable can be iterated.
1. Using enhanced for loop(for-each loop)
2. Using Iterable forEach loop
3. Using Iterator<T> interface
import [Link].*;
import [Link].*;
class IterateUsingEnhancedForLoop {
public static void main (String[] args) {
// create a list
List<String> list = new ArrayList<String>();
// add elements
[Link]("Python");
[Link]("Java");
[Link]("PHP");
Output
Python
Java
PHP
import [Link].*;
import [Link].*;
class IterateUsingforEach {
public static void main(String[] args)
{
// create a list
List<String> list = new ArrayList<>();
Output
python
Java
PHP
import [Link].*;
import [Link].*;
class IterateUsingIterator {
public static void main(String[] args)
{
List<String> list = new ArrayList<>();
[Link]("Python");
[Link]("Java");
[Link]("PHP");
Iterator<String> iterator = [Link]();
while ([Link]()) {
String element = [Link]();
[Link](element);
}
}
}
Output
Python
Java
PHP
Methods of Iterable
METHOD DESCRIPTION
forEach(Consumer<? Performs the given action for each element of the Iterable until all elements
super T> action) have been processed or the action throws an exception.
iterator() Returns an iterator over elements of type T.
spliterator() Creates a Spliterator over the elements described by this Iterable.
ListIterators:
ListIterator is a type of Java cursor used to traverse all types of lists, such as ArrayList, LinkedList,
Vector, and Stack. It was introduced in Java 1.2 and extends the Iterator interface.
It works only with list-implemented classes.
It supports bi-directional traversal (forward & backward).
Supports Create, Read, Update, Delete (CRUD) operations.
Declaration of ListIterator
public interface ListIterator<E> extends Iterator<E>
Where E represents the generic type, i.e, any parameter of any type/user-defined object.
import [Link].*;
[Link]("Welcome");
[Link]("To");
[Link]("Goa");
// Getting ListIterator
ListIterator<String> namesIterator = [Link]();
Output
Welcome
To
Goa
Welcome
To
Goa
Hierarchy of ListIterator
It extends Iterator, which in turn extends the Collection traversal mechanism under the [Link] package.
import [Link].*;
// Getting ListIterator
ListIterator<String> listIterator = [Link]();
// Traversing elements
[Link]("Forward Direction Iteration:");
while ([Link]()) {
[Link]([Link]());
}
Output
Forward Direction Iteration:
learn
from
Tutorial
Backward Direction Iteration:
Tutorial
from
learn
Methods of ListIterator
Method Description
add(E e) This method inserts the specified element into the list.
hasNext() This returns true if the list has more elements to traverse.
This returns true if the list iterator has more elements while traversing the list in the
hasPrevious()
backward direction.
next() This method returns the next element and increases the cursor by one position.
This method returns the index of the element which would be returned on calling the
nextIndex()
next() method.
This method returns the previous element of the list and shifts the cursor one position
previous()
backward
This method returns the index of the element which would be returned on calling the
previousIndex()
previous() method.
This method removes the last element from the list that was returned on calling next() or
remove()
previous() method element from.
This method replaces the last element that was returned on calling next() or previous()
set(E e)
method with the specified element.
Lecture 41
Definition of File I/O:, File Class and Methods with example
The File class in Java is used to represent the path of a file or folder. It helps in creating, deleting, and
checking details of files or directories, but not in reading or writing data. It acts as an abstract
representation of file and directory names in the system.
Can retrieve parent directories using the getParent() method.
A File object is created by passing a file or directory name to its constructor.
File systems may impose access permissions (read, write, execute).
File objects are immutable. Once created, their pathname cannot change.
How to Create a File Object
A File object is created by passing in a string that represents the name of a file, a String or another File
object.
Syntax
File file = new File("path_to_file");
if ([Link]()) {
[Link]("Is writable:" + [Link]());
[Link]("Is readable" + [Link]());
[Link]("Is a directory:" + [Link]());
[Link]("File Size in bytes " + [Link]());
}
}
}
Output:
Display All Contents of a Directory
This program displays all files and subdirectories inside a given directory using the list() method.
import [Link];
import [Link];
import [Link];
import [Link];
class AllDir
{
public static void main(String[] args)
throws IOException
{
// Enter the path and dirname
BufferedReader br = new BufferedReader(new InputStreamReader([Link]));
// If directory exists,then
if ([Link]()) {
// Get the contents into arr[], now arr[i] represent either a File or Directory
String arr[] = [Link]();
// Find no. of entries in the directory
int n = [Link];
// Create File object with the entry and test if it is a file or directory
File f1 = new File(f,arr[i]);
if ([Link]())
[Link](": is a file");
if ([Link]())
[Link](": is a directory");
}
Lecture 42
Byte Streams and Character Streams with example
The [Link] package contains nearly every class you might ever need to perform input and output (I/O) in
Java. All these streams represent an input source and an output destination. The stream in the [Link]
package supports many data such as primitives, object, localized characters, etc.
Stream
A stream can be defined as a sequence of data. There are two kinds of Streams −
• InPutStream − The InputStream is used to read data from a source.
• OutPutStream − The OutputStream is used for writing data to a destination.
Java provides strong but flexible support for I/O related to files and networks but this tutorial covers very
basic functionality related to streams and I/O. We will see the most commonly used examples one by one −
Byte Streams
Java byte streams are used to perform input and output of 8-bit bytes. Though there are many classes related
to byte streams but the most frequently used classes are, FileInputStream and FileOutputStream. Following
is an example which makes use of these two classes to copy an input file into an output file −
Example
import [Link];
import [Link];
import [Link];
try {
in = new FileInputStream("[Link]");
out = new FileOutputStream("[Link]");
int c;
while ((c = [Link]()) != -1) {
[Link](c);
}
}finally {
if (in != null) {
[Link]();
}
if (out != null) {
[Link]();
}
}
}
}
As a next step, compile the above program and execute it, which will result in creating [Link] file with
the same content as we have in [Link]. So let's put the above code in [Link] file and do the
following −
$javac [Link]
$java CopyFile
Character Streams
Java Byte streams are used to perform input and output of 8-bit bytes, whereas Java Character streams are
used to perform input and output for 16-bit unicode. Though there are many classes related to character
streams but the most frequently used classes are, FileReader and FileWriter. Though internally FileReader
uses FileInputStream and FileWriter uses FileOutputStream but here the major difference is that FileReader
reads two bytes at a time and FileWriter writes two bytes at a time.
We can re-write the above example, which makes the use of these two classes to copy an input file (having
unicode characters) into an output file −
Example
import [Link];
import [Link];
import [Link];
try {
in = new FileReader("[Link]");
out = new FileWriter("[Link]");
int c;
while ((c = [Link]()) != -1) {
[Link](c);
}
}finally {
if (in != null) {
[Link]();
}
if (out != null) {
[Link]();
}
}
}
}
As a next step, compile the above program and execute it, which will result in creating [Link] file with
the same content as we have in [Link]. So let's put the above code in [Link] file and do the
following −
$javac [Link]
$java CopyFile
Standard Streams
All the programming languages provide support for standard I/O where the user's program can take input
from a keyboard and then produce an output on the computer screen. If you are aware of C or
C++ programming languages, then you must be aware of three standard devices STDIN,
STDOUT and STDERR. Similarly, Java provides the following three standard streams –
Standard Input − This is used to feed the data to user's program and usually a keyboard is used as
standard input stream and represented as [Link].
Standard Output − This is used to output the data produced by the user's program and usually a
computer screen is used for standard output stream and represented as [Link].
Standard Error − This is used to output the error data produced by the user's program and usually a
computer screen is used for standard error stream and represented as [Link].
Following is a simple program, which creates InputStreamReader to read standard input stream until the user
types a "q" −
Example
import [Link];
public class ReadConsole {
public static void main(String args[]) throws IOException {
InputStreamReader cin = null;
try {
cin = new InputStreamReader([Link]);
[Link]("Enter characters, 'q' to quit.");
char c;
do {
c = (char) [Link]();
[Link](c);
} while(c != 'q');
}finally {
if (cin != null) {
[Link]();
}
}
}
}
Let's keep the above code in [Link] file and try to compile and execute it as shown in the
following program. This program continues to read and output the same character until we press 'q' −
$javac [Link]
$java ReadConsole
FileInputStream
This stream is used for reading data from the files. Objects can be created using the keyword new and there
are several types of constructors available.
Following constructor takes a file name as a string to create an input stream object to read the file −
InputStream f = new FileInputStream("C:/java/hello");
Following constructor takes a file object to create an input stream object to read the file. First we create a
file object using File() method as follows −
Once you have InputStream object in hand, then there is a list of helper methods which can be used to read
to stream or to do other operations on the stream.
There are other important input streams available, for more detail you can refer to the following links −
• ByteArrayInputStream
• DataInputStream
FileOutputStream
FileOutputStream is used to create a file and write data into it. The stream would create a file, if it doesn't
already exist, before opening it for output.
Here are two constructors which can be used to create a FileOutputStream object.
Following constructor takes a file name as a string to create an input stream object to write the file −
OutputStream f = new FileOutputStream("C:/java/hello")
Following constructor takes a file object to create an output stream object to write the file. First, we create a
file object using File() method as follows −
Once you have OutputStream object in hand, then there is a list of helper methods, which can be used to
write to stream or to do other operations on the stream.
There are other important output streams available, for more detail you can refer to the following links −
• ByteArrayOutputStream
• DataOutputStream
Example
Following is the example to demonstrate InputStream and OutputStream −
import [Link];
try {
byte bWrite [] = {11,21,3,40,5};
OutputStream os = new FileOutputStream("[Link]");
for(int x = 0; x < [Link] ; x++) {
[Link]( bWrite[x] ); // writes the bytes
}
[Link]();
The above code would create file [Link] and would write given numbers in binary format. Same would be
the output on the stdout screen.
Directories in Java
A directory is a File which can contain a list of other files and directories. You use File object to create
directories, to list down files available in a directory. For complete detail, check a list of all the methods
which you can call on File object and what are related to directories.
Creating Directories
There are two useful File utility methods, which can be used to create directories −
The mkdir( ) method creates a directory, returning true on success and false on failure. Failure
indicates that the path specified in the File object already exists, or that the directory cannot be
created because the entire path does not exist yet.
The mkdirs() method creates both a directory and all the parents of the directory.
Example
import [Link];
Note − Java automatically takes care of path separators on UNIX and Windows as per conventions. If you
use a forward slash (/) on a Windows version of Java, the path will still resolve correctly.
Listing Directories
You can use list( ) method provided by File object to list down all the files and directories available in a
directory as follows −
Example
import [Link];
try {
// create new file object
file = new File("/tmp");
This will produce the following result based on the directories and files available in your /tmp directory −
Output
[Link]
[Link]
[Link]
[Link]
Lecture 43
Reading and Writing Files Serialization and Deserialization
In Java, serialization plays a very important role it's something that we use a lot in our real life, even if we
do not always notice it. Serialization helps us to save the current state of an object so that we can use it
further and share complex data between different systems. In this article, we will discuss a lot more about
serialization and deserialization in Java for better understanding and clarity.
Deserialization is the reverse process where the byte stream is used to recreate the actual Java object in
memory. This mechanism is used to persist the object.
Serialization Process: The byte stream created is platform independent. So, the object serialized on one
platform can be deserialized on a different platform. To make a Java object serializable we implement the
[Link] interface. The ObjectOutputStream class contains writeObject() method for serializing
an Object.
public final void writeObject(Object obj)
throws IOException
Advantages of Serialization:
Persistence: The serialization allows us to save and persist the state of an object to a file or database.
Network Communication: Serialization is often used to transfer objects across a network, enabling
the communication between different components and or systems.
Deserialization Process: The ObjectInputStream class contains readObject() method for deserializing an
object.
Advantages of Deserialization:
It turns saved data back into the original objects, so everything works just like before.
t helps different programs or systems share information easily by rebuilding objects from the saved
data.
Serializable Interface and Marker Interfaces
Only the objects of those classes can be serialized which are implementing [Link] interface.
Serializable is a marker interface (has no data member and method). It is used to "mark" java classes so
that objects of these classes may get certain capability. Other examples of marker interfaces are:-
Cloneable and Remote.
Example:
class A implements Serializable{
// B also implements Serializable
// interface.
B ob=new B();
}
SerialVersionUID
The Serialization runtime associates a version number with each Serializable class called a
SerialVersionUID, which is used during Deserialization to verify that sender and receiver of a serialized
object have loaded classes for that object which are compatible with respect to serialization. If the receiver
has loaded a class for the object that has different UID than that of corresponding sender's class, the
Deserialization will result in an InvalidClassException.
Syntax:
private static final long serialVersionUID = 3L;
A Serializable class can declare its own UID explicitly by declaring a field name. It must be static, final
and of type long. i.e- ANY-ACCESS-MODIFIER static final long serialVersionUID=42L; If a serializable
class doesn't explicitly declare a serialVersionUID, then the serialization runtime will calculate a default
one for that class based on various aspects of class, as described in Java Object Serialization Specification.
However it is strongly recommended that all serializable classes explicitly declare serialVersionUID
value, since its computation is highly sensitive to class details that may vary depending on compiler
implementations, any change in class or using different id may affect the serialized data. It is also
recommended to use private modifier for UID since it is not useful as inherited member. serialver The
serialver is a tool that comes with JDK. It is used to get serialVersionUID number for Java classes.
// Serialization
try {
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);
[Link](object);
[Link]();
[Link]();
[Link]("Object has been serialized");
// Deserialization
try {
FileInputStream file = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(file);
object1 = (Demo) [Link]();
[Link]();
[Link]();
[Link]("Object has been deserialized");
[Link]("a = " + object1.a);
[Link]("b = " + object1.b);
Output:
Object has been serialized
Object has been deserialized
a=1
b = Welcome to Goa
// Serialization
try {
// Saving of object in a file
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);
[Link](object);
[Link]();
[Link]();
[Link]("Object has been serialized\nData before Deserialization.");
printData(object);
object = null;
// Deserialization
try {
// Reading the object from a file
FileInputStream file = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(file);
object = (Emp) [Link]();
[Link]();
[Link]();
[Link]("Object has been deserialized\nData after Deserialization.");
printData(object);
Output
Object has been serialized
Data before Deserialization.
name = ab
age = 20
a=2
b = 1000
Object has been deserialized
Data after Deserialization.
name = ab
age = 20
a=0
b = 2000
Explanation In the above code while deserializing the object the values of a and b has changed. The
reason being a was marked as transient and b was static.
In case of transient variables:- A variable defined with transient keyword is not serialized during
serialization [Link] variable will be initialized with default value during deserialization. (e.g: for
objects it is null, for int it is 0).
In case of static Variables:- A variable defined with static keyword is not serialized during
serialization [Link] variable will be loaded with current value defined in the class during
deserialization.
Transient Vs Final
The main difference between Transient and Final is listed below:
Final variables are serialized by their value directly.
Declaring a final variable as transient has no use because the compiler replaces final variables with
their literal values in the bytecode.
Example:
final int x= 10;
int y = 20;
[Link](x);// compiler will replace this as [Link](10)->10
because x is final.
[Link](y);//20
[Link]("serialization started");
[Link](d1);
[Link]("Serialization ended");
//Deserialization started
[Link]("Deserialization started");
FileInputStream fis=new FileInputStream("[Link]");
ObjectInputStream ois=new ObjectInputStream(fis);
Dog d2=(Dog) [Link]();
[Link]("Deserialization ended");
[Link]("Dog object data");
//final result
[Link](d2.i+"\t" +d2.j);
}
}
Output
serialization started
Serialization ended
Deserialization started
Deserialization ended
Dog object data
10 20
Lecture 44
Summary
The study of the Java Collections Framework and Input/Output (I/O) operations in Java forms an
important part of Java programming. These concepts provide powerful tools for managing data efficiently
and for interacting with external resources such as files, databases, and networks. Understanding these
components enables programmers to develop applications that are organized, efficient, and capable of
handling large amounts of data in a structured manner.
The Java Collections Framework provides a unified architecture for storing and manipulating groups of
objects. Before the introduction of this framework, programmers used traditional data structures such as
arrays and vectors, which were often less flexible and required more manual handling. The Collections
Framework simplifies these tasks by providing ready-made classes and interfaces that support dynamic data
management. It allows developers to store, retrieve, search, sort, and manipulate data easily without writing
complex code for basic operations.
At the core of the Collections Framework are several important interfaces, including List, Set, and Map.
These interfaces define the basic structure and behavior of different types of collections. The List interface
represents an ordered collection that allows duplicate elements. Common implementations of this interface
include ArrayList and LinkedList. These classes are widely used when data needs to be stored in a sequence
and accessed using indexes. They also provide various methods to add, remove, and update elements
dynamically.
The Set interface represents a collection that does not allow duplicate elements. It is useful in situations
where uniqueness of data must be maintained. Classes such as HashSet, LinkedHashSet, and TreeSet
implement this interface and provide different ways of storing and organizing data. For example, HashSet
stores elements using a hashing mechanism, while TreeSet maintains elements in sorted order. These
features allow programmers to choose the most suitable structure depending on the requirements of the
application.
Another important component of the Collections Framework is the Map interface, which stores data in the
form of key-value pairs. Each key in a map is unique and is used to retrieve the corresponding value.
Popular implementations of the Map interface include HashMap, LinkedHashMap, and TreeMap. These
classes are widely used in applications that require quick data lookup and association between keys and
values, such as storing user information, configuration settings, or database records.
The Collections Framework also provides utility classes such as Collections and Arrays, which offer
methods for sorting, searching, and manipulating collection elements. For example, programmers can easily
sort a list of elements using built-in methods rather than implementing sorting algorithms manually. This
saves development time and reduces the chances of errors in complex programs.
Another important concept related to collections is the use of iterators. Iterators provide a standard way to
traverse through the elements of a collection. They allow programmers to access elements sequentially
without exposing the internal structure of the collection. The Iterator interface provides methods such as
hasNext(), next(), and remove(), which make it easier to navigate through data structures safely and
efficiently.
Along with collections, the study of Java Input/Output (I/O) is equally important. Input/Output operations
allow programs to interact with external sources of data. In many real-world applications, data cannot be
stored only in memory because memory is temporary and data would be lost when the program ends. Java
I/O provides mechanisms to read data from files, write data to files, and transfer information between
different devices.
Java supports a stream-based I/O system, where data is treated as a continuous flow of information called a
stream. Streams can be categorized into two main types: input streams and output streams. Input streams are
used to read data from a source, while output streams are used to write data to a destination. This stream-
based approach makes it easier to handle different types of data sources such as files, keyboard input, and
network connections.
Java I/O is mainly implemented through the [Link] package, which contains several important classes for
handling file operations. One of the most commonly used classes is the File class, which represents files and
directories in the system. It allows programmers to create files, check file properties, delete files, and obtain
information about file paths. However, the File class does not actually read or write file contents; it mainly
provides information and management operations for files.
To read and write data in files, Java provides classes such as FileReader, FileWriter, BufferedReader, and
BufferedWriter. FileReader and FileWriter are used for basic character-based file operations, while
BufferedReader and BufferedWriter improve performance by buffering data during reading and writing
processes. These classes allow programmers to process large amounts of data more efficiently.
Another set of important classes in Java I/O includes DataInputStream and DataOutputStream, which are
used to read and write primitive data types such as integers, floating-point numbers, and characters. These
streams make it possible to store structured data in files and retrieve it accurately when needed. Similarly,
ObjectInputStream and ObjectOutputStream allow Java objects to be written to files and read back later
through a process known as object serialization.
Error handling is also an essential aspect of Java I/O operations. When dealing with files and external
resources, several errors may occur, such as file not found, access denied, or input/output failures. Java
handles such situations using exception handling mechanisms, particularly the IOException class and its
subclasses. By using try-catch blocks, programmers can manage these errors effectively and ensure that
programs run smoothly without unexpected crashes.
The combination of the Java Collections Framework and Java I/O capabilities makes Java a powerful
language for building real-world applications. Collections help manage data efficiently within the program,
while I/O operations allow that data to be stored, retrieved, and exchanged with external systems. These two
components work together to support the development of applications such as data processing systems, web
applications, file management tools, and enterprise software solutions.
In conclusion, the Java Collections Framework and Java I/O provide essential features for effective data
handling and program interaction with external resources. The Collections Framework offers a wide range
of data structures and algorithms that simplify data management, while Java I/O provides mechanisms for
reading and writing data through streams and files. By mastering these concepts, programmers can design
applications that are more efficient, flexible, and reliable. These tools not only improve coding productivity
but also support the development of scalable and maintainable software systems in modern computing
environments.