0% found this document useful (0 votes)
6 views67 pages

Java Unit 4 Notes

The document provides an overview of the Java Collections Framework (JCF) and Java Input/Output (I/O), detailing their components, interfaces, and classes. JCF simplifies data handling with interfaces like List, Set, and Map, while Java I/O manages input and output operations through various streams. Key operations and examples for manipulating collections, particularly the List interface, are also discussed.

Uploaded by

vikik2757
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views67 pages

Java Unit 4 Notes

The document provides an overview of the Java Collections Framework (JCF) and Java Input/Output (I/O), detailing their components, interfaces, and classes. JCF simplifies data handling with interfaces like List, Set, and Map, while Java I/O manages input and output operations through various streams. Key operations and examples for manipulating collections, particularly the List interface, are also discussed.

Uploaded by

vikik2757
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Unit-4

Java Collections Framework and I/O

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.

The framework is built on three main components:


1. Interfaces – Define the types of collections (e.g., List, Set, Queue, Map).
2. Classes – Implement these interfaces (e.g., ArrayList, LinkedList, HashSet, HashMap).
3. Algorithms – Provide methods for sorting, searching, and manipulating data (e.g.,
[Link]()).

Key advantages of JCF:


 Reduces programming effort
 Increases performance and efficiency
 Promotes code reusability
 Supports Generics (type safety)
 Provides dynamic data structures

The main interfaces include:


 List – Ordered collection (ArrayList, LinkedList)
 Set – Unordered collection without duplicates (HashSet, TreeSet)
 Queue – Follows FIFO principle (PriorityQueue)
 Map – Stores key-value pairs (HashMap, TreeMap)

Thus, JCF simplifies data handling and improves application development.

Java Input/Output (I/O)


Java I/O is used to handle input and output operations in a program. It allows data to be read from input
sources (keyboard, files, network) and written to output destinations (screen, files, network).
Java I/O is mainly provided by:
 [Link] package (traditional I/O)
 [Link] package (New I/O – faster and more efficient)
There are two main types of streams:
1. Byte Streams – Handle binary data (InputStream, OutputStream)
2. Character Streams – Handle text data (Reader, Writer)
Important classes:
 File
 FileReader, FileWriter
 BufferedReader, BufferedWriter
 InputStream, OutputStream
Java I/O supports file handling, buffering, object serialization, and efficient data transfer.
Lecture 36
Definition of Collections Framework: Overview of Collections with
example
The Java Collections Framework provides a set of interfaces (like List, Set, and Map) and a set of classes
(ArrayList, HashSet, HashMap, etc.) that implement those interfaces.

All of these are part of the [Link] package.

They are used to store, search, sort, and organize data more easily - all using standardized methods and
patterns.

Tip: Think of the Collections Framework as a toolbox.

Interfaces like List define what tools can do, and classes like ArrayList are the actual tools that do the work.

Core Interfaces in the Collections Framework


Here are some common interfaces, along with their classes:

Interface Common Classes Description


List ArrayList, LinkedList Ordered collection that allows duplicates
Set HashSet, TreeSet, LinkedHashSet Collection of unique elements
Map HashMap, TreeMap, LinkedHashMap Stores key-value pairs with unique keys

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.

Declaration of Java List Interface


public interface List<E> extends Collection<E> { }
To use a List, we must instantiate a class that implements it. Example classes that implement it are
ArrayList and LinkedList
List<Type> list = new ArrayList<Type>();

Hierarchy of List Interface


It extends the Collection interface.
The common implementation classes of the List interface are:
 ArrayList: It is implemented using resizable array, offers fast random access but slower insert/delete.
 LinkedList: It is implemented using Doubly-linked list, efficient for frequent insertions and deletions.
 Vector: It is implemented using Legacy synchronized dynamic array, thread-safe but slower.
 Stack: It is implemented using a LIFO (Last-In-First-Out) subclass of Vector for stack operations.

Java List - Operations


List can be used only with a class that implements this interface. Now, let's see how to perform a few
frequently used operations on the List.

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<>();

// Adding elements to object of List class


[Link]("Python");
[Link]("PHP");
[Link](1, "C++");

[Link]("Initial ArrayList " + al);

// Setting (updating) element at 1st index using set() method


[Link](1, "Java");

[Link]("Updated ArrayList " + al);


}
}

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 {

public static void main(String[] args)


{
// create a list of integers
List<Integer> al = new ArrayList<>();

// add some integers to the list


[Link](1);
[Link](2);
[Link](3);
[Link](2);

// use indexOf() to find the first occurrence of an element in the list


int i = [Link](2);

[Link]("First Occurrence of 2 is at Index: "+i);

// use lastIndexOf() to find the last occurrence of an element in the list


int l = [Link](2);

[Link]("Last Occurrence of 2 is at Index: "+l);


}
}

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 {

public static void main(String args[])


{

// Creating List class object


List<String> al = new ArrayList<>();

// Adding elements to the object Custom inputs


[Link]("Python");
[Link]("PHP");

// Adding For at 1st indexes


[Link](1, "Java");

[Link]("Initial ArrayList " + al);

// Now remove element from the above list present at 1st index
[Link](1);
[Link]("After the Index Removal " + al);

// Now remove the current object from the updated List


[Link]("PHP");

[Link]("After the Object 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");

// Accessing elements using get() method


String first = [Link](0);
String second = [Link](1);
String third = [Link](2);

[Link](first);
[Link](second);
[Link](third);
[Link](al);
}
}

Output
Python
Java
PHP
[Python, Java, PHP]

6. Checking if an element is present or not


To check if an element is present in the list, we can use the contains() method. This method returns true if
the specified element is present in the list, otherwise, it returns false.
contains(Object o): This method takes a single parameter, the object to be checked if it is present 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");

// Checking if element is present using contains() method


boolean isPresent = [Link]("Python");

// Printing the result


[Link]("Is Python present in the list? "+ isPresent);
}
}

Output
Is Python present in the list? true

Iterating over List Interface in Java


For larger datasets, Lists can be iterated using:
 Basic for loop with get(index)
 Enhanced for-each loop
These methods allow efficient traversal of elements.

import [Link].*;

public class Main {

public static void main(String args[])


{
// Creating an empty Arraylist of string type
List<String> al = new ArrayList<>();

// Adding elements to above object of ArrayList


[Link]("Python");
[Link]("PHP");

// Adding element at specified position inside list object


[Link](1, "Java");

// Using for loop for iteration


for (int i = 0; i < [Link](); i++) {

// Using get() method to access particular element


[Link]([Link](i) + " ");
}

// New line for better readability


[Link]();
// Using for-each loop for iteration
for (String str : al)

[Link](str + " ");


}
}

Output
Python Java PHP
Python Java PHP

Complexity of List Interface in Java


Operation Time Complexity Space Complexity
Adding Element in List Interface O(1) O(1)
Remove Element from List Interface O(N) O(1)
Replace Element in List Interface O(1) O(1)
aTraversing List Interface O(N) O(1)

Methods of the List Interface


Methods Description
This method is used with Java List Interface to add an element at a
add(int index,
particular index in the list. When a single parameter is passed, it simply
element)
adds the element at the end of the list.
This method is used with List Interface in Java to add all the elements
addAll(int index,
in the given collection to the list. When a single parameter is passed, it
Collection collection)
adds all the elements of the given collection at the end of the list.
This method is used with Java List Interface to return the size of the
size()
list.
This method is used to remove all the elements in the list. However,
clear()
the reference of the list created is still stored.
This method removes an element from the specified index. It shifts
remove(int index)
subsequent elements(if any) to left and decreases their indexes by 1.
This method is used with Java List Interface to remove the first
remove(element)
occurrence of the given element in the list.
get(int index) This method returns elements at the specified index.
This method replaces elements at a given index with the new element.
set(int index, element) This function returns the element which was just replaced by a new
element.
This method returns the first occurrence of the given element or -1 if
indexOf(element)
the element is not present in the list.
This method returns the last occurrence of the given element or -1 if
lastIndexOf(element)
the element is not present in the list.
This method is used with Java List Interface to compare the equality of
equals(element)
the given element with the elements of the list.
This method is used with List Interface in Java to return the hashcode
hashCode()
value of the given list.
This method is used with Java List Interface to check if the list is
isEmpty()
empty or not. It returns true if the list is empty, else false.
This method is used with List Interface in Java to check if the list
contains(element) contains the given element or not. It returns true if the list contains the
element.
containsAll(Collection This method is used with Java List Interface to check if the list
collection) contains all the collection of elements.
sort(Comparator This method is used with List Interface in Java to sort the elements of
comp) the list on the basis of the given comparator.

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];

public class Main {

public static void main(String args[])


{
// Create a Set using HashSet
Set<String> s = new HashSet<>();

// Displaying the Set


[Link]("Set Elements: " + s);
}
}
Explanation: In the above example, HashSet will appear as an empty set, as no elements were added. The
order of elements in HashSet is not guaranteed, so the elements will be displayed in a random order if any
are added.
Hierarchy of Java Set interface
The image below demonstrates the hierarchy of Java Set interface.
Classes that implement the Set interface
 HashSet: A set that stores unique elements without any specific order, using a hash table and allows
one null element.
 EnumSet : A high-performance set designed specifically for enum types, where all elements must
belong to the same enum.
 LinkedHashSet: A set that maintains the order of insertion while storing unique elements.
 TreeSet: A set that stores unique elements in sorted order, either by natural ordering or a specified
comparator.
Declaration of Set Interface
The declaration of Set interface is listed below:
public interface Set extends Collection
Creating Set Objects
Since Set is an interface, objects cannot be created of the typeset. We always need a class that implements
this interface in order to create an object. And also, after the introduction of Generics in Java 1.5, it is
possible to restrict the type of object that can be stored in the Set. This type-safe set can be defined as:
// Obj is the type of the object to be stored in Set
Set<Obj> set = new HashSet<Obj> ();
Performing Various Operations on Set
Set interface provides commonly used operations to manage unique elements in a collection. Now let us
discuss these operations individually as follows:
1. Adding Elements
To add elements to a Set in Java, use the add() method.
import [Link].*;

// Main class
class Main {

public static void main(String[] args)


{
Set<String> s = new HashSet<String>();

[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 {

public static void main(String[] args)


{
Set<String> h = new HashSet<String>();

[Link]("A");
[Link]("B");
[Link]("C");
[Link]("A");

[Link]("Set is " + h);

String s = "D";

[Link]("Contains " + s + " " + [Link](s));


}
}

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 {

public static void main(String[] args)


{
// Declaring object of Set of type String
Set<String> h = new HashSet<String>();

// Elements are added using add() method, Custom input elements


[Link]("A");
[Link]("B");
[Link]("C");
[Link]("B");
[Link]("D");
[Link]("E");

[Link]("Initial HashSet " + h);

// Removing custom element using remove() method


[Link]("B");
[Link]("After removing element " + h);
}
}

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 {

public static void main(String[] args)


{
// Creating object of Set and declaring String type
Set<String> h = new HashSet<String>();

// Adding elements to Set using add() method, Custom input elements


[Link]("A");
[Link]("B");
[Link]("C");
[Link]("B");
[Link]("D");
[Link]("E");

// Iterating through the Set via for-each loop


for (String value : h)

// Printing all the values inside the object


[Link](value + ", ");

[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];

public class Main{

public static void main(String[] args){

// Create a Map using HashMap


Map<String, Integer> m = new HashMap<>();

// Adding key-value pairs to the map


[Link]("Java1", 1);
[Link]("Java2", 2);
[Link]("Java3", 3);

[Link]("Map elements: " + m);


}
}

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.

Implemented Classes of Map Interface


 HashMap: Stores key-value pairs using hashing for fast access, insertion, and deletion.
 LinkedHashMap: Similar to HashMap but maintains the insertion order of key-value pairs.
 TreeMap: Stores key-value pairs in sorted order using natural ordering or a custom comparator.
 Hashtable: A synchronized Map implementation that doesn’t allow null keys or values.
Operations on Map using HashMap
Now, let’s see how to perform a few frequently used operations on a Map using the widely used HashMap
class.

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 {

public static void main(String[] args) {

// Default initialization of a Map using generics


Map<Integer, String> hm1 = new HashMap<>();

// Initialization of a Map (redundant type on right side unnecessary)


Map<Integer, String> hm2 = new HashMap<>();

// Inserting elements
[Link](1, "Python");
[Link](2, "Java");
[Link](3, "PHP");

// Inserting elements — no need to use new Integer()


[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[])
{

// Initialization of a Map using Generics


Map<Integer, String> hm1= new HashMap<Integer, String>();

// Inserting the Elements


[Link](new Integer(1), "Python");
[Link](new Integer(2), "C++");
[Link](new Integer(3), "PHP");

[Link]("Initial Map: " + hm1);

[Link](new Integer(2), "Java");

[Link]("Updated Map: " + hm1);


}
}

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{

public static void main(String args[]){

// Initialization of a Map using Generics


Map<Integer, String> hm1 = new HashMap<Integer, String>();

// Inserting the Elements


[Link](new Integer(1), "Python");
[Link](new Integer(2), "Java");
[Link](new Integer(3), "PHP");
[Link](new Integer(4), "C++");

[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[]){

// Initialization of a Map using Generics


Map<Integer, String> hm1 = new HashMap<Integer, String>();

// Inserting the Elements


[Link](new Integer(1), "Python");
[Link](new Integer(2), "Java");
[Link](new Integer(3), "PHP");

for ([Link] mapElement : [Link]()) {


int key = (int)[Link]();

// Finding the value


String value = (String)[Link]();

[Link](key + " : " + value);


}
}
}

Output
1 : Python
2 : Java
3 : PHP

Methods in Java Map Interface


Methods Action Performed
This method is used in Java Map Interface to clear and remove all of the
clear()
elements or mappings from a specified Map collection.
containsKey(Object) Checks if a key exists in the map.
containsValue(Object) Checks if a value exists in the map.
entrySet() Returns a set view of the map’s key-value pairs.
equals(Object) Compares two maps for equality.
get(Object) Returns the value for the given key, or null if not found.
This method is used in Map Interface to generate a hashCode for the given
hashCode()
map containing keys and values.
This method is used to check if a map is having any entry for key and value
isEmpty()
pairs. If no mapping exists, then this returns true.
keySet() Returns a set view of the keys in the map.
put(Object, Object) This method is used in Java Map Interface to associate the specified value with
the specified key in this map.
This method is used in Map Interface in Java to copy all of the mappings from
putAll(Map)
the specified map to this map.
This method is used in Map Interface to remove the mapping for a key from
remove(Object)
this map if it is present in the map.
This method is used to return the number of key/value pairs available in the
size()
map.
values() Returns a collection view of the map’s values.
getOrDefault(Object key, Returns the value to which the specified key is mapped, or defaultValue if this
V defaultValue) map contains no mapping for the key.
merge(K key, V value,
BiFunction<? super V,? If the specified key is not already associated with a value or is associated with
super V,? extends V> null, associate it with the given non-null value.
remappingFunction)
putIfAbsent(K key, V
Adds a mapping only if the key is not already mapped.
value)

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>();

// Adding Element in ArrayList


[Link](1);
[Link](2);
[Link](3);

// 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.

ArrayList Constructors in Java


Java provides multiple constructors to create an ArrayList based on different requirements:
1. ArrayList()
Creates an empty ArrayList with default initial capacity.
ArrayList<Integer> arr = new ArrayList<>();

2. ArrayList(Collection<? extends E> c)


Creates an ArrayList initialized with elements from the specified collection.
ArrayList<String> arr = new ArrayList<>(collection);

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{

public static void main(String args[]){

// Creating an Array of string type


ArrayList<String> al = new ArrayList<>();

// 1. Adding elements to ArrayList at the end


[Link]("Python");
[Link]("PHP");

[Link]("Original List : "+al);

// Adding Elements at the specific index


[Link](1, "Java");

[Link]("After Adding element at index 1 : "+ al);

// 2. Removing Element using index


[Link](0);

[Link]("Element removed from index 0 : "+ al);

// Removing Element using the value


[Link]("PHP");

[Link]("Element PHP removed : "+ al);

// 3. Updating value at index 0


[Link]("List after updation of value : "+al);
}
}

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++]

Complexity of Java ArrayList


Operation Time Complexity Space Complexity
Inserting Element in ArrayList O(1) O(N)
Removing Element from O(N) O(1)
ArrayList
Traversing Elements in O(N) O(N)
ArrayList
Replacing Elements in O(1) O(1)
ArrayList

Java ArrayList Methods


Method Description
add(int index, Object element) This method is used to insert a specific element at a specific position index
in a list.
add(Object o) This method is used to append a specific element to the end of a list.
addAll(Collection C) This method is used to append all the elements from a specific collection to
the end of the mentioned list, in such an order that the values are returned
by the specified collection’s iterator.
addAll(int index, Collection Used to insert all of the elements starting at the specified position from a
C) specific collection into the mentioned list.
clear() This method is used to remove all the elements from any list.
clone() This method is used to return a shallow copy of an ArrayList in Java.
contains(Object o) Returns true if this list contains the specified element.
ensureCapacity(int Increases the capacity of this ArrayList instance, if necessary, to ensure
minCapacity) that it can hold at least the number of elements specified by the minimum
capacity argument.
forEach(Consumer<? super Performs the given action for each element of the Iterable until all elements
E> action) have been processed or the action throws an exception.
get(int index) Returns the element at the specified position in this list.
indexOf(Object O) The index the first occurrence of a specific element is either returned or -1
in case the element is not in the list.
isEmpty() Returns true if this list contains no elements.
lastIndexOf(Object O) The index of the last occurrence of a specific element is either returned or -
1 in case the element is not in the list.
listIterator() Returns a list iterator over the elements in this list (in proper sequence).
listIterator(int index) Returns a list iterator over the elements in this list (in proper sequence),
starting at the specified position in the list.
remove(int index) Removes the element at the specified position in this list.
remove(Object o) Removes the first occurrence of the specified element from this list, if it is
present.
removeAll(Collection c) Removes from this list all of its elements that are contained in the specified
collection.
removeIf(Predicate filter) Removes all of the elements of this collection that satisfy the given
predicate.
removeRange(int fromIndex, Removes from this list all of the elements whose index is between from
int toIndex) Index, inclusive and to Index, exclusive.
retainAll(Collection<?> c) Retains only the elements in this list that are contained in the specified
collection.
set(int index, E element) Replaces the element at the specified position in this list with the specified
element.
size() Returns the number of elements in this list.
spliterator() Creates a late-binding and fail-fast Spliterator over the elements in this list.
subList(int fromIndex, int Returns a view of the portion of this list between the specified fromIndex,
toIndex) inclusive and toIndex, exclusive.
toArray() This method is used to return an array containing all of the elements in the
list in the correct order.
toArray(Object[] O) It is also used to return an array containing all of the elements in this list in
the correct order same as the previous method.
trimToSize() This method is used to trim the capacity of the instance of the ArrayList to
the list's current size.

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];

public class Main {

public static void main(String[] args){

// Creating a LinkedList
LinkedList<String> l = new LinkedList<String>();

// Adding elements to the LinkedList using add() method


[Link]("One");
[Link]("Two");
[Link]("Three");
[Link]("Four");
[Link]("Five");

[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);

Performing Different Operations on LinkedList


1. Adding Elements
With the help of the add() method, we can add elements to a LinkedList This method can perform multiple
operations based on different parameters. They are:
 add(Object): This method is used to add an element at the end of the LinkedList.
 add(int index, Object): This method is used to add an element at a specific index in the LinkedList.

import [Link].*;

public class Main {

public static void main(String args[])


{
LinkedList<String> ll = new LinkedList<>();

[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].*;

public class Main {


public static void main(String args[])
{
LinkedList<String> ll = new LinkedList<>();

[Link]("Python");
[Link]("PHP");
[Link](1, "C++");

[Link]("Initial LinkedList " + ll);

[Link](1, "Java");

[Link]("Updated LinkedList " + ll);


}
}

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].*;

public class Main {

public static void main(String args[])


{
LinkedList<String> ll = new LinkedList<>();

[Link]("Python");
[Link]("PHP");
[Link](1, "Java");

[Link]("Initial LinkedList " + ll);

// Function call
[Link](1);

[Link]("After the Index Removal " + ll);

[Link]("Python");

[Link]("After the Object Removal " + ll);


}
}

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].*;

public class Main {

public static void main(String args[])


{
LinkedList<String> ll = new LinkedList<>();

[Link]("Python");
[Link]("PHP");
[Link](1, "Java");

// Using the Get method and the for loop


for (int i = 0; i < [Link](); i++) {

[Link]([Link](i) + " ");


}

[Link]();

// Using the for each loop


for (String str : ll)
[Link](str + " ");
}
}

Output
Python Java PHP
Python Java PHP

Methods for Java LinkedList


Method Description
add(int index, E element) Inserts element at given index.
add(E e) This method Appends the specified element to the end of this list.
addAll(int index, Collection<E> c) Inserts all elements of collection starting at index.
addAll(Collection<E> c) Appends all elements of collection to end
addFirst(E e) This method Inserts the specified element at the beginning of this
list.
addLast(E e) This method Appends the specified element to the end of this list.
clear() This method removes all of the elements from this list.
clone() This method returns a shallow copy of this LinkedList.
contains(Object o) This method returns true if this list contains the specified element.
descendingIterator() This method returns an iterator over the elements in this deque in
reverse sequential order.
element() This method retrieves but does not remove, the head (first element)
of this list.
get(int index) This method returns the element at the specified position in this list.
getFirst() This method returns the first element in this list.
getLast() This method returns the last element in this list.
indexOf(Object o) Return first index of element or -1 if element is not present
lastIndexOf(Object o) Return Last index of element or -1 if element is not present
listIterator(int index) This method returns a list-iterator of the elements.
offer(E e) This method Adds the specified element as the tail (last element) of
this list.
offerFirst(E e) This method Inserts the specified element at the front of this list.
offerLast(E e) This method Inserts the specified element at the end of this list.
peek() This method retrieves but does not remove, the head (first element)
of this list.
peekFirst() This method retrieves, but does not remove, the first element of this
list or returns null if this list is empty.
peekLast() This method retrieves, but does not remove, the last element of this
list or returns null if this list is empty.
poll() This method retrieves and removes the head (first element) of this
list.
pollFirst() This method retrieves and removes the first element of this list or
returns null if this list is empty.
pollLast() This method retrieves and removes the last element of this list or
returns null if this list is empty.
pop() This method Pops an element from the stack represented by this list.
push(E e) This method pushes an element onto the stack represented by this
list.
remove() This method retrieves and removes the head (first element) of this
list.
remove(int index) This method removes the element at the specified position in this list.
remove(Object o) This method removes the first occurrence of the specified element
from this list if it is present.
removeFirst() This method removes and returns the first element from this list.
removeFirstOccurrence(Object o) This method removes the first occurrence of the specified element in
this list.
removeLast() This method removes and returns the last element from this list.
removeLastOccurrence(Object o) This method removes the last occurrence of the specified element in
this list.
set(int index, E element) This method replaces the element at the specified position in this list
with the specified element.
size() This method returns the number of elements in this list.
spliterator() This method creates a late-binding and fail-fast Spliterator over the
elements in this list.
toArray() This method returns an array containing all of the elements in this list
in proper sequence.
toArray(T[] a) Returns array of all elements in given type.
toString() This method returns string representation of list.

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);

[Link]("HashSet Size: " + [Link]());


[Link]("Elements in HashSet: " + hs);
}
}

Output
HashSet Size: 2
Elements in HashSet: [1, 2]

Hierarchy Diagram of HashSet


It implements the Set interface, which is a sub-interface of the Collection interface.

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

Constructors of HashSet class


To create a HashSet, we need to create an object of the HashSet class. The HashSet class consists of
various constructors that allow the possible creation of the HashSet. The following are the constructors
available in this class.

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);

3. HashSet(int initialCapacity, float loadFactor)


Creates an empty HashSet with the given initial capacity and load factor.
HashSet<Type> set = new HashSet<>(int initialCapacity, float loadFactor);
4. HashSet(Collection<? extends E> c)
Creates a new HashSet containing the elements of the specified collection (removes duplicates
automatically).
HashSet<Type> set = new HashSet<>(c);

Performing Various Operations on HashSet


Let’s see how to perform a few frequently used operations on the HashSet.

1. Adding Elements in HashSet


To add an element to the HashSet, we can use the add() method. However, the insertion order is not
retained in the HashSet. We need to keep a note that duplicate elements are not allowed and all duplicate
elements are ignored.

import [Link].*;

class Main
{
public static void main(String[] args)
{
// Creating an empty HashSet of string entities
HashSet<String> hs = new HashSet<String>();

// Adding elements using add() method


[Link]("Python");
[Link]("Java");
[Link]("PHP");

[Link]("HashSet : " + hs);


}
}

Output
HashSet : [Python, Java, PHP]

2. Removing Elements in HashSet


The values can be removed from the HashSet using the remove() method.

import [Link].*;
class Main
{
public static void main(String[] args)
{

HashSet<String> hs = new HashSet<String>();

// Adding elements to above Set using add() method


[Link]("Python");
[Link]("Java");
[Link]("PHP");
[Link]("C++");
[Link]("C");
[Link]("Basic");

[Link]("HashSet : " + hs);

// Removing the element C


[Link]("C");

// Printing the updated HashSet elements


[Link]("HashSet after removing element : " + hs);

// Returns false if the element is not present


[Link]("C exists in Set : " + [Link]("C"));
}
}

Output
HashSet : [Python, Java, PHP, C++, C, Basic]
HashSet after removing element [Python, Java, PHP, C++, Basic]
C exists in Set : false

3. Iterating through the HashSet


Iterate through the elements of HashSet using the iterator() method. Also, the most famous one is to use
the enhanced for loop.

import [Link];
import [Link];

public class Main


{
public static void main(String[] args)
{
// Create a HashSet of Strings
HashSet<String> hs = new HashSet<>();

// Add elements to the HashSet


[Link]("Python");
[Link]("Java");
[Link]("PHP");
[Link]("C++");
[Link]("C");
[Link]("Basic");

// Using iterator() method to iterate Over the HashSet


[Link]("Using iterator : ");
Iterator<String> iterator = [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.

Differences between HashSet and HashMap.


Basis HashSet HashMap
Implementation HashSet implements a Set interface. HashMap implements a Map interface.
Duplicates HashSet doesn't allow duplicate values. HashMap stores key-value pairs and
doesn’t allow duplicate keys. A duplicate
key replaces the old value.
Number of objects HashSet requires only one object HashMap requires two objects put(K key,
during storing add(Object o). V Value) to add an element to the
objects HashMap object.
Dummy value HashSet internally uses a HashMap, HashMap does not have any concept of
where each element added is stored as a dummy value.
key with a dummy value.
Storing or Adding HashSet internally uses the HashMap HashMap internally uses hashing to store
a mechanism object to store or add the objects. or add objects
Faster HashSet is slower than HashMap. HashMap is faster than HashSet.
Insertion HashSet uses the add() method for adding HashMap uses the put() method for
or storing data. storing data.

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];

public class TreeSetCreation


{
public static void main(String args[])
{
// Create a TreeSet of Strings
TreeSet<String> t = new TreeSet<>();

// Displaying the TreeSet (which is empty at this point)


[Link]("TreeSet elements: " + t);
}
}

Output
TreeSet elements: []

Hierarchy Diagram of TreeSet


TreeSet implements NavigableSet, which extends SortedSet, which extends Set.
TreeSet-Heirarchy
Note:
 A class must implement Comparable (or provide a Comparator) to be stored in a TreeSet.
 Built-in classes like String, wrapper classes, etc., already implement Comparable

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);

Common Operations on TreeSet


Here we will be performing various operations over the TreeSet object to get familiar with the methods
and concepts of TreeSet in java. Let’s see how to perform a few frequently used operations on the
TreeSet.

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<>();

// Elements are added using add() method


[Link]("Python");
[Link]("Java");
[Link]("PHP");

// Print all elements inside object


[Link](ts);
}
}

Output
[Python, Java, PHP]

2. Accessing the Elements


After adding the elements, if we wish to access the elements, we can use inbuilt methods
like contains(), first(), last(), etc.

import [Link].*;
class Main {

public static void main(String[] args){

// Creating a NavigableSet object with reference to


// TreeSet class
NavigableSet<String> ts = new TreeSet<>();

// Elements are added using add() method


[Link]("python");
[Link]("Java");
[Link]("PHP");

[Link]("Tree Set is " + ts);


String check = "python";

// Check if the above string exists in the treeset


// or not
[Link]("Contains " + check + " " + [Link](check));

// Print the first element in the TreeSet


[Link]("First Value " + [Link]());

// Print the last element in the TreeSet


[Link]("Last Value " + [Link]());

String val = "python";

// Find the values just greater and smaller than the


// above string
[Link]("Higher " + [Link](val));
[Link]("Lower " + [Link](val));
}
}

Output
Tree Set is [Java, PHP, python]
Contains python true
First Value Java
Last Value python
Higher python
Lower PHP

3. Removing the Values


The values can be removed from the TreeSet using the remove() method. There are various other methods
that are used to remove the first value or the last value.

import [Link].*;

class Main {

public static void main(String[] args){

// Creating an object of NavigableSet with reference


// to TreeSet class
NavigableSet<String> ts = new TreeSet<>();

// Elements are added using add() method


[Link]("Python");
[Link]("Java");
[Link]("PHP");
[Link]("OOPs");
[Link](“C");
[Link]("C++");

[Link]("Initial TreeSet " + ts);

// Removing a specific existing element inserted


// above
[Link]("C");

// Printing the updated TreeSet


[Link]("After removing element " + ts);

// Now removing the first element using pollFirst()


// method
[Link]();

// Again printing the updated TreeSet


[Link]("After removing first " + ts);

// Removing the last element using pollLast() method


[Link]();

[Link]("After removing last " + ts);


}
}

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{

public static void main(String[] args){

// Creating an object of Set with reference to


// TreeSet class
Set<String> ts = new TreeSet<>();

// Adding elements in above object using add()


// method
[Link]("Python");
[Link]("Java");
[Link]("PHP");
[Link]("C");
[Link]("C++");
[Link]("Basic");

for (String value : ts)


[Link](value + ", ");

[Link]();
}
}

Output
Basic, C, C++, Java, PHP, Python,

5. Using TreeSet with Custom Objects


If a class does not implement Comparable (e.g., StringBuffer), provide a Comparator.

import [Link].*;

class Main {

public static void main(String[] args)


{
// Creating a TreeSet with a custom Comparator
Set<StringBuffer> ts = new TreeSet<>(new Comparator<StringBuffer>() {
@Override
public int compare(StringBuffer sb1, StringBuffer sb2) {
return [Link]().compareTo([Link]());
}
});

// Adding elements to the TreeSet


[Link](new StringBuffer("A"));
[Link](new StringBuffer("Z"));
[Link](new StringBuffer("L"));
[Link](new StringBuffer("B"));
[Link](new StringBuffer("O"));
[Link](new StringBuffer("1"));

// Printing the elements


[Link](ts);
}
}

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

It takes two parameters, namely as follows:


 K -> Type of keys maintained by this map
 V -> Type of mapped values

import [Link];
import [Link];

public class Main{

public static void main(String[] args){

// Create a HashMap
HashMap<String, Integer> hashMap = new HashMap<>();

// Add elements to the HashMap


[Link]("John", 25);
[Link]("Jane", 30);
[Link]("Jim", 35);

// Iterate through the HashMap


for ([Link]<String, Integer> entry : [Link]()) {
[Link]([Link]() + " -> " + [Link]());
}
}
}

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);

Performing Various Operations on HashMap


1. Adding Elements in HashMap in Java
To add an element to the map, we can use the put() method. However, the insertion order is not retained in
the Hashmap.

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<>();

// Initialization of a HashMap using Generics


HashMap<Integer, String> hm2 = new HashMap<Integer, String>();

// Add Elements using put method


[Link](1, "Python");
[Link](2, "Java");
[Link](3, "PHP");

[Link](1, "Python");
[Link](2, "Java");
[Link](3, "PHP");

[Link]("Mappings of HashMap hm1 are : "+ hm1);


[Link]("Mapping of HashMap hm2 are : "+ hm2);
}
}
Output
Mappings of HashMap hm1 are : {1=Python, 2=Java, 3=PHP}
Mapping of HashMap hm2 are : {1=Python, 2=Java, 3=PHP}

2. Changing Elements in HashMap in Java


We can change a value in a HashMap by using the put() method with the same key, which replaces the old
value with the new one.

import [Link].*;
import [Link].*;
class ChangeElementsOfHashMap {
public static void main(String args[])
{

// Initialization of a HashMap
HashMap<Integer, String> hm
= new HashMap<Integer, String>();

// Change Value using put method


[Link](1, "Python");
[Link](2, "C");
[Link](3, "PHP");

[Link]("Initial Map " + hm);

[Link](2, "Java");

[Link]("Updated Map " + hm);


}
}

Output
Initial Map {1=Python, 2=C, 3=PHP}
Updated Map {1=Python, 2=Java, 3=PHP}

3. Removing Element from Java HashMap


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].*;
import [Link].*;
class RemoveElementsOfHashMap{
public static void main(String args[])
{
// Initialization of a HashMap
Map<Integer, String> hm = new HashMap<Integer, String>();

// Add elements using put method


[Link](1, "Python");
[Link](2, "Java");
[Link](3, "PHP");
[Link](4, "C");

// Initial HashMap
[Link]("Mappings of HashMap are : "+ hm);

// remove element with a key


// using remove method
[Link](4);

// 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}

4. Traversal of Java HashMap


We can use an Iterator with [Link]<?, ?> to traverse a HashMap and print its entries using the next()
method.

import [Link];
import [Link];

public class TraversalTheHashMap {


public static void main(String[] args)
{
// initialize a HashMap
HashMap<String, Integer> map = new HashMap<>();

// Add elements using put method


[Link]("vishal", 10);
[Link]("sachin", 30);
[Link]("vaibhav", 20);

// Iterate the map using for-each loop


for ([Link]<String, Integer> e : [Link]())
[Link]("Key: " + [Link]()+ " Value: " + [Link]());
}
}

Output
Key: vaibhav Value: 20
Key: vishal Value: 10
Key: sachin Value: 30

Time and Space Complexity


HashMap provides constant time complexity for basic operations.
Operation Time Complexity Space Complexity
Adding elements in HashMap O(1) O(N)
Removing elements from HashMap O(1) O(N)
Extracting elements from HashMap O(1) O(N)

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.

Methods inherited from class [Link]


Method Description
equals() Compares the specified object with this map for equality.
hashCode() Returns the hash code value for this map.
toString() Returns a string representation of this map.

Methods inherited from interface [Link]


Method Description
equals() Compares the specified object with this map for equality.
forEach(BiConsumer<?
Performs the given action for each entry in this map until all entries have been
super K, ? super V>
processed or the action throws an exception.
action)
getOrDefault(Object key, Returns the value to which the specified key is mapped, or defaultValue if this
V defaultValue) map contains no mapping for the key.
hashCode() Returns the hash code value for this map.
If the specified key is not already associated with a value (or is mapped to
putIfAbsent(K key, V
null) associates it with the given value and returns null, else returns the current
value)
value.
remove(Object key, Removes the entry for the specified key only if it is currently mapped to the
Object value) specified value.
replace(K key, V value) Replaces the entry for the specified key only if it is currently mapped to some
value.
replace(K key, V Replaces the entry for the specified key only if currently mapped to the
oldValue, V newValue) specified value.
replaceAll(BiFunction<? Replaces each entry's value with the result of invoking the given function on
super K,? super V,? that entry until all entries have been processed or the function throws an
extends V> function) exception.

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];

public class TreeMapCreation {


public static void main(String args[]){

// Create a TreeMap of Strings (keys) and Integers


// (values)
TreeMap<String, Integer> tm = new TreeMap<>();

[Link]("TreeMap elements: " + tm);


}
}

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].*;

public class Main {

// To show TreeMap constructor


static void Constructor(){

// Creating an empty TreeMap


TreeMap<Integer, String> tm = new TreeMap<>();
// Mapping string values to int keys using put()
// method
[Link](10, "Python");
[Link](15, "Java");
[Link](20, "PHP");

// Printing the elements of TreeMap


[Link]("TreeMap: " + tm);
}

public static void main(String[] args){

[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;

public Student(int rollno, String name, String address){

[Link] = rollno;
[Link] = name;
[Link] = address;
}

public String toString(){

return [Link] + " " + [Link] + " "+ [Link];


}
}

// Comparator class
class SortByRoll implements Comparator<Student>{

public int compare(Student a, Student b){


// Compare based on roll number
return [Link] - [Link];
}
}

public class Geeks{


public static void main(String[] args){

// Create a TreeMap using a Comparator


TreeMap<Student, Integer> tm = new TreeMap<>(new SortByRoll());

[Link](new Student(111, "Java1", "New York"), 1);


[Link](new Student(131, "Java2", "London"), 2);
[Link](new Student(121, "Java3", "Paris"), 3);

[Link]("TreeMap sorted by roll number: "+ tm);


}
}

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].*;

public class Main {

// Method To illustrate constructor<Map>


static void Constructor()
{
// Creating an empty HashMap
TreeMap<Integer, String> m = new TreeMap<>();

[Link](10, "Python");
[Link](20, "Java");
[Link](30, "PHP");

// Creating the TreeMap using the Map


TreeMap<Integer, String> tm = new TreeMap<Integer, String>(m);

// Printing the elements of TreeMap


[Link]("TreeMap: " + tm);
}

public static void main(String[] args)


{
[Link](
"TreeMap using TreeMap(Map) Constructor");
Constructor();
}
}

Output
TreeMap using TreeMap(Map) Constructor
TreeMap: {10=Python, 20=Java, 30=PHP}

Performing Various Operations on TreeMap


1. Adding Elements
We can use the put() method to insert elements to a TreeMap. However, the insertion order is not retained
in the TreeMap. Internally, for every element, the keys are compared and sorted in ascending order.

import [Link].*;

class Main {

public static void main(String args[]){

// Initialization of TreeMap
TreeMap<Integer, String> tm = new TreeMap<>();

// Inserting the elements in TreeMap using put()


// method
[Link](3, "Python");
[Link](2, "Java");
[Link](1, "PHP");

[Link]("TreeMap with raw type: " + tm);

// Initialization of TreeMap with Generics


TreeMap<Integer, String> tm1 = new TreeMap<>();

// Inserting elements into tm1


[Link](3, "Language");
[Link](2, "Programming");
[Link](1, "Java");

[Link]("TreeMap with generics: " + tm1);


}
}

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{

public static void main(String args[]){


TreeMap<Integer, String> tm = new TreeMap<>();

// Inserting the elements in Map


[Link](3, "Java");
[Link](2, "C++");
[Link](1, "PHP");

[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{

public static void main(String args[]){

// Initialization of a TreeMap using Generics


TreeMap<Integer, String> tm = new TreeMap<>();

// Inserting the elements using put() method


[Link](3, "Java");
[Link](2, "C++");
[Link](1, "Python");
[Link](4, "JS");

[Link](tm);

// Removing the element corresponding to key


[Link](4);

[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 {

public static void main(String args[]){

// Initialization of TreeMap
TreeMap<Integer, String> tm = new TreeMap<>();

// Inserting elements
[Link](3, "Python");
[Link](2, "Java");
[Link](1, "PHP");

for ([Link]<Integer, String> e : [Link]()) {


int k = [Link]();
String v = [Link]();

[Link](k + " : " + v);


}
}
}

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();

void forEach(Consumer<? super T> action);


}
Here, T is the type of element returned by the Iterator.

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

Iterate an Iterable using enhanced for loop


Objects of Classes implementing Collection interface can be iterated using for-each loop, Collection
interface extends Iterable interface.

// Java Program to demonstrate iterate


// an iterable using for-each loop

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");

// Iterate through the list


for( String element : list ){
[Link]( element );
}
}
}

Output
Python
Java
PHP

Iterate an Iterable using forEach loop


The forEach() method takes the Lambda Expression as a parameter. This Lambda Expression is called for
each element of the collection. In the below example, for each element of the list, the function prints the
element to the console.

// Java Program to demonstrate iterate


// an Iterable using forEach method

import [Link].*;
import [Link].*;

class IterateUsingforEach {
public static void main(String[] args)
{
// create a list
List<String> list = new ArrayList<>();

// add elements to the list


[Link]("Python");
[Link]("Java");
[Link]("PHP");

// Iterate through the list


[Link](
(element) -> { [Link](element); });
}
}

Output
python
Java
PHP

Iterate an Iterable using Iterator


We can iterate the elements of Java Iterable by obtaining the Iterator from it using the iterator() method.
The methods used while traversing the collections using Iterator to perform the operations are:
 hasNext(): It returns false if we have reached the end of the collection, otherwise returns true.
 next(): Returns the next element in a collection.
 remove(): Removes the last element returned by the iterator from the collection.
 forEachRemaining(): Performs the given action for each remaining element in a collection, in
sequential order.

// Java Program to demonstrate iterate


// an Iterable using an Iterator

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].*;

public class Main{

public static void main(String[] args){

// Creating a list of names


List<String> names = new LinkedList<>();

[Link]("Welcome");
[Link]("To");
[Link]("Goa");

// Getting ListIterator
ListIterator<String> namesIterator = [Link]();

// Traversing elements using next() method


while ([Link]()) {
[Link]([Link]());
}

// for-each loop creates Internal Iterator here.


for (String s : names) {
[Link](s);
}
}
}

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.

Interesting Fact about ListIterator


There is no current element in ListIterator. Its cursor always lies between the previous and next elements.
The previous() will return to the previous elements and the next() will return to the next element.
Therefore, for a list of length n, there are n+1 possible cursors.

Forward and Backward Traversal


1. Forward direction iteration
 hasNext(): This method returns true when the list has more elements to traverse while traversing in
the forward direction
 next(): This method returns the next element of the list and advances the position of the cursor.
 nextIndex(): This method returns the index of the element that would be returned on calling
the next() method.
2. Backward direction iteration
 hasPrevious(): This method returns true when the list has more elements to traverse while traversing
in the reverse direction
 previous(): This method returns the previous element of the list and shifts the cursor one position
backward.
 previousIndex(): This method returns the index of the element that would be returned on calling
the previous() method.

import [Link].*;

public class Main {

public static void main(String[] args)


{
// list of names
List<String> names = new LinkedList<>();
[Link]("learn");
[Link]("from");
[Link]("Tutorial");

// Getting ListIterator
ListIterator<String> listIterator = [Link]();

// Traversing elements
[Link]("Forward Direction Iteration:");
while ([Link]()) {
[Link]([Link]());
}

// Traversing elements, the iterator is at the end at this point


[Link]("Backward 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.

Difference between Iterator and ListIterator


Iterator ListIterator
It traverses only list collection implemented classes
It can traverse a collection of any type.
like LinkedList, ArrayList, etc.
Traversal of elements can be done in both forward and
Traversal can only be done in forwarding direction.
backward direction.
Iterator object can be created by calling iterator() ListIterator object can be created by calling
method of the collection interface. listIterator() method of the collection interface.
Deletion of elements is allowed using remove()
Deletion of elements is allowed.
method.
It throws ConcurrentModificationException on
doing addition operation. Hence, addition is not Addition of elements is allowed.
allowed.
In listIterator, we have nextIndex() and
In iterator, we can't access the index of the
previousIndex() methods for accessing the indexes of
traversed element.
the traversed or the next traversing element.
Modification of any element is not allowed. Modification is allowed.

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");

Example 1: Program to check if a file or directory physically exists or not.


import [Link];

// Displaying file property


class CheckFileExist {

public static void main(String[] args){

// Accept file name or directory name through


// command line args
String fname = args[0];

// pass the filename or directory name to File


// object
File f = new File(fname);

// apply File class methods on File object


[Link]("File name :" + [Link]());
[Link]("Path: " + [Link]());
[Link]("Absolute path:"+ [Link]());
[Link]("Parent:" + [Link]());
[Link]("Exists :" + [Link]());

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]));

[Link]("Enter directory path : ");


String dirpath = [Link]();

[Link]("Enter the directory name : ");


String dname = [Link]();

// Create File object with dirpath and dname


File f = new File(dirpath, dname);

// 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];

// Displaying the entries


for (int i = 0; i < n; i++) {

[Link](arr[i] + " ");

// 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");
}

[Link]("\nNo of entries in this directory : " + n);


}
else
[Link]("Directory not found");
}
}
Output:

Constructors of Java File Class


 File(File parent, String child): Creates a new File instance from a parent abstract pathname and a
child pathname string.
 File(String pathname): Creates a new File instance by converting the given pathname string into an
abstract pathname.
 File(String parent, String child): Creates a new File instance from a parent pathname string and a
child pathname string.
 File(URI uri): Creates a new File instance by converting the given file: URI into an abstract
pathname.

Fields in File Class


Field Type Description
the character or string used to separate individual paths in a list of file
pathSeparator String
system paths.
pathSeparatorChar Char the character used to separate individual paths in a list of file system paths.
Separator String default name separator character represented as a string.
separatorChar Char default name separator character.

Methodsof File Class in Java


Method Description Return Type
canExecute() Checks if the file is executable boolean
canRead() Checks if the file is readable boolean
canWrite() Checks if the file is writable boolean
compareTo(File other) Lexicographically compares pathnames int
createNewFile() Atomically creates a new empty file boolean
createTempFile(String prefix, String Creates a temp file in default temp directory File
suffix)
delete() Deletes this file or directory boolean
exists() Checks if the file/directory exists boolean
equals(Object obj) Compares pathnames for equality boolean
getAbsolutePath() Returns absolute pathname as a string String
getCanonicalPath() Returns canonical (distinct) pathname String
getName() Returns name of file or directory String
getParent() Returns parent pathname string String
getParentFile() Returns parent as a File object File
getPath() Returns the original pathname string String
getFreeSpace() Returns unallocated bytes in partition long
length() Returns file size in bytes long
isDirectory() Checks if it’s a directory boolean
isFile() Checks if it’s a normal file boolean
isHidden() Checks if file is hidden boolean
lastModified() Returns last modification time (ms since epoch) long
list() Returns names of all entries in directory String[]
listFiles() Returns File objects for entries in directory File[]
listFiles(FileFilter filter) Filters entries via FileFilter File[]
listFiles(FilenameFilter filter) Filters entries via FilenameFilter File[]
mkdir() Creates a directory boolean
mkdirs() Creates directory including parent dirs. boolean
renameTo(File dest) Renames or moves file/directory boolean
setReadOnly() Marks file/directory as read-only boolean
setExecutable(boolean exec) Sets owner's execute permission boolean
setReadable(boolean read) Sets owner's read permission boolean
setReadable(boolean read, boolean
Sets read permission for owner or all boolean
ownerOnly)
setWritable(boolean write) Sets owner's write permission boolean
toURI() Converts pathname to a URI object URI
toString() Returns pathname string String

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];

public class CopyFile {

public static void main(String args[]) throws IOException {


FileInputStream in = null;
FileOutputStream out = null;

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]();
}
}
}
}

Now let's have a file [Link] with the following content −

This is test for copy file.

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];

public class CopyFile {

public static void main(String args[]) throws IOException {


FileReader in = null;
FileWriter out = null;

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]();
}
}
}
}

Now let's have a file [Link] with the following content −

This is test for copy file.

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&plus;&plus; 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

Enter characters, 'q' to quit.


1
1
e
e
q
q

Reading and Writing Files


As described earlier, a stream can be defined as a sequence of data. The InputStream is used to read data
from a source and the OutputStream is used for writing data to a destination.
Here is a hierarchy of classes to deal with Input and Output streams.
The two important streams are FileInputStream and FileOutputStream, which would be discussed in this
tutorial.

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 −

File f = new File("C:/java/hello");


InputStream f = new FileInputStream(f);

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.

[Link] Method Description


public void close() This method closes the file output stream. Releases any system resources
1
throws IOException{} associated with the file. Throws an IOException.
protected void This method cleans up the connection to the file. Ensures that the close
2 finalize()throws method of this file output stream is called when there are no more
IOException {} references to this stream. Throws an IOException.
This method reads the specified byte of data from the InputStream.
public int read(int r)
3 Returns an int. Returns the next byte of data and -1 will be returned if it's
throws IOException{}
the end of the file.
This method reads [Link] bytes from the input stream into an array.
public int read(byte[] r)
4 Returns the total number of bytes read. If it is the end of the file, -1 will
throws IOException{}
be returned.
public int available() Gives the number of bytes that can be read from this file input stream.
5
throws IOException{} Returns an int.

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 −

File f = new File("C:/java/hello");


OutputStream f = new FileOutputStream(f);

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.

[Link]. Method Description


public void close() This method closes the file output stream. Releases any system resources
1
throws IOException{} associated with the file. Throws an IOException.
protected void This method cleans up the connection to the file. Ensures that the close
2 finalize() throws method of this file output stream is called when there are no more
IOException {} references to this stream. Throws an IOException.
public void write(int w)
3 This methods writes the specified byte to the output stream.
throws IOException{}
public void write Writes [Link] bytes from the mentioned byte array to the
4
(byte[] w) OutputStream.

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];

public class fileStreamTest {

public static void main(String args[]) {

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]();

InputStream is = new FileInputStream("[Link]");


int size = [Link]();

for(int i = 0; i < size; i++) {


[Link]((char)[Link]() + " ");
}
[Link]();
} catch (IOException e) {
[Link]("Exception");
}
}
}

The above code would create file [Link] and would write given numbers in binary format. Same would be
the output on the stdout screen.

File Navigation and I/O


There are several other classes that we would be going through to get to know the basics of File Navigation
and I/O.
• File Class
• FileReader Class
• FileWriter Class

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.

Following example creates "/tmp/user/java/bin" directory −

Example
import [Link];

public class CreateDir {

public static void main(String args[]) {


String dirname = "/tmp/user/java/bin";
File d = new File(dirname);

// Create directory now.


[Link]();
}
}

Compile and execute the above code to create "/tmp/user/java/bin".

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];

public class ReadDir {

public static void main(String[] args) {


File file = null;
String[] paths;

try {
// create new file object
file = new File("/tmp");

// array of files and directory


paths = [Link]();

// for each name in the path array


for(String path:paths) {
// prints filename and directory name
[Link](path);
}
} catch (Exception e) {
// if any error occurs
[Link]();
}
}
}

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.

What is Serialization and Deserialization?

Serialization is a mechanism of converting the state of an object into a byte stream.

Important Points of Serialisation:


 Platform-Independent: In Java, the serialization is a platform-independent process. It means that if
we serialize an object using a byte stream on one platform can be easily deserialized on different
platforms.
 Serializable Interface: If we want to make a class serializable, then it must implement the
Serializable interface. This interface does not contain any methods or variables ( marker interface), but
it gives a signal that the class is ready for serialization.

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.

Important Points of Deserialization:


 Rebuilds Objects: Deserialization takes the byte stream and turns it back into the original object with
the same state as before.
 Platform-Independent: Deserialization works well with different platforms without any issues.
 Class Must Be Available: When we deserialize an object, it is necessary that the class definition be
present in the program.
Visual Representation of Serialization and Deserialization Process
The image below demonstrates the process of serialization and deserialization.

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.

public final Object readObject()


throws IOException,
ClassNotFoundException

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.

Points to remember while using Serialization:


 Parent-Child Serialization: If a parent class has implemented Serializable interface then child class
doesn't need to implement it but vice-versa is not true.
 Non-static Data Members: Only non-static data members are saved via Serialization process. Static
variable are not serialized becaue they are not associated with any specific instance.
 Transient Data Members: Static data members and transient data members are not saved via
Serialization process. So, if you don't want to save value of a non-static data member then make it
transient.
 Constructor Calling: Constructor of object is never called when an object is deserialized.
 Associated Objects: Associated objects must be implementing Serializable interface.

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.

Example of Getting SerialVersionUID using Serialver


We can run the following command to get serialVersionUID serialver [-classpath classpath] [-show]
[classname...]

Example: Serialization and Deserialization of a Java Object.


import [Link].*;

class Demo implements Serializable {


public int a;
public String b;

public Demo(int a, String b) {


this.a = a;
this.b = b;
}
}

public class Main {


public static void main(String[] args) {
Demo object = new Demo(1, "Welcome to Goa");
String filename = "[Link]";

// Serialization
try {
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);
[Link](object);
[Link]();
[Link]();
[Link]("Object has been serialized");

} catch (IOException ex) {


[Link]("IOException is caught");
}

Demo object1 = null;

// 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);

} catch (IOException ex) {


[Link]("IOException is caught");
} catch (ClassNotFoundException ex) {
[Link]("ClassNotFoundException is caught");
}
}
}

Output:
Object has been serialized
Object has been deserialized
a=1
b = Welcome to Goa

Example: Serialization with Transient and Static Fields.


import [Link].*;

class Emp implements Serializable {


private static final long serialVersionUID = 129348938L;
transient int a;
static int b;
String name;
int age;

public Emp(String name, int age, int a, int b) {


[Link] = name;
[Link] = age;
this.a = a;
this.b = b;
}
}

public class Main{


public static void printData(Emp object1) {
[Link]("name = " + [Link]);
[Link]("age = " + [Link]);
[Link]("a = " + object1.a);
[Link]("b = " + object1.b);
}

public static void main(String[] args) {


Emp object = new Emp("ab", 20, 2, 1000);
String filename = "[Link]";

// 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);

// Change static variable b


object.b = 2000;
} catch (IOException ex) {
[Link]("IOException is caught");
}

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);

} catch (IOException ex) {


[Link]("IOException is caught");
} catch (ClassNotFoundException ex) {
[Link]("ClassNotFoundException is caught");
}
}
}

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

Example: Demonstration of transient and final behaviour together while serialization.

// Java program for final with transient


import [Link].*;

class Dog implements Serializable{


int i=10;
transient final int j=20;
}
class Main
{
public static void main (String[] args)throws
IOException, ClassNotFoundException
{
Dog d1=new Dog();
//Serialization started

[Link]("serialization started");

FileOutputStream fos= new FileOutputStream("[Link]");


ObjectOutputStream oos=new ObjectOutputStream(fos);

[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

Serialization vs Deserialization in Java


The main difference between serialization and deserialization is:
 Serialization is the process of converting object to byte stream.
 Deserialization is the process of converting byte stream to object.

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.

You might also like